From 29954f6062e59beb645109e2585afa4eb71e7992 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Tue, 1 May 2018 13:57:14 -0700 Subject: [PATCH 1/2] init: refactor first stage to not require fstab In order to support dm-linear devices, we need an additional first-stage step to ensure that required devices are created. This must happen before setting up dm-verity or mounting any first-stage partitions. This patch refactors FirstStageMount so that having a compatible fstab is optional. This will let us use InitRequiredDevices on systems that would not otherwise perform first-stage mounts. Bug: 78914864 Test: non-AVB devices still boot Change-Id: I11265375a9900d983da8cabcc77d32c503ded02e --- init/init_first_stage.cpp | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/init/init_first_stage.cpp b/init/init_first_stage.cpp index 45d3d4499..1b6e97ec7 100644 --- a/init/init_first_stage.cpp +++ b/init/init_first_stage.cpp @@ -118,14 +118,14 @@ static bool inline IsRecoveryMode() { // ----------------- FirstStageMount::FirstStageMount() : need_dm_verity_(false), device_tree_fstab_(fs_mgr_read_fstab_dt(), fs_mgr_free_fstab) { - if (!device_tree_fstab_) { + if (device_tree_fstab_) { + // Stores device_tree_fstab_->recs[] into mount_fstab_recs_ (vector) + // 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]); + } + } else { LOG(INFO) << "Failed to read fstab from device tree"; - return; - } - // Stores device_tree_fstab_->recs[] into mount_fstab_recs_ (vector) - // 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]); } } @@ -138,8 +138,11 @@ std::unique_ptr FirstStageMount::Create() { } bool FirstStageMount::DoFirstStageMount() { - // Nothing to mount. - if (mount_fstab_recs_.empty()) return true; + if (mount_fstab_recs_.empty()) { + // Nothing to mount. + LOG(INFO) << "First stage mount skipped (missing/incompatible/empty fstab in device tree)"; + return true; + } if (!InitDevices()) return false; @@ -479,12 +482,6 @@ bool DoFirstStageMount() { return true; } - // Firstly checks if device tree fstab entries are compatible. - if (!is_android_dt_value_expected("fstab/compatible", "android,fstab")) { - LOG(INFO) << "First stage mount skipped (missing/incompatible fstab in device tree)"; - return true; - } - std::unique_ptr handle = FirstStageMount::Create(); if (!handle) { LOG(ERROR) << "Failed to create FirstStageMount"; From 5a4db628eee34e0dea45bbe1fcf14432d82eed36 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Wed, 2 May 2018 18:18:12 -0700 Subject: [PATCH 2/2] fs_mgr: clean up dm ioctl flags DM_READONLY_FLAG should only be used when loading tables, and DM_STATUS_TABLE_FLAG should only be used when querying a table's status. This patch cleans up how we set flags to reflect when the kernel actually cares about them. Bug: 78914864 Test: AVB device still boots Change-Id: I809d8c2ef2105849ebdd095bbe7f08f15ae63465 --- fs_mgr/fs_mgr.cpp | 2 +- fs_mgr/fs_mgr_avb.cpp | 3 ++- fs_mgr/fs_mgr_dm_ioctl.cpp | 11 +++++------ fs_mgr/fs_mgr_priv_dm_ioctl.h | 2 +- fs_mgr/fs_mgr_verity.cpp | 3 ++- 5 files changed, 11 insertions(+), 10 deletions(-) diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp index 9aab0bac4..6769fda67 100644 --- a/fs_mgr/fs_mgr.cpp +++ b/fs_mgr/fs_mgr.cpp @@ -1383,7 +1383,7 @@ bool fs_mgr_update_verity_state(fs_mgr_verity_state_callback callback) { mount_point = basename(fstab->recs[i].mount_point); } - fs_mgr_verity_ioctl_init(io, mount_point, 0); + fs_mgr_verity_ioctl_init(io, mount_point); const char* status; if (ioctl(fd, DM_TABLE_STATUS, io)) { diff --git a/fs_mgr/fs_mgr_avb.cpp b/fs_mgr/fs_mgr_avb.cpp index 7824cfa70..6ea38335e 100644 --- a/fs_mgr/fs_mgr_avb.cpp +++ b/fs_mgr/fs_mgr_avb.cpp @@ -303,13 +303,14 @@ static std::string construct_verity_table(const AvbHashtreeDescriptor& hashtree_ static bool load_verity_table(struct dm_ioctl* io, const std::string& dm_device_name, int fd, uint64_t image_size, const std::string& verity_table) { - fs_mgr_verity_ioctl_init(io, dm_device_name, DM_STATUS_TABLE_FLAG); + fs_mgr_verity_ioctl_init(io, dm_device_name); // The buffer consists of [dm_ioctl][dm_target_spec][verity_params]. char* buffer = (char*)io; // Builds the dm_target_spec arguments. struct dm_target_spec* dm_target = (struct dm_target_spec*)&buffer[sizeof(struct dm_ioctl)]; + io->flags = DM_READONLY_FLAG; io->target_count = 1; dm_target->status = 0; dm_target->sector_start = 0; diff --git a/fs_mgr/fs_mgr_dm_ioctl.cpp b/fs_mgr/fs_mgr_dm_ioctl.cpp index 4cbd5a86a..5f9b11868 100644 --- a/fs_mgr/fs_mgr_dm_ioctl.cpp +++ b/fs_mgr/fs_mgr_dm_ioctl.cpp @@ -23,21 +23,20 @@ #include "fs_mgr_priv.h" #include "fs_mgr_priv_dm_ioctl.h" -void fs_mgr_verity_ioctl_init(struct dm_ioctl* io, const std::string& name, unsigned flags) { +void fs_mgr_verity_ioctl_init(struct dm_ioctl* io, const std::string& name) { memset(io, 0, DM_BUF_SIZE); io->data_size = DM_BUF_SIZE; io->data_start = sizeof(struct dm_ioctl); io->version[0] = 4; io->version[1] = 0; io->version[2] = 0; - io->flags = flags | DM_READONLY_FLAG; if (!name.empty()) { strlcpy(io->name, name.c_str(), sizeof(io->name)); } } bool fs_mgr_create_verity_device(struct dm_ioctl* io, const std::string& name, int fd) { - fs_mgr_verity_ioctl_init(io, name, 1); + fs_mgr_verity_ioctl_init(io, name); if (ioctl(fd, DM_DEV_CREATE, io)) { PERROR << "Error creating device mapping"; return false; @@ -46,7 +45,7 @@ bool fs_mgr_create_verity_device(struct dm_ioctl* io, const std::string& name, i } bool fs_mgr_destroy_verity_device(struct dm_ioctl* io, const std::string& name, int fd) { - fs_mgr_verity_ioctl_init(io, name, 0); + fs_mgr_verity_ioctl_init(io, name); if (ioctl(fd, DM_DEV_REMOVE, io)) { PERROR << "Error removing device mapping"; return false; @@ -58,7 +57,7 @@ bool fs_mgr_get_verity_device_name(struct dm_ioctl* io, const std::string& name, std::string* out_dev_name) { FS_MGR_CHECK(out_dev_name != nullptr); - fs_mgr_verity_ioctl_init(io, name, 0); + fs_mgr_verity_ioctl_init(io, name); if (ioctl(fd, DM_DEV_STATUS, io)) { PERROR << "Error fetching verity device number"; return false; @@ -71,7 +70,7 @@ bool fs_mgr_get_verity_device_name(struct dm_ioctl* io, const std::string& name, } bool fs_mgr_resume_verity_table(struct dm_ioctl* io, const std::string& name, int fd) { - fs_mgr_verity_ioctl_init(io, name, 0); + fs_mgr_verity_ioctl_init(io, name); if (ioctl(fd, DM_DEV_SUSPEND, io)) { PERROR << "Error activating verity device"; return false; diff --git a/fs_mgr/fs_mgr_priv_dm_ioctl.h b/fs_mgr/fs_mgr_priv_dm_ioctl.h index a00a9c14d..792683eca 100644 --- a/fs_mgr/fs_mgr_priv_dm_ioctl.h +++ b/fs_mgr/fs_mgr_priv_dm_ioctl.h @@ -20,7 +20,7 @@ #include #include -void fs_mgr_verity_ioctl_init(struct dm_ioctl* io, const std::string& name, unsigned flags); +void fs_mgr_verity_ioctl_init(struct dm_ioctl* io, const std::string& name); bool fs_mgr_create_verity_device(struct dm_ioctl* io, const std::string& name, int fd); diff --git a/fs_mgr/fs_mgr_verity.cpp b/fs_mgr/fs_mgr_verity.cpp index 896b60313..d0bb05826 100644 --- a/fs_mgr/fs_mgr_verity.cpp +++ b/fs_mgr/fs_mgr_verity.cpp @@ -258,12 +258,13 @@ static int load_verity_table(struct dm_ioctl *io, const std::string &name, char *buffer = (char*) io; size_t bufsize; - fs_mgr_verity_ioctl_init(io, name, DM_STATUS_TABLE_FLAG); + fs_mgr_verity_ioctl_init(io, name); struct dm_target_spec *tgt = (struct dm_target_spec *) &buffer[sizeof(struct dm_ioctl)]; // set tgt arguments io->target_count = 1; + io->flags = DM_READONLY_FLAG; tgt->status = 0; tgt->sector_start = 0; tgt->length = device_size / 512;