From f89b1df1a5075753bf2a72699fd4bc441ca2af13 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Mon, 5 Nov 2018 17:30:16 -0800 Subject: [PATCH] init: Regenerate uevents for dependent super partition devices. This patch adds another uevent-regeneration pass to the first stage mount. When the super partition spans multiple block devices, we need /dev/block/by-name symlinks to have been created before we begin mapping dynamic partitions. Bug: 116802789 Test: retrofit device boots Change-Id: I00bb277e1d81385a457c5b4205a95d8fbe365bb2 --- fs_mgr/fs_mgr_dm_linear.cpp | 13 +++++++-- fs_mgr/include/fs_mgr_dm_linear.h | 11 +++++++- fs_mgr/liblp/include/liblp/liblp.h | 3 ++ fs_mgr/liblp/utility.cpp | 8 ++++++ init/first_stage_mount.cpp | 44 ++++++++++++++++++++++++++---- 5 files changed, 70 insertions(+), 9 deletions(-) diff --git a/fs_mgr/fs_mgr_dm_linear.cpp b/fs_mgr/fs_mgr_dm_linear.cpp index 4dacebfb0..fe0e03947 100644 --- a/fs_mgr/fs_mgr_dm_linear.cpp +++ b/fs_mgr/fs_mgr_dm_linear.cpp @@ -137,13 +137,22 @@ bool CreateLogicalPartitions(const std::string& block_device) { LOG(ERROR) << "Could not read partition table."; return true; } - for (const auto& partition : metadata->partitions) { + return CreateLogicalPartitions(*metadata.get()); +} + +std::unique_ptr ReadCurrentMetadata(const std::string& block_device) { + uint32_t slot = SlotNumberForSlotSuffix(fs_mgr_get_slot_suffix()); + return ReadMetadata(block_device.c_str(), slot); +} + +bool CreateLogicalPartitions(const LpMetadata& metadata) { + for (const auto& partition : metadata.partitions) { if (!partition.num_extents) { LINFO << "Skipping zero-length logical partition: " << GetPartitionName(partition); continue; } std::string path; - if (!CreateLogicalPartition(*metadata.get(), partition, false, {}, &path)) { + if (!CreateLogicalPartition(metadata, partition, false, {}, &path)) { LERROR << "Could not create logical partition: " << GetPartitionName(partition); return false; } diff --git a/fs_mgr/include/fs_mgr_dm_linear.h b/fs_mgr/include/fs_mgr_dm_linear.h index 08f455474..66abfca16 100644 --- a/fs_mgr/include/fs_mgr_dm_linear.h +++ b/fs_mgr/include/fs_mgr_dm_linear.h @@ -33,11 +33,20 @@ #include #include -#include +#include namespace android { namespace fs_mgr { +// Read metadata from the current slot. +std::unique_ptr ReadCurrentMetadata(const std::string& block_device); + +// Create block devices for all logical partitions in the given metadata. The +// metadata must have been read from the current slot. +bool CreateLogicalPartitions(const LpMetadata& metadata); + +// Create block devices for all logical partitions. This is a convenience +// method for ReadMetadata and CreateLogicalPartitions. bool CreateLogicalPartitions(const std::string& block_device); // Create a block device for a single logical partition, given metadata and diff --git a/fs_mgr/liblp/include/liblp/liblp.h b/fs_mgr/liblp/include/liblp/liblp.h index 4669cea55..a5dac000c 100644 --- a/fs_mgr/liblp/include/liblp/liblp.h +++ b/fs_mgr/liblp/include/liblp/liblp.h @@ -90,6 +90,9 @@ const LpMetadataBlockDevice* GetMetadataSuperBlockDevice(const LpMetadata& metad // Return the total size of all partitions comprising the super partition. uint64_t GetTotalSuperPartitionSize(const LpMetadata& metadata); +// Get the list of block device names required by the given metadata. +std::vector GetBlockDevicePartitionNames(const LpMetadata& metadata); + // Helper to return a slot number for a slot suffix. uint32_t SlotNumberForSlotSuffix(const std::string& suffix); diff --git a/fs_mgr/liblp/utility.cpp b/fs_mgr/liblp/utility.cpp index 742ad823e..199d9945b 100644 --- a/fs_mgr/liblp/utility.cpp +++ b/fs_mgr/liblp/utility.cpp @@ -116,5 +116,13 @@ uint64_t GetTotalSuperPartitionSize(const LpMetadata& metadata) { return size; } +std::vector GetBlockDevicePartitionNames(const LpMetadata& metadata) { + std::vector list; + for (const auto& block_device : metadata.block_devices) { + list.emplace_back(GetBlockDevicePartitionName(block_device)); + } + return list; +} + } // namespace fs_mgr } // namespace android diff --git a/init/first_stage_mount.cpp b/init/first_stage_mount.cpp index eb86eb087..13a9d0809 100644 --- a/init/first_stage_mount.cpp +++ b/init/first_stage_mount.cpp @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include "devices.h" #include "switch_root.h" @@ -69,7 +69,8 @@ class FirstStageMount { bool MountPartition(fstab_rec* fstab_rec); bool MountPartitions(); bool IsDmLinearEnabled(); - bool GetBackingDmLinearDevices(); + bool GetDmLinearMetadataDevice(); + bool InitDmLinearBackingDevices(const android::fs_mgr::LpMetadata& metadata); virtual ListenerAction UeventCallback(const Uevent& uevent); @@ -183,7 +184,7 @@ bool FirstStageMount::DoFirstStageMount() { } bool FirstStageMount::InitDevices() { - return GetBackingDmLinearDevices() && GetDmVerityDevices() && InitRequiredDevices(); + return GetDmLinearMetadataDevice() && GetDmVerityDevices() && InitRequiredDevices(); } bool FirstStageMount::IsDmLinearEnabled() { @@ -193,7 +194,7 @@ bool FirstStageMount::IsDmLinearEnabled() { return false; } -bool FirstStageMount::GetBackingDmLinearDevices() { +bool FirstStageMount::GetDmLinearMetadataDevice() { // Add any additional devices required for dm-linear mappings. if (!IsDmLinearEnabled()) { return true; @@ -258,17 +259,48 @@ bool FirstStageMount::InitRequiredDevices() { return true; } +bool FirstStageMount::InitDmLinearBackingDevices(const android::fs_mgr::LpMetadata& metadata) { + auto partition_names = GetBlockDevicePartitionNames(metadata); + for (const auto& partition_name : partition_names) { + if (partition_name == lp_metadata_partition_) { + continue; + } + required_devices_partition_names_.emplace(partition_name); + } + if (required_devices_partition_names_.empty()) { + return true; + } + + auto uevent_callback = [this](const Uevent& uevent) { return UeventCallback(uevent); }; + uevent_listener_.RegenerateUevents(uevent_callback); + + if (!required_devices_partition_names_.empty()) { + LOG(ERROR) << __PRETTY_FUNCTION__ << ": partition(s) not found after polling timeout: " + << android::base::Join(required_devices_partition_names_, ", "); + return false; + } + return true; +} + bool FirstStageMount::CreateLogicalPartitions() { if (!IsDmLinearEnabled()) { return true; } - if (lp_metadata_partition_.empty()) { LOG(ERROR) << "Could not locate logical partition tables in partition " << super_partition_name_; return false; } - return android::fs_mgr::CreateLogicalPartitions(lp_metadata_partition_); + + auto metadata = android::fs_mgr::ReadCurrentMetadata(lp_metadata_partition_); + if (!metadata) { + LOG(ERROR) << "Could not read logical partition metadata from " << lp_metadata_partition_; + return false; + } + if (!InitDmLinearBackingDevices(*metadata.get())) { + return false; + } + return android::fs_mgr::CreateLogicalPartitions(*metadata.get()); } ListenerAction FirstStageMount::HandleBlockDevice(const std::string& name, const Uevent& uevent) {