From c0966c9a1b21a8c34662ebffc7ded763c81f22b7 Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Mon, 26 Nov 2018 09:57:17 -0800 Subject: [PATCH 1/4] fs_mgr: overlay: umount scratch more aggressively For specific teardown operations, if we mount scratch with the intention of it being temporary to strike out content for a specific partition, umount it. Otherwise it could interfer with fastboot. Test: adb-remount-test.sh Bug: 120034852 Change-Id: Ieff3f6ea0bcda5eb540e9acf6cab8a56d1453b3e --- fs_mgr/fs_mgr_overlayfs.cpp | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/fs_mgr/fs_mgr_overlayfs.cpp b/fs_mgr/fs_mgr_overlayfs.cpp index bef46e1e1..edada175a 100644 --- a/fs_mgr/fs_mgr_overlayfs.cpp +++ b/fs_mgr/fs_mgr_overlayfs.cpp @@ -395,6 +395,18 @@ bool fs_mgr_overlayfs_has_logical(const fstab* fstab) { return false; } +void fs_mgr_overlayfs_umount_scratch() { + // Lazy umount will allow us to move on and possibly later + // establish a new fresh mount without requiring a reboot should + // the developer wish to restart. Old references should melt + // away or have no data. Main goal is to shut the door on the + // current overrides with an expectation of a subsequent reboot, + // thus any errors here are ignored. + umount2(kScratchMountPoint.c_str(), MNT_DETACH); + LINFO << "umount(" << kScratchMountPoint << ")"; + rmdir(kScratchMountPoint.c_str()); +} + // reduce 'DM_DEV_STATUS failed for scratch: No such device or address' noise std::string scratch_device_cache; @@ -408,13 +420,7 @@ bool fs_mgr_overlayfs_teardown_scratch(const std::string& overlay, bool* change) auto save_errno = errno; if (fs_mgr_overlayfs_already_mounted(kScratchMountPoint, false)) { - // Lazy umount will allow us to move on and possibly later - // establish a new fresh mount without requiring a reboot should - // the developer wish to restart. Old references should melt - // away or have no data. Main goal is to shut the door on the - // current overrides with an expectation of a subsequent reboot, - // thus any errors here are ignored. - umount2(kScratchMountPoint.c_str(), MNT_DETACH); + fs_mgr_overlayfs_umount_scratch(); } auto builder = MetadataBuilder::New(super_device, slot_number); if (!builder) { @@ -773,8 +779,7 @@ bool fs_mgr_overlayfs_mount_all(fstab* fstab) { fs_mgr_overlayfs_mount_scratch(scratch_device, fs_mgr_overlayfs_scratch_mount_type()) && !fs_mgr_access(kScratchMountPoint + kOverlayTopDir)) { - umount2(kScratchMountPoint.c_str(), MNT_DETACH); - rmdir(kScratchMountPoint.c_str()); + fs_mgr_overlayfs_umount_scratch(); } } if (fs_mgr_overlayfs_mount(mount_point)) ret = true; @@ -867,6 +872,7 @@ bool fs_mgr_overlayfs_teardown(const char* mount_point, bool* change) { auto ret = true; // If scratch exists, but is not mounted, lets gain access to clean // specific override entries. + auto mount_scratch = false; if ((mount_point != nullptr) && !fs_mgr_overlayfs_already_mounted(kScratchMountPoint, false)) { auto scratch_device = fs_mgr_overlayfs_scratch_device(); if (scratch_device.empty()) { @@ -876,7 +882,8 @@ bool fs_mgr_overlayfs_teardown(const char* mount_point, bool* change) { CreateLogicalPartition(super_device, slot_number, partition_name, true, 0s, &scratch_device); } - fs_mgr_overlayfs_mount_scratch(scratch_device, fs_mgr_overlayfs_scratch_mount_type()); + mount_scratch = fs_mgr_overlayfs_mount_scratch(scratch_device, + fs_mgr_overlayfs_scratch_mount_type()); } for (const auto& overlay_mount_point : kOverlayMountPoints) { ret &= fs_mgr_overlayfs_teardown_one(overlay_mount_point, mount_point ?: "", change); @@ -894,6 +901,8 @@ bool fs_mgr_overlayfs_teardown(const char* mount_point, bool* change) { PERROR << "teardown"; ret = false; } + if (mount_scratch) fs_mgr_overlayfs_umount_scratch(); + return ret; } From 9040aa56657b69b7c26dabe1fb7996633d0d5f8d Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Mon, 26 Nov 2018 09:57:17 -0800 Subject: [PATCH 2/4] fs_mgr: overlay: disable overrides in recovery or fastbootd. Disable overrides if we are booting up in recovery or fastbootd. Check for existence of /system/bin/recovery. Test: adb-remount-test.sh Bug: 120034852 Change-Id: I946eb605300226d31356ecac209d6367f4e13526 --- fs_mgr/fs_mgr_overlayfs.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/fs_mgr/fs_mgr_overlayfs.cpp b/fs_mgr/fs_mgr_overlayfs.cpp index edada175a..20652ad86 100644 --- a/fs_mgr/fs_mgr_overlayfs.cpp +++ b/fs_mgr/fs_mgr_overlayfs.cpp @@ -759,14 +759,20 @@ bool fs_mgr_overlayfs_scratch_can_be_mounted(const std::string& scratch_device) return builder->FindPartition(android::base::Basename(kScratchMountPoint)) != nullptr; } +bool fs_mgr_overlayfs_invalid(const fstab* fstab) { + if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kNotSupported) return true; + + // in recovery or fastbootd mode, not allowed! + if (fs_mgr_access("/system/bin/recovery")) return true; + + return !fstab; +} + } // namespace bool fs_mgr_overlayfs_mount_all(fstab* fstab) { auto ret = false; - - if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kNotSupported) return ret; - - if (!fstab) return ret; + if (fs_mgr_overlayfs_invalid(fstab)) return ret; auto scratch_can_be_mounted = true; for (const auto& mount_point : fs_mgr_candidate_list(fstab)) { @@ -795,9 +801,9 @@ bool fs_mgr_overlayfs_mount_all(const std::vector& fsrecs) { } std::vector fs_mgr_overlayfs_required_devices(fstab* fstab) { - if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kNotSupported) return {}; + if (fs_mgr_overlayfs_invalid(fstab)) return {}; - if (fs_mgr_get_entry_for_mount_point(const_cast(fstab), kScratchMountPoint)) { + if (fs_mgr_get_entry_for_mount_point(fstab, kScratchMountPoint)) { return {}; } From 307a41fe9f4eb140d839ed91a771838ab0b6b4de Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Mon, 26 Nov 2018 09:57:17 -0800 Subject: [PATCH 3/4] fastboot: call fs_mgr_overlayfs_teardown() in UpdateSuper When the update-super command is issued, we want overlayfs overrides to disappear without a doubt, which includes non-A/B utilizing /cache/overlay/ tree. Call fs_mgr_overlayfs_teardown() on successful return. Test: adb-remount-test.sh Bug: 120034852 Change-Id: Ia5cdb797f7e8350b5591a51fc8ae5f323901aee4 --- fastboot/device/flashing.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fastboot/device/flashing.cpp b/fastboot/device/flashing.cpp index 7b99884a8..fbba63122 100644 --- a/fastboot/device/flashing.cpp +++ b/fastboot/device/flashing.cpp @@ -153,6 +153,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(); return device->WriteOkay("Successfully flashed partition table"); } @@ -186,5 +187,6 @@ bool UpdateSuper(FastbootDevice* device, const std::string& super_name, bool wip if (!UpdateAllPartitionMetadata(super_name, *new_metadata.get())) { return device->WriteFail("Unable to write new partition table"); } + fs_mgr_overlayfs_teardown(); return device->WriteOkay("Successfully updated partition table"); } From acf56c297f57f68331cd42772eca327c1b3bddcd Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Mon, 26 Nov 2018 09:57:17 -0800 Subject: [PATCH 4/4] init: overlay: allow fs_mgr_overlayfs_required_devices to report partitions init add support for picking up partitions if specified by fs_mgr_overlayfs_required_devices() as /dev/block/by-name/ Test: adb-remount-test.sh Bug: 119885423 Change-Id: I6a4c3d9b5c2b406178f0acf0a86c52ab17209537 --- init/first_stage_mount.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/init/first_stage_mount.cpp b/init/first_stage_mount.cpp index 8644dae6b..d35329ed7 100644 --- a/init/first_stage_mount.cpp +++ b/init/first_stage_mount.cpp @@ -413,7 +413,14 @@ bool FirstStageMount::MountPartitions() { // heads up for instantiating required device(s) for overlayfs logic const auto devices = fs_mgr_overlayfs_required_devices(device_tree_fstab_.get()); for (auto const& device : devices) { - InitMappedDevice(device); + if (android::base::StartsWith(device, "/dev/block/by-name/")) { + required_devices_partition_names_.emplace(basename(device.c_str())); + auto uevent_callback = [this](const Uevent& uevent) { return UeventCallback(uevent); }; + uevent_listener_.RegenerateUevents(uevent_callback); + uevent_listener_.Poll(uevent_callback, 10s); + } else { + InitMappedDevice(device); + } } fs_mgr_overlayfs_mount_all(device_tree_fstab_.get());