From a3bf8478a3b40a7a205c829162102bc3dffd4428 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Tue, 10 Dec 2019 20:43:40 -0800 Subject: [PATCH] remount: Do not run the create-scratch logic on older devices. The prologue of fs_mgr_overlayfs_create_scratch() will implicitly succeed on physical block devices, and implicitly fail if for some reason they can't be accessed. This patch makes the success and failure cases explicit. The logic specific to DAP has been moved to CreateDynamicScratch. fs_mgr_overlayfs_create_scratch now calls GetScratchStrategy, and only calls CreateDynamicScratch for DAP-launch devices. In the case a physical block device can be used, no action is taken. Bug: 134949511 Test: adb remount and adb_remount_test.sh Change-Id: I0af7cda9bc551416c9e2ffca5a36305f89d3bf46 --- fs_mgr/fs_mgr_overlayfs.cpp | 46 ++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/fs_mgr/fs_mgr_overlayfs.cpp b/fs_mgr/fs_mgr_overlayfs.cpp index 233706583..a2fe22e5c 100644 --- a/fs_mgr/fs_mgr_overlayfs.cpp +++ b/fs_mgr/fs_mgr_overlayfs.cpp @@ -825,7 +825,8 @@ enum class ScratchStrategy { kSystemOther }; -static ScratchStrategy GetScratchStrategy(std::string* backing_device) { +// Return the strategy this device must use for creating a scratch partition. +static ScratchStrategy GetScratchStrategy(std::string* backing_device = nullptr) { auto slot_number = fs_mgr_overlayfs_slot_number(); auto super_device = fs_mgr_overlayfs_super_device(slot_number); auto path = fs_mgr_overlayfs_super_device(slot_number == 0); @@ -834,11 +835,11 @@ static ScratchStrategy GetScratchStrategy(std::string* backing_device) { // wouldn't have registed by-name symlinks for the device as it's // normally not needed. The access checks elsewhere in this function // are safe because system/super are always required. - *backing_device = path; + if (backing_device) *backing_device = path; return ScratchStrategy::kSuperOther; } if (fs_mgr_access(super_device)) { - *backing_device = super_device; + if (backing_device) *backing_device = super_device; return ScratchStrategy::kDynamicPartition; } @@ -846,7 +847,7 @@ static ScratchStrategy GetScratchStrategy(std::string* backing_device) { if (!other_slot.empty()) { path = kPhysicalDevice + "system" + other_slot; if (fs_mgr_access(path)) { - *backing_device = path; + if (backing_device) *backing_device = path; return ScratchStrategy::kSystemOther; } } @@ -924,16 +925,15 @@ static void TruncatePartitionsWithSuffix(MetadataBuilder* builder, const std::st } } -// This is where we find and steal backing storage from the system. -bool fs_mgr_overlayfs_create_scratch(const Fstab& fstab, std::string* scratch_device, - bool* partition_exists, bool* change) { - *scratch_device = fs_mgr_overlayfs_scratch_device(); - *partition_exists = fs_mgr_rw_access(*scratch_device); +// Create or update a scratch partition within super. +static bool CreateDynamicScratch(const Fstab& fstab, std::string* scratch_device, + bool* partition_exists, bool* change) { + const auto partition_name = android::base::Basename(kScratchMountPoint); + + auto& dm = DeviceMapper::Instance(); + *partition_exists = dm.GetState(partition_name) != DmDeviceState::INVALID; + auto partition_create = !*partition_exists; - // Do we need to create a logical "scratch" partition? - if (!partition_create && android::base::StartsWith(*scratch_device, kPhysicalDevice)) { - return true; - } auto slot_number = fs_mgr_overlayfs_slot_number(); auto super_device = fs_mgr_overlayfs_super_device(slot_number); if (!fs_mgr_rw_access(super_device)) return false; @@ -943,7 +943,6 @@ bool fs_mgr_overlayfs_create_scratch(const Fstab& fstab, std::string* scratch_de LERROR << "open " << super_device << " metadata"; return false; } - const auto partition_name = android::base::Basename(kScratchMountPoint); auto partition = builder->FindPartition(partition_name); *partition_exists = partition != nullptr; auto changed = false; @@ -1024,6 +1023,25 @@ bool fs_mgr_overlayfs_create_scratch(const Fstab& fstab, std::string* scratch_de return true; } +bool fs_mgr_overlayfs_create_scratch(const Fstab& fstab, std::string* scratch_device, + bool* partition_exists, bool* change) { + auto strategy = GetScratchStrategy(); + if (strategy == ScratchStrategy::kDynamicPartition) { + return CreateDynamicScratch(fstab, scratch_device, partition_exists, change); + } + + // The scratch partition can only be landed on a physical partition if we + // get here. If there are no viable candidates that are R/W, just return + // that there is no device. + *scratch_device = GetScratchDevice(); + if (scratch_device->empty()) { + errno = ENXIO; + return false; + } + *partition_exists = true; + return true; +} + // Create and mount kScratchMountPoint storage if we have logical partitions bool fs_mgr_overlayfs_setup_scratch(const Fstab& fstab, bool* change) { if (fs_mgr_overlayfs_already_mounted(kScratchMountPoint, false)) return true;