From 864021fbf6578ba0c4ba10cbd3aeb40471c6a244 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Tue, 10 Dec 2019 21:07:51 -0800 Subject: [PATCH] remount: Refactor fs_mgr_overlayfs_scratch_device(). This splits fs_mgr_overlayfs_scratch_device into two new methods. The first, GetScratchStrategy, returns an enum detailing exactly how the device will find space for scratch: - via system_, - via super_, or - via a dynamic partition. The second method, GetScratchDevice, uses the strategy to either return the underlying block device, or look up a dynamic partition. fs_mgr_overlayfs_scratch_device will be removed completely in a separate patch. Bug: 134949511 Test: adb remount and adb_remount_test.sh Change-Id: Ic7e3815ada4adaf5fd7c19b84dc22249f3dcc881 --- fs_mgr/fs_mgr_overlayfs.cpp | 74 ++++++++++++++++++++++++++++++------- 1 file changed, 60 insertions(+), 14 deletions(-) diff --git a/fs_mgr/fs_mgr_overlayfs.cpp b/fs_mgr/fs_mgr_overlayfs.cpp index 05f3311cf..233706583 100644 --- a/fs_mgr/fs_mgr_overlayfs.cpp +++ b/fs_mgr/fs_mgr_overlayfs.cpp @@ -815,26 +815,72 @@ std::string fs_mgr_overlayfs_scratch_mount_type() { return "auto"; } -std::string fs_mgr_overlayfs_scratch_device() { - if (!scratch_device_cache.empty()) return scratch_device_cache; +enum class ScratchStrategy { + kNone, + // DAP device, use logical partitions. + kDynamicPartition, + // Retrofit DAP device, use super_. + kSuperOther, + // Pre-DAP device, uses the other slot. + kSystemOther +}; - // Is this a multiple super device (retrofit)? +static ScratchStrategy GetScratchStrategy(std::string* backing_device) { 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); - if (super_device == path) { - // Create from within single super device; - auto& dm = DeviceMapper::Instance(); - const auto partition_name = android::base::Basename(kScratchMountPoint); - if (!dm.GetDmDevicePathByName(partition_name, &path)) { - // non-DAP A/B device? - if (fs_mgr_access(super_device)) return ""; - auto other_slot = fs_mgr_get_other_slot_suffix(); - if (other_slot.empty()) return ""; - path = kPhysicalDevice + "system" + other_slot; + if (super_device != path) { + // Note: we do not check access() here, since in first-stage init we + // 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; + return ScratchStrategy::kSuperOther; + } + if (fs_mgr_access(super_device)) { + *backing_device = super_device; + return ScratchStrategy::kDynamicPartition; + } + + auto other_slot = fs_mgr_get_other_slot_suffix(); + if (!other_slot.empty()) { + path = kPhysicalDevice + "system" + other_slot; + if (fs_mgr_access(path)) { + *backing_device = path; + return ScratchStrategy::kSystemOther; } } - return scratch_device_cache = path; + return ScratchStrategy::kNone; +} + +// Return the scratch device if it exists. +static std::string GetScratchDevice() { + std::string device; + ScratchStrategy strategy = GetScratchStrategy(&device); + + switch (strategy) { + case ScratchStrategy::kSuperOther: + case ScratchStrategy::kSystemOther: + return device; + case ScratchStrategy::kDynamicPartition: { + auto& dm = DeviceMapper::Instance(); + auto partition_name = android::base::Basename(kScratchMountPoint); + if (dm.GetState(partition_name) != DmDeviceState::INVALID && + dm.GetDmDevicePathByName(partition_name, &device)) { + return device; + } + return ""; + } + default: + return ""; + } +} + +std::string fs_mgr_overlayfs_scratch_device() { + if (!scratch_device_cache.empty()) return scratch_device_cache; + + scratch_device_cache = GetScratchDevice(); + return scratch_device_cache; } bool fs_mgr_overlayfs_make_scratch(const std::string& scratch_device, const std::string& mnt_type) {