From d1ff1bcfbcc76397b1896138ed6cbff136294d4b Mon Sep 17 00:00:00 2001 From: Yi-Yo Chiang Date: Thu, 11 Feb 2021 22:59:11 +0800 Subject: [PATCH] fs_mgr: Add OverlayMountPoints() to get the list of overlayfs backing storage Remove kOverlayMountPoints; add OverlayMountPoints(). Fix a regression where if host system didn't install a scratch_gsi partition and physical /cache partition is mounted, then DSU guest system could use /cache as its overlayfs backing storage. This is generally unwanted as the /cache partition could be shared between host and guest. Dynamically return the list of overlayfs backing storage candidates, so we don't accidentally fall back to use /cache storage within a DSU system. Bug: 165925766 Bug: 179980369 Test: 1. Prepare a DUT that have a physical cache partition, such as cuttlefish. 2. Install a DSU system, and unsure that scratch_gsi is not installed. 3. Reboot into DSU, verify that adb remount fails and overlayfs scratch is not created under /cache. Change-Id: I1815ac5367c0aac8614aeaabebe0e2cb91cbe161 --- fs_mgr/fs_mgr_overlayfs.cpp | 57 +++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 24 deletions(-) diff --git a/fs_mgr/fs_mgr_overlayfs.cpp b/fs_mgr/fs_mgr_overlayfs.cpp index 388c2967a..cdbadc9cd 100644 --- a/fs_mgr/fs_mgr_overlayfs.cpp +++ b/fs_mgr/fs_mgr_overlayfs.cpp @@ -125,10 +125,38 @@ void TeardownAllOverlayForMountPoint(const std::string&) {} namespace { +bool fs_mgr_in_recovery() { + // Check the existence of recovery binary instead of using the compile time + // macro, because first-stage-init is compiled with __ANDROID_RECOVERY__ + // defined, albeit not in recovery. More details: system/core/init/README.md + return fs_mgr_access("/system/bin/recovery"); +} + +bool fs_mgr_is_dsu_running() { + // Since android::gsi::CanBootIntoGsi() or android::gsi::MarkSystemAsGsi() is + // never called in recovery, the return value of android::gsi::IsGsiRunning() + // is not well-defined. In this case, just return false as being in recovery + // implies not running a DSU system. + if (fs_mgr_in_recovery()) return false; + auto saved_errno = errno; + auto ret = android::gsi::IsGsiRunning(); + errno = saved_errno; + return ret; +} + // list of acceptable overlayfs backing storage const auto kScratchMountPoint = "/mnt/scratch"s; const auto kCacheMountPoint = "/cache"s; -const std::vector kOverlayMountPoints = {kScratchMountPoint, kCacheMountPoint}; + +std::vector OverlayMountPoints() { + // Never fallback to legacy cache mount point if within a DSU system, + // because running a DSU system implies the device supports dynamic + // partitions, which means legacy cache mustn't be used. + if (fs_mgr_is_dsu_running()) { + return {kScratchMountPoint}; + } + return {kScratchMountPoint, kCacheMountPoint}; +} // Return true if everything is mounted, but before adb is started. Right // after 'trigger load_persist_props_action' is done. @@ -169,25 +197,6 @@ bool fs_mgr_filesystem_has_space(const std::string& mount_point) { (vst.f_bfree * vst.f_bsize) >= kSizeThreshold; } -bool fs_mgr_in_recovery() { - // Check the existence of recovery binary instead of using the compile time - // macro, because first-stage-init is compiled with __ANDROID_RECOVERY__ - // defined, albeit not in recovery. More details: system/core/init/README.md - return fs_mgr_access("/system/bin/recovery"); -} - -bool fs_mgr_is_dsu_running() { - // Since android::gsi::CanBootIntoGsi() or android::gsi::MarkSystemAsGsi() is - // never called in recovery, the return value of android::gsi::IsGsiRunning() - // is not well-defined. In this case, just return false as being in recovery - // implies not running a DSU system. - if (fs_mgr_in_recovery()) return false; - auto saved_errno = errno; - auto ret = android::gsi::IsGsiRunning(); - errno = saved_errno; - return ret; -} - const auto kPhysicalDevice = "/dev/block/by-name/"s; constexpr char kScratchImageMetadata[] = "/metadata/gsi/remount/lp_metadata"; @@ -300,7 +309,7 @@ const auto kOverlayTopDir = "/overlay"s; std::string fs_mgr_get_overlayfs_candidate(const std::string& mount_point) { if (!fs_mgr_is_dir(mount_point)) return ""; const auto base = android::base::Basename(mount_point) + "/"; - for (const auto& overlay_mount_point : kOverlayMountPoints) { + for (const auto& overlay_mount_point : OverlayMountPoints()) { auto dir = overlay_mount_point + kOverlayTopDir + "/" + base; auto upper = dir + kUpperName; if (!fs_mgr_is_dir(upper)) continue; @@ -1344,7 +1353,7 @@ bool fs_mgr_overlayfs_setup(const char* backing, const char* mount_point, bool* if (candidates.empty()) return ret; std::string dir; - for (const auto& overlay_mount_point : kOverlayMountPoints) { + for (const auto& overlay_mount_point : OverlayMountPoints()) { if (backing && backing[0] && (overlay_mount_point != backing)) continue; if (overlay_mount_point == kScratchMountPoint) { if (!fs_mgr_overlayfs_setup_scratch(fstab, change)) continue; @@ -1465,7 +1474,7 @@ bool fs_mgr_overlayfs_teardown(const char* mount_point, bool* change) { } } bool should_destroy_scratch = false; - for (const auto& overlay_mount_point : kOverlayMountPoints) { + for (const auto& overlay_mount_point : OverlayMountPoints()) { ret &= fs_mgr_overlayfs_teardown_one( overlay_mount_point, mount_point ? fs_mgr_mount_point(mount_point) : "", change, overlay_mount_point == kScratchMountPoint ? &should_destroy_scratch : nullptr); @@ -1569,7 +1578,7 @@ void TeardownAllOverlayForMountPoint(const std::string& mount_point) { constexpr bool* ignore_change = nullptr; // Teardown legacy overlay mount points that's not backed by a scratch device. - for (const auto& overlay_mount_point : kOverlayMountPoints) { + for (const auto& overlay_mount_point : OverlayMountPoints()) { if (overlay_mount_point == kScratchMountPoint) { continue; }