Loading fastboot/device/flashing.cpp +7 −2 Original line number Diff line number Diff line Loading @@ -186,6 +186,11 @@ int Flash(FastbootDevice* device, const std::string& partition_name) { return result; } static void RemoveScratchPartition() { AutoMountMetadata mount_metadata; android::fs_mgr::TeardownAllOverlayForMountPoint(); } bool UpdateSuper(FastbootDevice* device, const std::string& super_name, bool wipe) { std::vector<char> data = std::move(device->download_data()); if (data.empty()) { Loading Loading @@ -218,7 +223,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"); } android::fs_mgr::TeardownAllOverlayForMountPoint(); RemoveScratchPartition(); sync(); return device->WriteOkay("Successfully flashed partition table"); } Loading Loading @@ -262,7 +267,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"); } android::fs_mgr::TeardownAllOverlayForMountPoint(); RemoveScratchPartition(); sync(); return device->WriteOkay("Successfully updated partition table"); } fs_mgr/fs_mgr_overlayfs.cpp +58 −27 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ #include <algorithm> #include <memory> #include <optional> #include <string> #include <vector> Loading Loading @@ -1396,18 +1397,35 @@ bool fs_mgr_overlayfs_setup(const char* backing, const char* mount_point, bool* return ret; } struct MapInfo { // If set, partition is owned by ImageManager. std::unique_ptr<IImageManager> images; // If set, and images is null, this is a DAP partition. std::string name; // If set, and images and name are empty, this is a non-dynamic partition. std::string device; MapInfo() = default; MapInfo(MapInfo&&) = default; ~MapInfo() { if (images) { images->UnmapImageDevice(name); } else if (!name.empty()) { DestroyLogicalPartition(name); } } }; // 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(); if (!device->empty()) { return true; static std::optional<MapInfo> EnsureScratchMapped() { MapInfo info; info.device = GetBootScratchDevice(); if (!info.device.empty()) { return {std::move(info)}; } if (!fs_mgr_in_recovery()) { errno = EINVAL; return false; return {}; } auto partition_name = android::base::Basename(kScratchMountPoint); Loading @@ -1417,11 +1435,15 @@ static bool EnsureScratchMapped(std::string* device, bool* mapped) { // would otherwise always be mapped. auto images = IImageManager::Open("remount", 10s); if (images && images->BackingImageExists(partition_name)) { if (!images->MapImageDevice(partition_name, 10s, device)) { return false; if (images->IsImageDisabled(partition_name)) { return {}; } *mapped = true; return true; if (!images->MapImageDevice(partition_name, 10s, &info.device)) { return {}; } info.name = partition_name; info.images = std::move(images); return {std::move(info)}; } // Avoid uart spam by first checking for a scratch partition. Loading @@ -1429,12 +1451,12 @@ static bool EnsureScratchMapped(std::string* device, bool* mapped) { auto super_device = fs_mgr_overlayfs_super_device(metadata_slot); auto metadata = ReadCurrentMetadata(super_device); if (!metadata) { return false; return {}; } auto partition = FindPartition(*metadata.get(), partition_name); if (!partition) { return false; return {}; } CreateLogicalPartitionParams params = { Loading @@ -1444,11 +1466,11 @@ static bool EnsureScratchMapped(std::string* device, bool* mapped) { .force_writable = true, .timeout_ms = 10s, }; if (!CreateLogicalPartition(params, device)) { return false; if (!CreateLogicalPartition(params, &info.device)) { return {}; } *mapped = true; return true; info.name = partition_name; return {std::move(info)}; } // This should only be reachable in recovery, where DSU scratch is not Loading Loading @@ -1602,26 +1624,35 @@ void TeardownAllOverlayForMountPoint(const std::string& mount_point) { fs_mgr_overlayfs_teardown_one(overlay_mount_point, teardown_dir, ignore_change); } if (mount_point.empty()) { // Throw away the entire partition. auto partition_name = android::base::Basename(kScratchMountPoint); auto images = IImageManager::Open("remount", 10s); if (images && images->BackingImageExists(partition_name)) { if (images->DisableImage(partition_name)) { LOG(INFO) << "Disabled scratch partition for: " << kScratchMountPoint; } else { LOG(ERROR) << "Unable to disable scratch partition for " << kScratchMountPoint; } } } if (auto info = EnsureScratchMapped(); info.has_value()) { // 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())) { if (fs_mgr_overlayfs_mount_scratch(info->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); fs_mgr_overlayfs_umount_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. std::string scratch_device; if (MapDsuScratchDevice(&scratch_device)) { fs_mgr_overlayfs_umount_scratch(); if (fs_mgr_overlayfs_mount_scratch(scratch_device, fs_mgr_overlayfs_scratch_mount_type())) { Loading fs_mgr/libfiemap/binder.cpp +12 −0 Original line number Diff line number Diff line Loading @@ -66,6 +66,7 @@ class ImageManagerBinder final : public IImageManager { bool RemoveDisabledImages() override; bool GetMappedImageDevice(const std::string& name, std::string* device) override; bool MapAllImages(const std::function<bool(std::set<std::string>)>& init) override; bool IsImageDisabled(const std::string& name) override; std::vector<std::string> GetAllBackingImages() override; Loading Loading @@ -219,6 +220,17 @@ bool ImageManagerBinder::GetMappedImageDevice(const std::string& name, std::stri return !device->empty(); } bool ImageManagerBinder::IsImageDisabled(const std::string& name) { bool retval; auto status = manager_->isImageDisabled(name, &retval); if (!status.isOk()) { LOG(ERROR) << __PRETTY_FUNCTION__ << " binder returned: " << status.exceptionMessage().string(); return false; } return retval; } bool ImageManagerBinder::MapAllImages(const std::function<bool(std::set<std::string>)>&) { LOG(ERROR) << __PRETTY_FUNCTION__ << " not available over binder"; return false; Loading fs_mgr/libfiemap/image_manager.cpp +18 −0 Original line number Diff line number Diff line Loading @@ -854,6 +854,24 @@ bool ImageManager::ValidateImageMaps() { return true; } bool ImageManager::IsImageDisabled(const std::string& name) { if (!MetadataExists(metadata_dir_)) { return true; } auto metadata = OpenMetadata(metadata_dir_); if (!metadata) { return false; } auto partition = FindPartition(*metadata.get(), name); if (!partition) { return false; } return !!(partition->attributes & LP_PARTITION_ATTR_DISABLED); } std::unique_ptr<MappedDevice> MappedDevice::Open(IImageManager* manager, const std::chrono::milliseconds& timeout_ms, const std::string& name) { Loading fs_mgr/libfiemap/image_test.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -119,6 +119,7 @@ TEST_F(NativeTest, DisableImage) { ASSERT_TRUE(manager_->CreateBackingImage(base_name_, kTestImageSize, false, nullptr)); ASSERT_TRUE(manager_->BackingImageExists(base_name_)); ASSERT_TRUE(manager_->DisableImage(base_name_)); ASSERT_TRUE(manager_->IsImageDisabled(base_name_)); ASSERT_TRUE(manager_->RemoveDisabledImages()); ASSERT_TRUE(!manager_->BackingImageExists(base_name_)); } Loading Loading
fastboot/device/flashing.cpp +7 −2 Original line number Diff line number Diff line Loading @@ -186,6 +186,11 @@ int Flash(FastbootDevice* device, const std::string& partition_name) { return result; } static void RemoveScratchPartition() { AutoMountMetadata mount_metadata; android::fs_mgr::TeardownAllOverlayForMountPoint(); } bool UpdateSuper(FastbootDevice* device, const std::string& super_name, bool wipe) { std::vector<char> data = std::move(device->download_data()); if (data.empty()) { Loading Loading @@ -218,7 +223,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"); } android::fs_mgr::TeardownAllOverlayForMountPoint(); RemoveScratchPartition(); sync(); return device->WriteOkay("Successfully flashed partition table"); } Loading Loading @@ -262,7 +267,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"); } android::fs_mgr::TeardownAllOverlayForMountPoint(); RemoveScratchPartition(); sync(); return device->WriteOkay("Successfully updated partition table"); }
fs_mgr/fs_mgr_overlayfs.cpp +58 −27 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ #include <algorithm> #include <memory> #include <optional> #include <string> #include <vector> Loading Loading @@ -1396,18 +1397,35 @@ bool fs_mgr_overlayfs_setup(const char* backing, const char* mount_point, bool* return ret; } struct MapInfo { // If set, partition is owned by ImageManager. std::unique_ptr<IImageManager> images; // If set, and images is null, this is a DAP partition. std::string name; // If set, and images and name are empty, this is a non-dynamic partition. std::string device; MapInfo() = default; MapInfo(MapInfo&&) = default; ~MapInfo() { if (images) { images->UnmapImageDevice(name); } else if (!name.empty()) { DestroyLogicalPartition(name); } } }; // 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(); if (!device->empty()) { return true; static std::optional<MapInfo> EnsureScratchMapped() { MapInfo info; info.device = GetBootScratchDevice(); if (!info.device.empty()) { return {std::move(info)}; } if (!fs_mgr_in_recovery()) { errno = EINVAL; return false; return {}; } auto partition_name = android::base::Basename(kScratchMountPoint); Loading @@ -1417,11 +1435,15 @@ static bool EnsureScratchMapped(std::string* device, bool* mapped) { // would otherwise always be mapped. auto images = IImageManager::Open("remount", 10s); if (images && images->BackingImageExists(partition_name)) { if (!images->MapImageDevice(partition_name, 10s, device)) { return false; if (images->IsImageDisabled(partition_name)) { return {}; } *mapped = true; return true; if (!images->MapImageDevice(partition_name, 10s, &info.device)) { return {}; } info.name = partition_name; info.images = std::move(images); return {std::move(info)}; } // Avoid uart spam by first checking for a scratch partition. Loading @@ -1429,12 +1451,12 @@ static bool EnsureScratchMapped(std::string* device, bool* mapped) { auto super_device = fs_mgr_overlayfs_super_device(metadata_slot); auto metadata = ReadCurrentMetadata(super_device); if (!metadata) { return false; return {}; } auto partition = FindPartition(*metadata.get(), partition_name); if (!partition) { return false; return {}; } CreateLogicalPartitionParams params = { Loading @@ -1444,11 +1466,11 @@ static bool EnsureScratchMapped(std::string* device, bool* mapped) { .force_writable = true, .timeout_ms = 10s, }; if (!CreateLogicalPartition(params, device)) { return false; if (!CreateLogicalPartition(params, &info.device)) { return {}; } *mapped = true; return true; info.name = partition_name; return {std::move(info)}; } // This should only be reachable in recovery, where DSU scratch is not Loading Loading @@ -1602,26 +1624,35 @@ void TeardownAllOverlayForMountPoint(const std::string& mount_point) { fs_mgr_overlayfs_teardown_one(overlay_mount_point, teardown_dir, ignore_change); } if (mount_point.empty()) { // Throw away the entire partition. auto partition_name = android::base::Basename(kScratchMountPoint); auto images = IImageManager::Open("remount", 10s); if (images && images->BackingImageExists(partition_name)) { if (images->DisableImage(partition_name)) { LOG(INFO) << "Disabled scratch partition for: " << kScratchMountPoint; } else { LOG(ERROR) << "Unable to disable scratch partition for " << kScratchMountPoint; } } } if (auto info = EnsureScratchMapped(); info.has_value()) { // 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())) { if (fs_mgr_overlayfs_mount_scratch(info->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); fs_mgr_overlayfs_umount_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. std::string scratch_device; if (MapDsuScratchDevice(&scratch_device)) { fs_mgr_overlayfs_umount_scratch(); if (fs_mgr_overlayfs_mount_scratch(scratch_device, fs_mgr_overlayfs_scratch_mount_type())) { Loading
fs_mgr/libfiemap/binder.cpp +12 −0 Original line number Diff line number Diff line Loading @@ -66,6 +66,7 @@ class ImageManagerBinder final : public IImageManager { bool RemoveDisabledImages() override; bool GetMappedImageDevice(const std::string& name, std::string* device) override; bool MapAllImages(const std::function<bool(std::set<std::string>)>& init) override; bool IsImageDisabled(const std::string& name) override; std::vector<std::string> GetAllBackingImages() override; Loading Loading @@ -219,6 +220,17 @@ bool ImageManagerBinder::GetMappedImageDevice(const std::string& name, std::stri return !device->empty(); } bool ImageManagerBinder::IsImageDisabled(const std::string& name) { bool retval; auto status = manager_->isImageDisabled(name, &retval); if (!status.isOk()) { LOG(ERROR) << __PRETTY_FUNCTION__ << " binder returned: " << status.exceptionMessage().string(); return false; } return retval; } bool ImageManagerBinder::MapAllImages(const std::function<bool(std::set<std::string>)>&) { LOG(ERROR) << __PRETTY_FUNCTION__ << " not available over binder"; return false; Loading
fs_mgr/libfiemap/image_manager.cpp +18 −0 Original line number Diff line number Diff line Loading @@ -854,6 +854,24 @@ bool ImageManager::ValidateImageMaps() { return true; } bool ImageManager::IsImageDisabled(const std::string& name) { if (!MetadataExists(metadata_dir_)) { return true; } auto metadata = OpenMetadata(metadata_dir_); if (!metadata) { return false; } auto partition = FindPartition(*metadata.get(), name); if (!partition) { return false; } return !!(partition->attributes & LP_PARTITION_ATTR_DISABLED); } std::unique_ptr<MappedDevice> MappedDevice::Open(IImageManager* manager, const std::chrono::milliseconds& timeout_ms, const std::string& name) { Loading
fs_mgr/libfiemap/image_test.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -119,6 +119,7 @@ TEST_F(NativeTest, DisableImage) { ASSERT_TRUE(manager_->CreateBackingImage(base_name_, kTestImageSize, false, nullptr)); ASSERT_TRUE(manager_->BackingImageExists(base_name_)); ASSERT_TRUE(manager_->DisableImage(base_name_)); ASSERT_TRUE(manager_->IsImageDisabled(base_name_)); ASSERT_TRUE(manager_->RemoveDisabledImages()); ASSERT_TRUE(!manager_->BackingImageExists(base_name_)); } Loading