diff --git a/fs_mgr/Android.bp b/fs_mgr/Android.bp index f23150d1c..05dba1524 100644 --- a/fs_mgr/Android.bp +++ b/fs_mgr/Android.bp @@ -42,6 +42,7 @@ cc_library_static { "fs_mgr_verity.cpp", "fs_mgr_avb.cpp", "fs_mgr_avb_ops.cpp", + "fs_mgr_dm_linear.cpp", ], static_libs: [ "libfec", diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp index e9040dfe8..6e9ffba59 100644 --- a/fs_mgr/fs_mgr.cpp +++ b/fs_mgr/fs_mgr.cpp @@ -794,6 +794,29 @@ static bool call_vdc(const std::vector& args) { return true; } +bool fs_mgr_update_logical_partition(struct fstab_rec* rec) { + // Logical partitions are specified with a named partition rather than a + // block device, so if the block device is a path, then it has already + // been updated. + if (rec->blk_device[0] == '/') { + return true; + } + + android::base::unique_fd dm_fd(open("/dev/device-mapper", O_RDONLY)); + if (dm_fd < 0) { + PLOG(ERROR) << "open /dev/device-mapper failed"; + return false; + } + struct dm_ioctl io; + std::string device_name; + if (!fs_mgr_dm_get_device_name(&io, rec->blk_device, dm_fd, &device_name)) { + return false; + } + free(rec->blk_device); + rec->blk_device = strdup(device_name.c_str()); + return true; +} + /* When multiple fstab records share the same mount_point, it will * try to mount each one in turn, and ignore any duplicates after a * first successful mount. @@ -845,6 +868,13 @@ int fs_mgr_mount_all(struct fstab *fstab, int mount_mode) } } + if ((fstab->recs[i].fs_mgr_flags & MF_LOGICAL)) { + if (!fs_mgr_update_logical_partition(&fstab->recs[i])) { + LERROR << "Could not set up logical partition, skipping!"; + continue; + } + } + if (fstab->recs[i].fs_mgr_flags & MF_WAIT && !fs_mgr_wait_for_file(fstab->recs[i].blk_device, 20s)) { LERROR << "Skipping '" << fstab->recs[i].blk_device << "' during mount_all"; @@ -1065,6 +1095,13 @@ int fs_mgr_do_mount(struct fstab *fstab, const char *n_name, char *n_blk_device, return FS_MGR_DOMNT_FAILED; } + if ((fstab->recs[i].fs_mgr_flags & MF_LOGICAL)) { + if (!fs_mgr_update_logical_partition(&fstab->recs[i])) { + LERROR << "Could not set up logical partition, skipping!"; + continue; + } + } + /* First check the filesystem if requested */ if (fstab->recs[i].fs_mgr_flags & MF_WAIT && !fs_mgr_wait_for_file(n_blk_device, 20s)) { LERROR << "Skipping mounting '" << n_blk_device << "'"; diff --git a/fs_mgr/fs_mgr_avb.cpp b/fs_mgr/fs_mgr_avb.cpp index cf6b49702..5a9cb654f 100644 --- a/fs_mgr/fs_mgr_avb.cpp +++ b/fs_mgr/fs_mgr_avb.cpp @@ -585,7 +585,13 @@ SetUpAvbHashtreeResult FsManagerAvbHandle::SetUpAvbHashtree(struct fstab_rec* fs // Derives partition_name from blk_device to query the corresponding AVB HASHTREE descriptor // to setup dm-verity. The partition_names in AVB descriptors are without A/B suffix. - std::string partition_name(basename(fstab_entry->blk_device)); + std::string partition_name; + if (fstab_entry->fs_mgr_flags & MF_LOGICAL) { + partition_name = fstab_entry->logical_partition_name; + } else { + partition_name = basename(fstab_entry->blk_device); + } + if (fstab_entry->fs_mgr_flags & MF_SLOTSELECT) { auto ab_suffix = partition_name.rfind(fs_mgr_get_slot_suffix()); if (ab_suffix != std::string::npos) { diff --git a/fs_mgr/fs_mgr_dm_linear.cpp b/fs_mgr/fs_mgr_dm_linear.cpp new file mode 100644 index 000000000..b2f3a6887 --- /dev/null +++ b/fs_mgr/fs_mgr_dm_linear.cpp @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "fs_mgr_dm_linear.h" + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include "fs_mgr_priv.h" +#include "fs_mgr_priv_dm_ioctl.h" + +namespace android { +namespace fs_mgr { + +std::string LogicalPartitionExtent::Serialize() const { + // Note: we need to include an explicit null-terminator. + std::string argv = + android::base::StringPrintf("%s %" PRIu64, block_device_.c_str(), first_sector_); + argv.push_back(0); + + // The kernel expects each target to be aligned. + size_t spec_bytes = sizeof(struct dm_target_spec) + argv.size(); + size_t padding = ((spec_bytes + 7) & ~7) - spec_bytes; + for (size_t i = 0; i < padding; i++) { + argv.push_back(0); + } + + struct dm_target_spec spec; + spec.sector_start = logical_sector_; + spec.length = num_sectors_; + spec.status = 0; + strcpy(spec.target_type, "linear"); + spec.next = sizeof(struct dm_target_spec) + argv.size(); + + return std::string((char*)&spec, sizeof(spec)) + argv; +} + +static bool LoadDmTable(int dm_fd, const LogicalPartition& partition) { + // Combine all dm_target_spec buffers together. + std::string target_string; + for (const auto& extent : partition.extents) { + target_string += extent.Serialize(); + } + + // Allocate the ioctl buffer. + size_t buffer_size = sizeof(struct dm_ioctl) + target_string.size(); + std::unique_ptr buffer = std::make_unique(buffer_size); + + // Initialize the ioctl buffer header, then copy our target specs in. + struct dm_ioctl* io = reinterpret_cast(buffer.get()); + fs_mgr_dm_ioctl_init(io, buffer_size, partition.name); + io->target_count = partition.extents.size(); + if (partition.attributes & kPartitionReadonly) { + io->flags |= DM_READONLY_FLAG; + } + memcpy(io + 1, target_string.c_str(), target_string.size()); + + if (ioctl(dm_fd, DM_TABLE_LOAD, io)) { + PERROR << "Failed ioctl() on DM_TABLE_LOAD, partition " << partition.name; + return false; + } + return true; +} + +static bool LoadTablesAndActivate(int dm_fd, const LogicalPartition& partition) { + if (!LoadDmTable(dm_fd, partition)) { + return false; + } + + struct dm_ioctl io; + return fs_mgr_dm_resume_table(&io, partition.name, dm_fd); +} + +static bool CreateDmDeviceForPartition(int dm_fd, const LogicalPartition& partition) { + struct dm_ioctl io; + if (!fs_mgr_dm_create_device(&io, partition.name, dm_fd)) { + return false; + } + if (!LoadTablesAndActivate(dm_fd, partition)) { + // Remove the device rather than leave it in an inactive state. + fs_mgr_dm_destroy_device(&io, partition.name, dm_fd); + return false; + } + + LINFO << "Created device-mapper device: " << partition.name; + return true; +} + +bool CreateLogicalPartitions(const LogicalPartitionTable& table) { + android::base::unique_fd dm_fd(open("/dev/device-mapper", O_RDWR)); + if (dm_fd < 0) { + PLOG(ERROR) << "failed to open /dev/device-mapper"; + return false; + } + for (const auto& partition : table.partitions) { + if (!CreateDmDeviceForPartition(dm_fd, partition)) { + LOG(ERROR) << "could not create dm-linear device for partition: " << partition.name; + return false; + } + } + return true; +} + +std::unique_ptr LoadPartitionsFromDeviceTree() { + return nullptr; +} + +} // namespace fs_mgr +} // namespace android diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp index 3fbef9fc2..472ab59c7 100644 --- a/fs_mgr/fs_mgr_fstab.cpp +++ b/fs_mgr/fs_mgr_fstab.cpp @@ -109,6 +109,7 @@ static struct flag_list fs_mgr_flags[] = { {"logicalblk=", MF_LOGICALBLKSIZE}, {"sysfs_path=", MF_SYSFS}, {"defaults", 0}, + {"logical", MF_LOGICAL}, {0, 0}, }; @@ -445,10 +446,6 @@ static std::string read_fstab_from_dt() { LERROR << "dt_fstab: Failed to find device for partition " << dp->d_name; return {}; } - if (!StartsWith(value, "/dev")) { - LERROR << "dt_fstab: Invalid device node for partition " << dp->d_name; - return {}; - } fstab_entry.push_back(value); std::string mount_point; @@ -631,6 +628,10 @@ static struct fstab *fs_mgr_read_fstab_file(FILE *fstab_file) fstab->recs[cnt].erase_blk_size = flag_vals.erase_blk_size; fstab->recs[cnt].logical_blk_size = flag_vals.logical_blk_size; fstab->recs[cnt].sysfs_path = flag_vals.sysfs_path; + if (fstab->recs[cnt].fs_mgr_flags & MF_LOGICAL) { + fstab->recs[cnt].logical_partition_name = strdup(fstab->recs[cnt].blk_device); + } + cnt++; } /* If an A/B partition, modify block device to be the real block device */ @@ -797,6 +798,7 @@ void fs_mgr_free_fstab(struct fstab *fstab) for (i = 0; i < fstab->num_entries; i++) { /* Free the pointers return by strdup(3) */ free(fstab->recs[i].blk_device); + free(fstab->recs[i].logical_partition_name); free(fstab->recs[i].mount_point); free(fstab->recs[i].fs_type); free(fstab->recs[i].fs_options); @@ -944,3 +946,7 @@ int fs_mgr_has_sysfs_path(const struct fstab_rec *fstab) { return fstab->fs_mgr_flags & MF_SYSFS; } + +int fs_mgr_is_logical(const struct fstab_rec* fstab) { + return fstab->fs_mgr_flags & MF_LOGICAL; +} diff --git a/fs_mgr/fs_mgr_priv.h b/fs_mgr/fs_mgr_priv.h index ade0cc4cd..afd722790 100644 --- a/fs_mgr/fs_mgr_priv.h +++ b/fs_mgr/fs_mgr_priv.h @@ -82,6 +82,7 @@ * */ +// clang-format off #define MF_WAIT 0x1 #define MF_CHECK 0x2 #define MF_CRYPT 0x4 @@ -111,6 +112,8 @@ #define MF_AVB 0X2000000 #define MF_KEYDIRECTORY 0X4000000 #define MF_SYSFS 0X8000000 +#define MF_LOGICAL 0x10000000 +// clang-format on #define DM_BUF_SIZE 4096 diff --git a/fs_mgr/fs_mgr_slotselect.cpp b/fs_mgr/fs_mgr_slotselect.cpp index 0a113b47e..3b01d0e80 100644 --- a/fs_mgr/fs_mgr_slotselect.cpp +++ b/fs_mgr/fs_mgr_slotselect.cpp @@ -36,19 +36,30 @@ bool fs_mgr_update_for_slotselect(struct fstab *fstab) { std::string ab_suffix; for (n = 0; n < fstab->num_entries; n++) { - if (fstab->recs[n].fs_mgr_flags & MF_SLOTSELECT) { - char *tmp; + fstab_rec& record = fstab->recs[n]; + if (record.fs_mgr_flags & MF_SLOTSELECT) { if (ab_suffix.empty()) { ab_suffix = fs_mgr_get_slot_suffix(); // Return false if failed to get ab_suffix when MF_SLOTSELECT is specified. if (ab_suffix.empty()) return false; } - if (asprintf(&tmp, "%s%s", fstab->recs[n].blk_device, ab_suffix.c_str()) > 0) { - free(fstab->recs[n].blk_device); - fstab->recs[n].blk_device = tmp; - } else { + + char* new_blk_device; + if (asprintf(&new_blk_device, "%s%s", record.blk_device, ab_suffix.c_str()) <= 0) { return false; } + free(record.blk_device); + record.blk_device = new_blk_device; + + char* new_partition_name; + if (record.logical_partition_name) { + if (asprintf(&new_partition_name, "%s%s", record.logical_partition_name, + ab_suffix.c_str()) <= 0) { + return false; + } + free(record.logical_partition_name); + record.logical_partition_name = new_partition_name; + } } } return true; diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h index 653d8fa01..72f019e21 100644 --- a/fs_mgr/include/fs_mgr.h +++ b/fs_mgr/include/fs_mgr.h @@ -76,6 +76,7 @@ void fs_mgr_get_crypt_info(struct fstab* fstab, char* key_loc, char* real_blk_de bool fs_mgr_load_verity_state(int* mode); bool fs_mgr_update_verity_state(fs_mgr_verity_state_callback callback); int fs_mgr_swapon_all(struct fstab *fstab); +bool fs_mgr_update_logical_partition(struct fstab_rec* rec); int fs_mgr_do_format(struct fstab_rec *fstab, bool reserve_footer); diff --git a/fs_mgr/include/fs_mgr_dm_linear.h b/fs_mgr/include/fs_mgr_dm_linear.h new file mode 100644 index 000000000..7f928e508 --- /dev/null +++ b/fs_mgr/include/fs_mgr_dm_linear.h @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef __CORE_FS_MGR_DM_LINEAR_H +#define __CORE_FS_MGR_DM_LINEAR_H + +#include +#include +#include +#include + +namespace android { +namespace fs_mgr { + +static const uint32_t kPartitionReadonly = 0x1; + +class LogicalPartitionExtent { + public: + LogicalPartitionExtent() : logical_sector_(0), first_sector_(0), num_sectors_(0) {} + LogicalPartitionExtent(uint64_t logical_sector, uint64_t first_sector, uint64_t num_sectors, + const std::string& block_device) + : logical_sector_(logical_sector), + first_sector_(first_sector), + num_sectors_(num_sectors), + block_device_(block_device) {} + + // Return a string containing the dm_target_spec buffer needed to use this + // extent in a device-mapper table. + std::string Serialize() const; + + const std::string& block_device() const { return block_device_; } + + private: + // Logical sector this extent represents in the presented block device. + // This is equal to the previous extent's logical sector plus the number + // of sectors in that extent. The first extent always starts at 0. + uint64_t logical_sector_; + // First 512-byte sector of this extent, on the source block device. + uint64_t first_sector_; + // Number of 512-byte sectors. + uint64_t num_sectors_; + // Target block device. + std::string block_device_; +}; + +struct LogicalPartition { + LogicalPartition() : attributes(0), num_sectors(0) {} + + std::string name; + uint32_t attributes; + // Number of 512-byte sectors total. + uint64_t num_sectors; + // List of extents. + std::vector extents; +}; + +struct LogicalPartitionTable { + // List of partitions in the partition table. + std::vector partitions; +}; + +// Load a dm-linear table from the device tree if one is available; otherwise, +// return null. +std::unique_ptr LoadPartitionsFromDeviceTree(); + +// Create device-mapper devices for the given partition table. +// +// On success, two devices nodes will be created for each partition, both +// pointing to the same device: +// /dev/block/dm- where N is a sequential ID assigned by device-mapper. +// /dev/block/dm- where |name| is the partition name. +// +bool CreateLogicalPartitions(const LogicalPartitionTable& table); + +} // namespace fs_mgr +} // namespace android + +#endif // __CORE_FS_MGR_DM_LINEAR_H diff --git a/fs_mgr/include_fstab/fstab/fstab.h b/fs_mgr/include_fstab/fstab/fstab.h index 8c585dd2f..04ccfc5c6 100644 --- a/fs_mgr/include_fstab/fstab/fstab.h +++ b/fs_mgr/include_fstab/fstab/fstab.h @@ -37,6 +37,7 @@ struct fstab { struct fstab_rec { char* blk_device; + char* logical_partition_name; char* mount_point; char* fs_type; unsigned long flags; @@ -84,6 +85,7 @@ int fs_mgr_is_slotselect(const struct fstab_rec* fstab); int fs_mgr_is_nofail(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); int fs_mgr_has_sysfs_path(const struct fstab_rec* fstab); std::string fs_mgr_get_slot_suffix(); diff --git a/init/init_first_stage.cpp b/init/init_first_stage.cpp index 1b6e97ec7..a5ba6473a 100644 --- a/init/init_first_stage.cpp +++ b/init/init_first_stage.cpp @@ -33,11 +33,13 @@ #include "devices.h" #include "fs_mgr.h" #include "fs_mgr_avb.h" +#include "fs_mgr_dm_linear.h" #include "uevent.h" #include "uevent_listener.h" #include "util.h" using android::base::Timer; +using android::fs_mgr::LogicalPartitionTable; namespace android { namespace init { @@ -58,18 +60,21 @@ class FirstStageMount { protected: ListenerAction HandleBlockDevice(const std::string& name, const Uevent&); bool InitRequiredDevices(); - bool InitVerityDevice(const std::string& verity_device); + bool InitMappedDevice(const std::string& verity_device); + bool CreateLogicalPartitions(); bool MountPartitions(); + bool GetBackingDmLinearDevices(); virtual ListenerAction UeventCallback(const Uevent& uevent); // Pure virtual functions. - virtual bool GetRequiredDevices() = 0; + virtual bool GetDmVerityDevices() = 0; virtual bool SetUpDmVerity(fstab_rec* fstab_rec) = 0; bool need_dm_verity_; std::unique_ptr device_tree_fstab_; + std::unique_ptr dm_linear_table_; std::vector mount_fstab_recs_; std::set required_devices_partition_names_; DeviceHandler device_handler_; @@ -82,7 +87,7 @@ class FirstStageMountVBootV1 : public FirstStageMount { ~FirstStageMountVBootV1() override = default; protected: - bool GetRequiredDevices() override; + bool GetDmVerityDevices() override; bool SetUpDmVerity(fstab_rec* fstab_rec) override; }; @@ -95,7 +100,7 @@ class FirstStageMountVBootV2 : public FirstStageMount { protected: ListenerAction UeventCallback(const Uevent& uevent) override; - bool GetRequiredDevices() override; + bool GetDmVerityDevices() override; bool SetUpDmVerity(fstab_rec* fstab_rec) override; bool InitAvbHandle(); @@ -114,6 +119,17 @@ static bool inline IsRecoveryMode() { return access("/sbin/recovery", F_OK) == 0; } +static inline bool IsDmLinearEnabled() { + bool enabled = false; + import_kernel_cmdline( + false, [&enabled](const std::string& key, const std::string& value, bool in_qemu) { + if (key == "androidboot.lrap" && value == "1") { + enabled = true; + } + }); + return enabled; +} + // Class Definitions // ----------------- FirstStageMount::FirstStageMount() @@ -127,6 +143,10 @@ FirstStageMount::FirstStageMount() } else { LOG(INFO) << "Failed to read fstab from device tree"; } + + if (IsDmLinearEnabled()) { + dm_linear_table_ = android::fs_mgr::LoadPartitionsFromDeviceTree(); + } } std::unique_ptr FirstStageMount::Create() { @@ -138,7 +158,7 @@ std::unique_ptr FirstStageMount::Create() { } bool FirstStageMount::DoFirstStageMount() { - if (mount_fstab_recs_.empty()) { + if (!dm_linear_table_ && mount_fstab_recs_.empty()) { // Nothing to mount. LOG(INFO) << "First stage mount skipped (missing/incompatible/empty fstab in device tree)"; return true; @@ -146,13 +166,30 @@ bool FirstStageMount::DoFirstStageMount() { if (!InitDevices()) return false; + if (!CreateLogicalPartitions()) return false; + if (!MountPartitions()) return false; return true; } bool FirstStageMount::InitDevices() { - return GetRequiredDevices() && InitRequiredDevices(); + return GetBackingDmLinearDevices() && GetDmVerityDevices() && InitRequiredDevices(); +} + +bool FirstStageMount::GetBackingDmLinearDevices() { + // Add any additional devices required for dm-linear mappings. + if (!dm_linear_table_) { + return true; + } + + for (const auto& partition : dm_linear_table_->partitions) { + for (const auto& extent : partition.extents) { + const std::string& partition_name = android::base::Basename(extent.block_device()); + required_devices_partition_names_.emplace(partition_name); + } + } + return true; } // Creates devices with uevent->partition_name matching one in the member variable @@ -163,7 +200,7 @@ bool FirstStageMount::InitRequiredDevices() { return true; } - if (need_dm_verity_) { + if (dm_linear_table_ || need_dm_verity_) { const std::string dm_path = "/devices/virtual/misc/device-mapper"; bool found = false; auto dm_callback = [this, &dm_path, &found](const Uevent& uevent) { @@ -210,6 +247,13 @@ bool FirstStageMount::InitRequiredDevices() { return true; } +bool FirstStageMount::CreateLogicalPartitions() { + if (!dm_linear_table_) { + return true; + } + return android::fs_mgr::CreateLogicalPartitions(*dm_linear_table_.get()); +} + ListenerAction FirstStageMount::HandleBlockDevice(const std::string& name, const Uevent& uevent) { // Matches partition name to create device nodes. // Both required_devices_partition_names_ and uevent->partition_name have A/B @@ -247,14 +291,14 @@ ListenerAction FirstStageMount::UeventCallback(const Uevent& uevent) { } // Creates "/dev/block/dm-XX" for dm-verity by running coldboot on /sys/block/dm-XX. -bool FirstStageMount::InitVerityDevice(const std::string& verity_device) { - const std::string device_name(basename(verity_device.c_str())); +bool FirstStageMount::InitMappedDevice(const std::string& dm_device) { + const std::string device_name(basename(dm_device.c_str())); const std::string syspath = "/sys/block/" + device_name; bool found = false; - auto verity_callback = [&device_name, &verity_device, this, &found](const Uevent& uevent) { + auto verity_callback = [&device_name, &dm_device, this, &found](const Uevent& uevent) { if (uevent.device_name == device_name) { - LOG(VERBOSE) << "Creating dm-verity device : " << verity_device; + LOG(VERBOSE) << "Creating device-mapper device : " << dm_device; device_handler_.HandleDeviceEvent(uevent); found = true; return ListenerAction::kStop; @@ -279,6 +323,14 @@ bool FirstStageMount::InitVerityDevice(const std::string& verity_device) { bool FirstStageMount::MountPartitions() { for (auto fstab_rec : mount_fstab_recs_) { + if (fs_mgr_is_logical(fstab_rec)) { + if (!fs_mgr_update_logical_partition(fstab_rec)) { + return false; + } + if (!InitMappedDevice(fstab_rec->blk_device)) { + return false; + } + } if (!SetUpDmVerity(fstab_rec)) { PLOG(ERROR) << "Failed to setup verity for '" << fstab_rec->mount_point << "'"; return false; @@ -291,7 +343,7 @@ bool FirstStageMount::MountPartitions() { return true; } -bool FirstStageMountVBootV1::GetRequiredDevices() { +bool FirstStageMountVBootV1::GetDmVerityDevices() { std::string verity_loc_device; need_dm_verity_ = false; @@ -344,7 +396,7 @@ bool FirstStageMountVBootV1::SetUpDmVerity(fstab_rec* fstab_rec) { // The exact block device name (fstab_rec->blk_device) is changed to // "/dev/block/dm-XX". Needs to create it because ueventd isn't started in init // first stage. - return InitVerityDevice(fstab_rec->blk_device); + return InitMappedDevice(fstab_rec->blk_device); default: return false; } @@ -371,7 +423,7 @@ FirstStageMountVBootV2::FirstStageMountVBootV2() : avb_handle_(nullptr) { } } -bool FirstStageMountVBootV2::GetRequiredDevices() { +bool FirstStageMountVBootV2::GetDmVerityDevices() { need_dm_verity_ = false; // fstab_rec->blk_device has A/B suffix. @@ -444,7 +496,7 @@ bool FirstStageMountVBootV2::SetUpDmVerity(fstab_rec* fstab_rec) { // The exact block device name (fstab_rec->blk_device) is changed to // "/dev/block/dm-XX". Needs to create it because ueventd isn't started in init // first stage. - return InitVerityDevice(fstab_rec->blk_device); + return InitMappedDevice(fstab_rec->blk_device); default: return false; }