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

Commit a6ebcad2 authored by Yifan Hong's avatar Yifan Hong Committed by android-build-merger
Browse files

Merge "fs_mgr: retrofit VAB update after A/B calc COW space."

am: e78ca076

Change-Id: I26c9a744e3198045f2ff56484a911becd5fdace6
parents a49b7e9d e78ca076
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -1793,6 +1793,14 @@ bool SnapshotManager::CreateUpdateSnapshots(const DeltaArchiveManifest& manifest
    auto target_metadata =
            MetadataBuilder::NewForUpdate(opener, current_super, current_slot, target_slot);

    // Delete partitions with target suffix in |current_metadata|. Otherwise,
    // partition_cow_creator recognizes these left-over partitions as used space.
    for (const auto& group_name : current_metadata->ListGroups()) {
        if (android::base::EndsWith(group_name, target_suffix)) {
            current_metadata->RemoveGroupAndPartitions(group_name);
        }
    }

    SnapshotMetadataUpdater metadata_updater(target_metadata.get(), target_slot, manifest);
    if (!metadata_updater.Update()) {
        LOG(ERROR) << "Cannot calculate new metadata.";
+93 −6
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@ using android::fs_mgr::GetPartitionName;
using android::fs_mgr::Interval;
using android::fs_mgr::MetadataBuilder;
using chromeos_update_engine::DeltaArchiveManifest;
using chromeos_update_engine::DynamicPartitionGroup;
using chromeos_update_engine::PartitionUpdate;
using namespace ::testing;
using namespace android::storage_literals;
@@ -660,12 +661,12 @@ class SnapshotUpdateTest : public SnapshotTest {
        // Not using full name "system", "vendor", "product" because these names collide with the
        // mapped partitions on the running device.
        // Each test modifies manifest_ slightly to indicate changes to the partition layout.
        auto group = manifest_.mutable_dynamic_partition_metadata()->add_groups();
        group->set_name("group");
        group->set_size(kGroupSize);
        group->add_partition_names("sys");
        group->add_partition_names("vnd");
        group->add_partition_names("prd");
        group_ = manifest_.mutable_dynamic_partition_metadata()->add_groups();
        group_->set_name("group");
        group_->set_size(kGroupSize);
        group_->add_partition_names("sys");
        group_->add_partition_names("vnd");
        group_->add_partition_names("prd");
        sys_ = manifest_.add_partitions();
        sys_->set_partition_name("sys");
        SetSize(sys_, 3_MiB);
@@ -769,6 +770,7 @@ class SnapshotUpdateTest : public SnapshotTest {
    PartitionUpdate* sys_ = nullptr;
    PartitionUpdate* vnd_ = nullptr;
    PartitionUpdate* prd_ = nullptr;
    DynamicPartitionGroup* group_ = nullptr;
};

// Test full update flow executed by update_engine. Some partitions uses super empty space,
@@ -1060,6 +1062,91 @@ TEST_F(SnapshotUpdateTest, ReclaimCow) {
    }
}

TEST_F(SnapshotUpdateTest, RetrofitAfterRegularAb) {
    constexpr auto kRetrofitGroupSize = kGroupSize / 2;

    // Initialize device-mapper / disk
    ASSERT_TRUE(UnmapAll());
    FormatFakeSuper();

    // Setup source partition metadata to have both _a and _b partitions.
    src_ = MetadataBuilder::New(*opener_, "super", 0);
    ASSERT_NE(nullptr, src_);
    for (const auto& suffix : {"_a"s, "_b"s}) {
        ASSERT_TRUE(src_->AddGroup(group_->name() + suffix, kRetrofitGroupSize));
        for (const auto& name : {"sys"s, "vnd"s, "prd"s}) {
            auto partition = src_->AddPartition(name + suffix, group_->name() + suffix, 0);
            ASSERT_NE(nullptr, partition);
            ASSERT_TRUE(src_->ResizePartition(partition, 2_MiB));
        }
    }
    auto metadata = src_->Export();
    ASSERT_NE(nullptr, metadata);
    ASSERT_TRUE(UpdatePartitionTable(*opener_, "super", *metadata.get(), 0));

    // Flash source partitions
    std::string path;
    for (const auto& name : {"sys_a", "vnd_a", "prd_a"}) {
        ASSERT_TRUE(CreateLogicalPartition(
                CreateLogicalPartitionParams{
                        .block_device = fake_super,
                        .metadata_slot = 0,
                        .partition_name = name,
                        .timeout_ms = 1s,
                        .partition_opener = opener_.get(),
                },
                &path));
        ASSERT_TRUE(WriteRandomData(path));
        auto hash = GetHash(path);
        ASSERT_TRUE(hash.has_value());
        hashes_[name] = *hash;
    }

    // Setup manifest.
    group_->set_size(kRetrofitGroupSize);
    for (auto* partition : {sys_, vnd_, prd_}) {
        SetSize(partition, 2_MiB);
        auto* e = partition->add_operations()->add_dst_extents();
        e->set_start_block(0);
        e->set_num_blocks(2_MiB / manifest_.block_size());
    }

    ASSERT_TRUE(sm->BeginUpdate());
    ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));

    // Test that COW image should not be created for retrofit devices; super
    // should be big enough.
    ASSERT_FALSE(image_manager_->BackingImageExists("sys_b-cow-img"));
    ASSERT_FALSE(image_manager_->BackingImageExists("vnd_b-cow-img"));
    ASSERT_FALSE(image_manager_->BackingImageExists("prd_b-cow-img"));

    // Write some data to target partitions.
    for (const auto& name : {"sys_b", "vnd_b", "prd_b"}) {
        std::string path;
        ASSERT_TRUE(sm->MapUpdateSnapshot(
                CreateLogicalPartitionParams{
                        .block_device = fake_super,
                        .metadata_slot = 1,
                        .partition_name = name,
                        .timeout_ms = 10s,
                        .partition_opener = opener_.get(),
                },
                &path))
                << name;
        ASSERT_TRUE(WriteRandomData(path));
        auto hash = GetHash(path);
        ASSERT_TRUE(hash.has_value());
        hashes_[name] = *hash;
    }

    // Assert that source partitions aren't affected.
    for (const auto& name : {"sys_a", "vnd_a", "prd_a"}) {
        ASSERT_TRUE(IsPartitionUnchanged(name));
    }

    ASSERT_TRUE(sm->FinishedSnapshotWrites());
}

class MetadataMountedTest : public SnapshotUpdateTest {
  public:
    void SetUp() override {