init: allow first stage mount to read an fstab

Now that we have a first stage ramdisk (or use recovery in its place),
it's possible to place a vendor specific fstab along with first stage
init, removing the need for device tree modifications to have an
fstab.

Bug: 117933812
Test: hikey boots with only an fstab in first stage ramdisk
Test: blueline mainline boots with a disabled DT fstab and an fstab in recovery
Change-Id: I4460b88851557a75ba06ff795cd842e7dfb6da46
This commit is contained in:
Tom Cherry 2018-10-25 16:10:23 -07:00
parent bb72b808f4
commit e68bf85fd6
7 changed files with 40 additions and 21 deletions

View File

@ -1032,8 +1032,9 @@ int fs_mgr_mount_all(fstab* fstab, int mount_mode) {
for (i = 0; i < fstab->num_entries; i++) {
/* Don't mount entries that are managed by vold or not for the mount mode*/
if ((fstab->recs[i].fs_mgr_flags & (MF_VOLDMANAGED | MF_RECOVERYONLY)) ||
((mount_mode == MOUNT_MODE_LATE) && !fs_mgr_is_latemount(&fstab->recs[i])) ||
((mount_mode == MOUNT_MODE_EARLY) && fs_mgr_is_latemount(&fstab->recs[i]))) {
((mount_mode == MOUNT_MODE_LATE) && !fs_mgr_is_latemount(&fstab->recs[i])) ||
((mount_mode == MOUNT_MODE_EARLY) && fs_mgr_is_latemount(&fstab->recs[i])) ||
fs_mgr_is_first_stage_mount(&fstab->recs[i])) {
continue;
}

View File

@ -57,7 +57,7 @@ struct fs_mgr_flag_values {
struct flag_list {
const char *name;
int flag;
unsigned int flag;
};
static struct flag_list mount_flags[] = {
@ -102,6 +102,7 @@ static struct flag_list fs_mgr_flags[] = {
{"formattable", MF_FORMATTABLE},
{"slotselect", MF_SLOTSELECT},
{"nofail", MF_NOFAIL},
{"first_stage_mount", MF_FIRST_STAGE_MOUNT},
{"latemount", MF_LATEMOUNT},
{"reservedsize=", MF_RESERVEDSIZE},
{"quota", MF_QUOTA},
@ -998,6 +999,10 @@ int fs_mgr_is_nofail(const struct fstab_rec* fstab) {
return fstab->fs_mgr_flags & MF_NOFAIL;
}
int fs_mgr_is_first_stage_mount(const struct fstab_rec* fstab) {
return fstab->fs_mgr_flags & MF_FIRST_STAGE_MOUNT;
}
int fs_mgr_is_latemount(const struct fstab_rec* fstab) {
return fstab->fs_mgr_flags & MF_LATEMOUNT;
}

View File

@ -74,7 +74,7 @@ bool fs_mgr_overlayfs_mount_all(fstab*) {
return false;
}
bool fs_mgr_overlayfs_mount_all(const std::vector<const fstab_rec*>&) {
bool fs_mgr_overlayfs_mount_all(const std::vector<fstab_rec*>&) {
return false;
}
@ -82,7 +82,7 @@ std::vector<std::string> fs_mgr_overlayfs_required_devices(fstab*) {
return {};
}
std::vector<std::string> fs_mgr_overlayfs_required_devices(const std::vector<const fstab_rec*>&) {
std::vector<std::string> fs_mgr_overlayfs_required_devices(const std::vector<fstab_rec*>&) {
return {};
}
@ -805,7 +805,7 @@ bool fs_mgr_overlayfs_mount_all(fstab* fstab) {
return ret;
}
bool fs_mgr_overlayfs_mount_all(const std::vector<const fstab_rec*>& fsrecs) {
bool fs_mgr_overlayfs_mount_all(const std::vector<fstab_rec*>& fsrecs) {
std::vector<fstab_rec> recs;
for (const auto& rec : fsrecs) recs.push_back(*rec);
fstab fstab = {static_cast<int>(fsrecs.size()), &recs[0]};
@ -828,8 +828,7 @@ std::vector<std::string> fs_mgr_overlayfs_required_devices(fstab* fstab) {
return {};
}
std::vector<std::string> fs_mgr_overlayfs_required_devices(
const std::vector<const fstab_rec*>& fsrecs) {
std::vector<std::string> fs_mgr_overlayfs_required_devices(const std::vector<fstab_rec*>& fsrecs) {
std::vector<fstab_rec> recs;
for (const auto& rec : fsrecs) recs.push_back(*rec);
fstab fstab = {static_cast<int>(fsrecs.size()), &recs[0]};

View File

@ -118,6 +118,8 @@
#define MF_LOGICAL 0x10000000
#define MF_CHECKPOINT_BLK 0x20000000
#define MF_CHECKPOINT_FS 0x40000000
#define MF_FIRST_STAGE_MOUNT \
0x80000000
// clang-format on
#define DM_BUF_SIZE 4096

View File

@ -22,10 +22,9 @@
#include <vector>
bool fs_mgr_overlayfs_mount_all(fstab* fstab);
bool fs_mgr_overlayfs_mount_all(const std::vector<const fstab_rec*>& fstab);
bool fs_mgr_overlayfs_mount_all(const std::vector<fstab_rec*>& fstab);
std::vector<std::string> fs_mgr_overlayfs_required_devices(fstab* fstab);
std::vector<std::string> fs_mgr_overlayfs_required_devices(
const std::vector<const fstab_rec*>& fstab);
std::vector<std::string> fs_mgr_overlayfs_required_devices(const std::vector<fstab_rec*>& fstab);
bool fs_mgr_overlayfs_setup(const char* backing = nullptr, const char* mount_point = nullptr,
bool* change = nullptr);
bool fs_mgr_overlayfs_teardown(const char* mount_point = nullptr, bool* change = nullptr);

View File

@ -84,6 +84,7 @@ int fs_mgr_is_notrim(const struct fstab_rec* fstab);
int fs_mgr_is_formattable(const struct fstab_rec* fstab);
int fs_mgr_is_slotselect(const struct fstab_rec* fstab);
int fs_mgr_is_nofail(const struct fstab_rec* fstab);
int fs_mgr_is_first_stage_mount(const struct fstab_rec* fstab);
int fs_mgr_is_latemount(const struct fstab_rec* fstab);
int fs_mgr_is_quota(const struct fstab_rec* fstab);
int fs_mgr_is_logical(const struct fstab_rec* fstab);

View File

@ -84,7 +84,7 @@ class FirstStageMount {
bool need_dm_verity_;
std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> device_tree_fstab_;
std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> fstab_;
std::string lp_metadata_partition_;
std::vector<fstab_rec*> mount_fstab_recs_;
std::set<std::string> required_devices_partition_names_;
@ -132,15 +132,27 @@ static bool IsRecoveryMode() {
// Class Definitions
// -----------------
FirstStageMount::FirstStageMount()
: need_dm_verity_(false), device_tree_fstab_(fs_mgr_read_fstab_dt(), fs_mgr_free_fstab) {
if (device_tree_fstab_) {
// Stores device_tree_fstab_->recs[] into mount_fstab_recs_ (vector<fstab_rec*>)
// for easier manipulation later, e.g., range-base for loop.
for (int i = 0; i < device_tree_fstab_->num_entries; i++) {
mount_fstab_recs_.push_back(&device_tree_fstab_->recs[i]);
: need_dm_verity_(false), fstab_(fs_mgr_read_fstab_dt(), fs_mgr_free_fstab) {
// Stores fstab_->recs[] into mount_fstab_recs_ (vector<fstab_rec*>)
// for easier manipulation later, e.g., range-base for loop.
if (fstab_) {
// DT Fstab predated having a first_stage_mount fs_mgr flag, so if it exists, we use it.
for (int i = 0; i < fstab_->num_entries; i++) {
mount_fstab_recs_.push_back(&fstab_->recs[i]);
}
} else {
LOG(INFO) << "Failed to read fstab from device tree";
// Fstab found in first stage ramdisk, which should be a copy of the normal fstab.
// Mounts intended for first stage are explicitly flagged as such.
fstab_.reset(fs_mgr_read_fstab_default());
if (fstab_) {
for (int i = 0; i < fstab_->num_entries; i++) {
if (fs_mgr_is_first_stage_mount(&fstab_->recs[i])) {
mount_fstab_recs_.push_back(&fstab_->recs[i]);
}
}
} else {
LOG(INFO) << "Failed to read fstab from device tree";
}
}
auto boot_devices = fs_mgr_get_boot_devices();
@ -411,7 +423,7 @@ bool FirstStageMount::MountPartitions() {
}
// heads up for instantiating required device(s) for overlayfs logic
const auto devices = fs_mgr_overlayfs_required_devices(device_tree_fstab_.get());
const auto devices = fs_mgr_overlayfs_required_devices(mount_fstab_recs_);
for (auto const& device : devices) {
if (android::base::StartsWith(device, "/dev/block/by-name/")) {
required_devices_partition_names_.emplace(basename(device.c_str()));
@ -423,7 +435,7 @@ bool FirstStageMount::MountPartitions() {
}
}
fs_mgr_overlayfs_mount_all(device_tree_fstab_.get());
fs_mgr_overlayfs_mount_all(mount_fstab_recs_);
return true;
}