Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8fe31b12 authored by David Anderson's avatar David Anderson Committed by Automerger Merge Worker
Browse files

Merge "fastbootd: Remove all scratch partitions on update-super." am:...

Merge "fastbootd: Remove all scratch partitions on update-super." am: 035921dd am: bb0888e9 am: 7c83e767

Original change: https://android-review.googlesource.com/c/platform/system/core/+/1978058

Change-Id: Ic109b02ddb9aab5d207d75df8edd38b163a16608
parents 298b4ace 7c83e767
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -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()) {
@@ -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");
    }
@@ -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");
}
+58 −27
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@

#include <algorithm>
#include <memory>
#include <optional>
#include <string>
#include <vector>

@@ -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);
@@ -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.
@@ -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 = {
@@ -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
@@ -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())) {
+12 −0
Original line number Diff line number Diff line
@@ -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;

@@ -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;
+18 −0
Original line number Diff line number Diff line
@@ -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) {
+1 −0
Original line number Diff line number Diff line
@@ -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