Loading fastboot/device/flashing.cpp +3 −3 Original line number Diff line number Diff line Loading @@ -67,7 +67,7 @@ void WipeOverlayfsForPartition(FastbootDevice* device, const std::string& partit if ((partition + device->GetCurrentSlot()) == partition_name) { mount_metadata.emplace(); fs_mgr_overlayfs_teardown(entry.mount_point.c_str()); android::fs_mgr::TeardownAllOverlayForMountPoint(entry.mount_point); } } } Loading Loading @@ -194,7 +194,7 @@ bool UpdateSuper(FastbootDevice* device, const std::string& super_name, bool wip if (!FlashPartitionTable(super_name, *new_metadata.get())) { return device->WriteFail("Unable to flash new partition table"); } fs_mgr_overlayfs_teardown(); android::fs_mgr::TeardownAllOverlayForMountPoint(); sync(); return device->WriteOkay("Successfully flashed partition table"); } Loading Loading @@ -234,7 +234,7 @@ bool UpdateSuper(FastbootDevice* device, const std::string& super_name, bool wip if (!UpdateAllPartitionMetadata(device, super_name, *new_metadata.get())) { return device->WriteFail("Unable to write new partition table"); } fs_mgr_overlayfs_teardown(); android::fs_mgr::TeardownAllOverlayForMountPoint(); sync(); return device->WriteOkay("Successfully updated partition table"); } fs_mgr/fs_mgr_overlayfs.cpp +154 −23 Original line number Diff line number Diff line Loading @@ -73,6 +73,25 @@ bool fs_mgr_access(const std::string& path) { return ret; } 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; } // determine if a filesystem is available bool fs_mgr_overlayfs_filesystem_available(const std::string& filesystem) { std::string filesystems; Loading Loading @@ -113,8 +132,11 @@ bool fs_mgr_overlayfs_is_setup() { namespace android { namespace fs_mgr { void MapScratchPartitionIfNeeded(Fstab*, const std::function<bool(const std::set<std::string>&)>&) {} void MapScratchPartitionIfNeeded(Fstab*, const std::function<bool(const std::set<std::string>&)>&) { } void TeardownAllOverlayForMountPoint(const std::string&) {} } // namespace fs_mgr } // namespace android Loading Loading @@ -171,6 +193,10 @@ constexpr char kScratchImageMetadata[] = "/metadata/gsi/remount/lp_metadata"; // Note: this is meant only for recovery/first-stage init. bool ScratchIsOnData() { // The scratch partition of DSU is managed by gsid. if (fs_mgr_is_dsu_running()) { return false; } return fs_mgr_access(kScratchImageMetadata); } Loading Loading @@ -464,6 +490,12 @@ bool fs_mgr_overlayfs_teardown_scratch(const std::string& overlay, bool* change) // umount and delete kScratchMountPoint storage if we have logical partitions if (overlay != kScratchMountPoint) return true; // Validation check. if (fs_mgr_is_dsu_running()) { LERROR << "Destroying DSU scratch is not allowed."; return false; } auto save_errno = errno; if (fs_mgr_overlayfs_already_mounted(kScratchMountPoint, false)) { fs_mgr_overlayfs_umount_scratch(); Loading Loading @@ -512,10 +544,13 @@ bool fs_mgr_overlayfs_teardown_scratch(const std::string& overlay, bool* change) } bool fs_mgr_overlayfs_teardown_one(const std::string& overlay, const std::string& mount_point, bool* change) { bool* change, bool* should_destroy_scratch = nullptr) { const auto top = overlay + kOverlayTopDir; if (!fs_mgr_access(top)) return fs_mgr_overlayfs_teardown_scratch(overlay, change); if (!fs_mgr_access(top)) { if (should_destroy_scratch) *should_destroy_scratch = true; return true; } auto cleanup_all = mount_point.empty(); const auto partition_name = android::base::Basename(mount_point); Loading Loading @@ -571,7 +606,7 @@ bool fs_mgr_overlayfs_teardown_one(const std::string& overlay, const std::string PERROR << "rmdir " << top; } } if (cleanup_all) ret &= fs_mgr_overlayfs_teardown_scratch(overlay, change); if (should_destroy_scratch) *should_destroy_scratch = cleanup_all; return ret; } Loading Loading @@ -881,12 +916,29 @@ static std::string GetPhysicalScratchDevice() { return ""; } // Note: The scratch partition of DSU is managed by gsid, and should be initialized during // first-stage-mount. Just check if the DM device for DSU scratch partition is created or not. static std::string GetDsuScratchDevice() { auto& dm = DeviceMapper::Instance(); std::string device; if (dm.GetState(android::gsi::kDsuScratch) != DmDeviceState::INVALID && dm.GetDmDevicePathByName(android::gsi::kDsuScratch, &device)) { return device; } return ""; } // This returns the scratch device that was detected during early boot (first- // stage init). If the device was created later, for example during setup for // the adb remount command, it can return an empty string since it does not // query ImageManager. (Note that ImageManager in first-stage init will always // use device-mapper, since /data is not available to use loop devices.) static std::string GetBootScratchDevice() { // Note: fs_mgr_is_dsu_running() always returns false in recovery or fastbootd. if (fs_mgr_is_dsu_running()) { return GetDsuScratchDevice(); } auto& dm = DeviceMapper::Instance(); // If there is a scratch partition allocated in /data or on super, we Loading Loading @@ -1108,6 +1160,14 @@ static bool CanUseSuperPartition(const Fstab& fstab, bool* is_virtual_ab) { bool fs_mgr_overlayfs_create_scratch(const Fstab& fstab, std::string* scratch_device, bool* partition_exists, bool* change) { // Use the DSU scratch device managed by gsid if within a DSU system. if (fs_mgr_is_dsu_running()) { *scratch_device = GetDsuScratchDevice(); *partition_exists = !scratch_device->empty(); *change = false; return *partition_exists; } // Try a physical partition first. *scratch_device = GetPhysicalScratchDevice(); if (!scratch_device->empty() && fs_mgr_rw_access(*scratch_device)) { Loading Loading @@ -1166,12 +1226,8 @@ bool fs_mgr_overlayfs_setup_scratch(const Fstab& fstab, bool* change) { bool fs_mgr_overlayfs_invalid() { if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kNotSupported) return true; // in recovery, fastbootd, or gsi mode, not allowed! if (fs_mgr_access("/system/bin/recovery")) return true; auto save_errno = errno; auto ret = android::gsi::IsGsiRunning(); errno = save_errno; return ret; // in recovery or fastbootd, not allowed! return fs_mgr_in_recovery(); } } // namespace Loading Loading @@ -1314,6 +1370,8 @@ bool fs_mgr_overlayfs_setup(const char* backing, const char* mount_point, bool* return ret; } // Note: This function never returns the DSU scratch device in recovery or fastbootd, // because the DSU scratch is created in the first-stage-mount, which is not run in recovery. static bool EnsureScratchMapped(std::string* device, bool* mapped) { *mapped = false; *device = GetBootScratchDevice(); Loading @@ -1321,6 +1379,11 @@ static bool EnsureScratchMapped(std::string* device, bool* mapped) { return true; } if (!fs_mgr_in_recovery()) { errno = EINVAL; return false; } auto partition_name = android::base::Basename(kScratchMountPoint); // Check for scratch on /data first, before looking for a modified super Loading Loading @@ -1362,10 +1425,27 @@ static bool EnsureScratchMapped(std::string* device, bool* mapped) { return true; } static void UnmapScratchDevice() { // This should only be reachable in recovery, where scratch is not // automatically mapped and therefore can be unmapped. DestroyLogicalPartition(android::base::Basename(kScratchMountPoint)); // This should only be reachable in recovery, where DSU scratch is not // automatically mapped. static bool MapDsuScratchDevice(std::string* device) { std::string dsu_slot; if (!android::gsi::IsGsiInstalled() || !android::gsi::GetActiveDsu(&dsu_slot) || dsu_slot.empty()) { // Nothing to do if no DSU installation present. return false; } auto images = IImageManager::Open("dsu/" + dsu_slot, 10s); if (!images || !images->BackingImageExists(android::gsi::kDsuScratch)) { // Nothing to do if DSU scratch device doesn't exist. return false; } images->UnmapImageDevice(android::gsi::kDsuScratch); if (!images->MapImageDevice(android::gsi::kDsuScratch, 10s, device)) { return false; } return true; } // Returns false if teardown not permitted, errno set to last error. Loading @@ -1377,21 +1457,27 @@ bool fs_mgr_overlayfs_teardown(const char* mount_point, bool* change) { // If scratch exists, but is not mounted, lets gain access to clean // specific override entries. auto mount_scratch = false; bool unmap = false; if ((mount_point != nullptr) && !fs_mgr_overlayfs_already_mounted(kScratchMountPoint, false)) { std::string scratch_device; if (EnsureScratchMapped(&scratch_device, &unmap)) { std::string scratch_device = GetBootScratchDevice(); if (!scratch_device.empty()) { mount_scratch = fs_mgr_overlayfs_mount_scratch(scratch_device, fs_mgr_overlayfs_scratch_mount_type()); } } bool should_destroy_scratch = false; for (const auto& overlay_mount_point : kOverlayMountPoints) { ret &= fs_mgr_overlayfs_teardown_one( overlay_mount_point, mount_point ? fs_mgr_mount_point(mount_point) : "", change); overlay_mount_point, mount_point ? fs_mgr_mount_point(mount_point) : "", change, overlay_mount_point == kScratchMountPoint ? &should_destroy_scratch : nullptr); } // Do not attempt to destroy DSU scratch if within a DSU system, // because DSU scratch partition is managed by gsid. if (should_destroy_scratch && !fs_mgr_is_dsu_running()) { ret &= fs_mgr_overlayfs_teardown_scratch(kScratchMountPoint, change); } if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kNotSupported) { // After obligatory teardown to make sure everything is clean, but if // we didn't want overlayfs in the the first place, we do not want to // we didn't want overlayfs in the first place, we do not want to // waste time on a reboot (or reboot request message). if (change) *change = false; } Loading @@ -1405,9 +1491,6 @@ bool fs_mgr_overlayfs_teardown(const char* mount_point, bool* change) { if (mount_scratch) { fs_mgr_overlayfs_umount_scratch(); } if (unmap) { UnmapScratchDevice(); } return ret; } Loading Loading @@ -1475,6 +1558,54 @@ void CleanupOldScratchFiles() { } } void TeardownAllOverlayForMountPoint(const std::string& mount_point) { if (!fs_mgr_in_recovery()) { LERROR << __FUNCTION__ << "(): must be called within recovery."; return; } // Empty string means teardown everything. const std::string teardown_dir = mount_point.empty() ? "" : fs_mgr_mount_point(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) { if (overlay_mount_point == kScratchMountPoint) { continue; } fs_mgr_overlayfs_teardown_one(overlay_mount_point, teardown_dir, ignore_change); } // Map scratch device, mount kScratchMountPoint and teardown kScratchMountPoint. bool mapped = false; std::string scratch_device; if (EnsureScratchMapped(&scratch_device, &mapped)) { fs_mgr_overlayfs_umount_scratch(); if (fs_mgr_overlayfs_mount_scratch(scratch_device, fs_mgr_overlayfs_scratch_mount_type())) { bool should_destroy_scratch = false; fs_mgr_overlayfs_teardown_one(kScratchMountPoint, teardown_dir, ignore_change, &should_destroy_scratch); if (should_destroy_scratch) { fs_mgr_overlayfs_teardown_scratch(kScratchMountPoint, nullptr); } fs_mgr_overlayfs_umount_scratch(); } if (mapped) { DestroyLogicalPartition(android::base::Basename(kScratchMountPoint)); } } // Teardown DSU overlay if present. if (MapDsuScratchDevice(&scratch_device)) { fs_mgr_overlayfs_umount_scratch(); if (fs_mgr_overlayfs_mount_scratch(scratch_device, fs_mgr_overlayfs_scratch_mount_type())) { fs_mgr_overlayfs_teardown_one(kScratchMountPoint, teardown_dir, ignore_change); fs_mgr_overlayfs_umount_scratch(); } DestroyLogicalPartition(android::gsi::kDsuScratch); } } } // namespace fs_mgr } // namespace android Loading fs_mgr/include/fs_mgr_overlayfs.h +7 −0 Original line number Diff line number Diff line Loading @@ -49,5 +49,12 @@ void MapScratchPartitionIfNeeded(Fstab* fstab, const std::function<bool(const std::set<std::string>&)>& init); void CleanupOldScratchFiles(); // Teardown overlays of all sources (cache dir, scratch device, DSU) for |mount_point|. // Teardown all overlays if |mount_point| is empty. // // Note: This should be called if and only if in recovery or fastbootd to teardown // overlays if any partition is flashed or updated. void TeardownAllOverlayForMountPoint(const std::string& mount_point = {}); } // namespace fs_mgr } // namespace android Loading
fastboot/device/flashing.cpp +3 −3 Original line number Diff line number Diff line Loading @@ -67,7 +67,7 @@ void WipeOverlayfsForPartition(FastbootDevice* device, const std::string& partit if ((partition + device->GetCurrentSlot()) == partition_name) { mount_metadata.emplace(); fs_mgr_overlayfs_teardown(entry.mount_point.c_str()); android::fs_mgr::TeardownAllOverlayForMountPoint(entry.mount_point); } } } Loading Loading @@ -194,7 +194,7 @@ bool UpdateSuper(FastbootDevice* device, const std::string& super_name, bool wip if (!FlashPartitionTable(super_name, *new_metadata.get())) { return device->WriteFail("Unable to flash new partition table"); } fs_mgr_overlayfs_teardown(); android::fs_mgr::TeardownAllOverlayForMountPoint(); sync(); return device->WriteOkay("Successfully flashed partition table"); } Loading Loading @@ -234,7 +234,7 @@ bool UpdateSuper(FastbootDevice* device, const std::string& super_name, bool wip if (!UpdateAllPartitionMetadata(device, super_name, *new_metadata.get())) { return device->WriteFail("Unable to write new partition table"); } fs_mgr_overlayfs_teardown(); android::fs_mgr::TeardownAllOverlayForMountPoint(); sync(); return device->WriteOkay("Successfully updated partition table"); }
fs_mgr/fs_mgr_overlayfs.cpp +154 −23 Original line number Diff line number Diff line Loading @@ -73,6 +73,25 @@ bool fs_mgr_access(const std::string& path) { return ret; } 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; } // determine if a filesystem is available bool fs_mgr_overlayfs_filesystem_available(const std::string& filesystem) { std::string filesystems; Loading Loading @@ -113,8 +132,11 @@ bool fs_mgr_overlayfs_is_setup() { namespace android { namespace fs_mgr { void MapScratchPartitionIfNeeded(Fstab*, const std::function<bool(const std::set<std::string>&)>&) {} void MapScratchPartitionIfNeeded(Fstab*, const std::function<bool(const std::set<std::string>&)>&) { } void TeardownAllOverlayForMountPoint(const std::string&) {} } // namespace fs_mgr } // namespace android Loading Loading @@ -171,6 +193,10 @@ constexpr char kScratchImageMetadata[] = "/metadata/gsi/remount/lp_metadata"; // Note: this is meant only for recovery/first-stage init. bool ScratchIsOnData() { // The scratch partition of DSU is managed by gsid. if (fs_mgr_is_dsu_running()) { return false; } return fs_mgr_access(kScratchImageMetadata); } Loading Loading @@ -464,6 +490,12 @@ bool fs_mgr_overlayfs_teardown_scratch(const std::string& overlay, bool* change) // umount and delete kScratchMountPoint storage if we have logical partitions if (overlay != kScratchMountPoint) return true; // Validation check. if (fs_mgr_is_dsu_running()) { LERROR << "Destroying DSU scratch is not allowed."; return false; } auto save_errno = errno; if (fs_mgr_overlayfs_already_mounted(kScratchMountPoint, false)) { fs_mgr_overlayfs_umount_scratch(); Loading Loading @@ -512,10 +544,13 @@ bool fs_mgr_overlayfs_teardown_scratch(const std::string& overlay, bool* change) } bool fs_mgr_overlayfs_teardown_one(const std::string& overlay, const std::string& mount_point, bool* change) { bool* change, bool* should_destroy_scratch = nullptr) { const auto top = overlay + kOverlayTopDir; if (!fs_mgr_access(top)) return fs_mgr_overlayfs_teardown_scratch(overlay, change); if (!fs_mgr_access(top)) { if (should_destroy_scratch) *should_destroy_scratch = true; return true; } auto cleanup_all = mount_point.empty(); const auto partition_name = android::base::Basename(mount_point); Loading Loading @@ -571,7 +606,7 @@ bool fs_mgr_overlayfs_teardown_one(const std::string& overlay, const std::string PERROR << "rmdir " << top; } } if (cleanup_all) ret &= fs_mgr_overlayfs_teardown_scratch(overlay, change); if (should_destroy_scratch) *should_destroy_scratch = cleanup_all; return ret; } Loading Loading @@ -881,12 +916,29 @@ static std::string GetPhysicalScratchDevice() { return ""; } // Note: The scratch partition of DSU is managed by gsid, and should be initialized during // first-stage-mount. Just check if the DM device for DSU scratch partition is created or not. static std::string GetDsuScratchDevice() { auto& dm = DeviceMapper::Instance(); std::string device; if (dm.GetState(android::gsi::kDsuScratch) != DmDeviceState::INVALID && dm.GetDmDevicePathByName(android::gsi::kDsuScratch, &device)) { return device; } return ""; } // This returns the scratch device that was detected during early boot (first- // stage init). If the device was created later, for example during setup for // the adb remount command, it can return an empty string since it does not // query ImageManager. (Note that ImageManager in first-stage init will always // use device-mapper, since /data is not available to use loop devices.) static std::string GetBootScratchDevice() { // Note: fs_mgr_is_dsu_running() always returns false in recovery or fastbootd. if (fs_mgr_is_dsu_running()) { return GetDsuScratchDevice(); } auto& dm = DeviceMapper::Instance(); // If there is a scratch partition allocated in /data or on super, we Loading Loading @@ -1108,6 +1160,14 @@ static bool CanUseSuperPartition(const Fstab& fstab, bool* is_virtual_ab) { bool fs_mgr_overlayfs_create_scratch(const Fstab& fstab, std::string* scratch_device, bool* partition_exists, bool* change) { // Use the DSU scratch device managed by gsid if within a DSU system. if (fs_mgr_is_dsu_running()) { *scratch_device = GetDsuScratchDevice(); *partition_exists = !scratch_device->empty(); *change = false; return *partition_exists; } // Try a physical partition first. *scratch_device = GetPhysicalScratchDevice(); if (!scratch_device->empty() && fs_mgr_rw_access(*scratch_device)) { Loading Loading @@ -1166,12 +1226,8 @@ bool fs_mgr_overlayfs_setup_scratch(const Fstab& fstab, bool* change) { bool fs_mgr_overlayfs_invalid() { if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kNotSupported) return true; // in recovery, fastbootd, or gsi mode, not allowed! if (fs_mgr_access("/system/bin/recovery")) return true; auto save_errno = errno; auto ret = android::gsi::IsGsiRunning(); errno = save_errno; return ret; // in recovery or fastbootd, not allowed! return fs_mgr_in_recovery(); } } // namespace Loading Loading @@ -1314,6 +1370,8 @@ bool fs_mgr_overlayfs_setup(const char* backing, const char* mount_point, bool* return ret; } // Note: This function never returns the DSU scratch device in recovery or fastbootd, // because the DSU scratch is created in the first-stage-mount, which is not run in recovery. static bool EnsureScratchMapped(std::string* device, bool* mapped) { *mapped = false; *device = GetBootScratchDevice(); Loading @@ -1321,6 +1379,11 @@ static bool EnsureScratchMapped(std::string* device, bool* mapped) { return true; } if (!fs_mgr_in_recovery()) { errno = EINVAL; return false; } auto partition_name = android::base::Basename(kScratchMountPoint); // Check for scratch on /data first, before looking for a modified super Loading Loading @@ -1362,10 +1425,27 @@ static bool EnsureScratchMapped(std::string* device, bool* mapped) { return true; } static void UnmapScratchDevice() { // This should only be reachable in recovery, where scratch is not // automatically mapped and therefore can be unmapped. DestroyLogicalPartition(android::base::Basename(kScratchMountPoint)); // This should only be reachable in recovery, where DSU scratch is not // automatically mapped. static bool MapDsuScratchDevice(std::string* device) { std::string dsu_slot; if (!android::gsi::IsGsiInstalled() || !android::gsi::GetActiveDsu(&dsu_slot) || dsu_slot.empty()) { // Nothing to do if no DSU installation present. return false; } auto images = IImageManager::Open("dsu/" + dsu_slot, 10s); if (!images || !images->BackingImageExists(android::gsi::kDsuScratch)) { // Nothing to do if DSU scratch device doesn't exist. return false; } images->UnmapImageDevice(android::gsi::kDsuScratch); if (!images->MapImageDevice(android::gsi::kDsuScratch, 10s, device)) { return false; } return true; } // Returns false if teardown not permitted, errno set to last error. Loading @@ -1377,21 +1457,27 @@ bool fs_mgr_overlayfs_teardown(const char* mount_point, bool* change) { // If scratch exists, but is not mounted, lets gain access to clean // specific override entries. auto mount_scratch = false; bool unmap = false; if ((mount_point != nullptr) && !fs_mgr_overlayfs_already_mounted(kScratchMountPoint, false)) { std::string scratch_device; if (EnsureScratchMapped(&scratch_device, &unmap)) { std::string scratch_device = GetBootScratchDevice(); if (!scratch_device.empty()) { mount_scratch = fs_mgr_overlayfs_mount_scratch(scratch_device, fs_mgr_overlayfs_scratch_mount_type()); } } bool should_destroy_scratch = false; for (const auto& overlay_mount_point : kOverlayMountPoints) { ret &= fs_mgr_overlayfs_teardown_one( overlay_mount_point, mount_point ? fs_mgr_mount_point(mount_point) : "", change); overlay_mount_point, mount_point ? fs_mgr_mount_point(mount_point) : "", change, overlay_mount_point == kScratchMountPoint ? &should_destroy_scratch : nullptr); } // Do not attempt to destroy DSU scratch if within a DSU system, // because DSU scratch partition is managed by gsid. if (should_destroy_scratch && !fs_mgr_is_dsu_running()) { ret &= fs_mgr_overlayfs_teardown_scratch(kScratchMountPoint, change); } if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kNotSupported) { // After obligatory teardown to make sure everything is clean, but if // we didn't want overlayfs in the the first place, we do not want to // we didn't want overlayfs in the first place, we do not want to // waste time on a reboot (or reboot request message). if (change) *change = false; } Loading @@ -1405,9 +1491,6 @@ bool fs_mgr_overlayfs_teardown(const char* mount_point, bool* change) { if (mount_scratch) { fs_mgr_overlayfs_umount_scratch(); } if (unmap) { UnmapScratchDevice(); } return ret; } Loading Loading @@ -1475,6 +1558,54 @@ void CleanupOldScratchFiles() { } } void TeardownAllOverlayForMountPoint(const std::string& mount_point) { if (!fs_mgr_in_recovery()) { LERROR << __FUNCTION__ << "(): must be called within recovery."; return; } // Empty string means teardown everything. const std::string teardown_dir = mount_point.empty() ? "" : fs_mgr_mount_point(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) { if (overlay_mount_point == kScratchMountPoint) { continue; } fs_mgr_overlayfs_teardown_one(overlay_mount_point, teardown_dir, ignore_change); } // Map scratch device, mount kScratchMountPoint and teardown kScratchMountPoint. bool mapped = false; std::string scratch_device; if (EnsureScratchMapped(&scratch_device, &mapped)) { fs_mgr_overlayfs_umount_scratch(); if (fs_mgr_overlayfs_mount_scratch(scratch_device, fs_mgr_overlayfs_scratch_mount_type())) { bool should_destroy_scratch = false; fs_mgr_overlayfs_teardown_one(kScratchMountPoint, teardown_dir, ignore_change, &should_destroy_scratch); if (should_destroy_scratch) { fs_mgr_overlayfs_teardown_scratch(kScratchMountPoint, nullptr); } fs_mgr_overlayfs_umount_scratch(); } if (mapped) { DestroyLogicalPartition(android::base::Basename(kScratchMountPoint)); } } // Teardown DSU overlay if present. if (MapDsuScratchDevice(&scratch_device)) { fs_mgr_overlayfs_umount_scratch(); if (fs_mgr_overlayfs_mount_scratch(scratch_device, fs_mgr_overlayfs_scratch_mount_type())) { fs_mgr_overlayfs_teardown_one(kScratchMountPoint, teardown_dir, ignore_change); fs_mgr_overlayfs_umount_scratch(); } DestroyLogicalPartition(android::gsi::kDsuScratch); } } } // namespace fs_mgr } // namespace android Loading
fs_mgr/include/fs_mgr_overlayfs.h +7 −0 Original line number Diff line number Diff line Loading @@ -49,5 +49,12 @@ void MapScratchPartitionIfNeeded(Fstab* fstab, const std::function<bool(const std::set<std::string>&)>& init); void CleanupOldScratchFiles(); // Teardown overlays of all sources (cache dir, scratch device, DSU) for |mount_point|. // Teardown all overlays if |mount_point| is empty. // // Note: This should be called if and only if in recovery or fastbootd to teardown // overlays if any partition is flashed or updated. void TeardownAllOverlayForMountPoint(const std::string& mount_point = {}); } // namespace fs_mgr } // namespace android