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

Commit cbc204b3 authored by David Anderson's avatar David Anderson
Browse files

libsnapshot: Use the compression algorithm specified in the DeltaArchiveManifest.

update_engine and libsnapshot must agree on CowOptions parameters,
otherwise the COW size estimation may be incorrect.

Bug: N/A
Test: vts_libsnapshot_test
      apply OTA, snapshotctl dump
Change-Id: I219ae458dfa19e4b3c96360d3b847edb2a01ebc8
parent e8867021
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -46,7 +46,7 @@ enum MergePhase {
    SECOND_PHASE = 2;
}

// Next: 11
// Next: 12
message SnapshotStatus {
    // Name of the snapshot. This is usually the name of the snapshotted
    // logical partition; for example, "system_b".
@@ -102,6 +102,9 @@ message SnapshotStatus {

    // The old partition size (if none existed, this will be zero).
    uint64 old_partition_size = 10;

    // Compression algorithm (none, gz, or brotli).
    string compression_algorithm = 11;
}

// Next: 8
+1 −0
Original line number Diff line number Diff line
@@ -58,6 +58,7 @@ struct PartitionCowCreator {
    std::vector<ChromeOSExtent> extra_extents = {};
    // True if compression is enabled.
    bool compression_enabled = false;
    std::string compression_algorithm;

    struct Return {
        SnapshotStatus snapshot_status;
+19 −5
Original line number Diff line number Diff line
@@ -359,6 +359,7 @@ bool SnapshotManager::CreateSnapshot(LockedFile* lock, PartitionCowCreator* cow_
    status->set_sectors_allocated(0);
    status->set_metadata_sectors(0);
    status->set_compression_enabled(cow_creator->compression_enabled);
    status->set_compression_algorithm(cow_creator->compression_algorithm);

    if (!WriteSnapshotStatus(lock, *status)) {
        PLOG(ERROR) << "Could not write snapshot status: " << status->name();
@@ -2660,9 +2661,20 @@ Return SnapshotManager::CreateUpdateSnapshots(const DeltaArchiveManifest& manife
    // these devices.
    AutoDeviceList created_devices;

    bool use_compression = IsCompressionEnabled() &&
                           manifest.dynamic_partition_metadata().vabc_enabled() &&
                           !device_->IsRecovery();
    const auto& dap_metadata = manifest.dynamic_partition_metadata();
    bool use_compression =
            IsCompressionEnabled() && dap_metadata.vabc_enabled() && !device_->IsRecovery();

    std::string compression_algorithm;
    if (use_compression) {
        compression_algorithm = dap_metadata.vabc_compression_param();
        if (compression_algorithm.empty()) {
            // Older OTAs don't set an explicit compression type, so default to gz.
            compression_algorithm = "gz";
        }
    } else {
        compression_algorithm = "none";
    }

    PartitionCowCreator cow_creator{
            .target_metadata = target_metadata.get(),
@@ -2673,6 +2685,7 @@ Return SnapshotManager::CreateUpdateSnapshots(const DeltaArchiveManifest& manife
            .update = nullptr,
            .extra_extents = {},
            .compression_enabled = use_compression,
            .compression_algorithm = compression_algorithm,
    };

    auto ret = CreateUpdateSnapshotsInternal(lock.get(), manifest, &cow_creator, &created_devices,
@@ -2917,7 +2930,7 @@ Return SnapshotManager::InitializeUpdateSnapshots(
                return Return::Error();
            }

            CowWriter writer(CowOptions{});
            CowWriter writer(CowOptions{.compression = it->second.compression_algorithm()});
            if (!writer.Initialize(fd) || !writer.Finalize()) {
                LOG(ERROR) << "Could not initialize COW device for " << target_partition->name();
                return Return::Error();
@@ -3024,7 +3037,7 @@ std::unique_ptr<ISnapshotWriter> SnapshotManager::OpenCompressedSnapshotWriter(
    CHECK(lock);

    CowOptions cow_options;
    cow_options.compression = "gz";
    cow_options.compression = status.compression_algorithm();
    cow_options.max_blocks = {status.device_size() / cow_options.block_size};

    // Currently we don't support partial snapshots, since partition_cow_creator
@@ -3163,6 +3176,7 @@ bool SnapshotManager::Dump(std::ostream& os) {
        ss << "    cow file size (bytes): " << status.cow_file_size() << std::endl;
        ss << "    allocated sectors: " << status.sectors_allocated() << std::endl;
        ss << "    metadata sectors: " << status.metadata_sectors() << std::endl;
        ss << "    compression: " << status.compression_algorithm() << std::endl;
    }
    os << ss.rdbuf();
    return ok;
+11 −0
Original line number Diff line number Diff line
@@ -423,6 +423,11 @@ TEST_F(SnapshotTest, CreateSnapshot) {

    PartitionCowCreator cow_creator;
    cow_creator.compression_enabled = IsCompressionEnabled();
    if (cow_creator.compression_enabled) {
        cow_creator.compression_algorithm = "gz";
    } else {
        cow_creator.compression_algorithm = "none";
    }

    static const uint64_t kDeviceSize = 1024 * 1024;
    SnapshotStatus status;
@@ -446,6 +451,7 @@ TEST_F(SnapshotTest, CreateSnapshot) {
        ASSERT_EQ(status.device_size(), kDeviceSize);
        ASSERT_EQ(status.snapshot_size(), kDeviceSize);
        ASSERT_EQ(status.compression_enabled(), cow_creator.compression_enabled);
        ASSERT_EQ(status.compression_algorithm(), cow_creator.compression_algorithm);
    }

    ASSERT_TRUE(sm->UnmapSnapshot(lock_.get(), "test-snapshot"));
@@ -576,6 +582,11 @@ TEST_F(SnapshotTest, FirstStageMountAndMerge) {
    SnapshotStatus status;
    ASSERT_TRUE(init->ReadSnapshotStatus(lock_.get(), "test_partition_b", &status));
    ASSERT_EQ(status.state(), SnapshotState::CREATED);
    if (IsCompressionEnabled()) {
        ASSERT_EQ(status.compression_algorithm(), "gz");
    } else {
        ASSERT_EQ(status.compression_algorithm(), "none");
    }

    DeviceMapper::TargetInfo target;
    ASSERT_TRUE(init->IsSnapshotDevice("test_partition_b", &target));
+1 −0
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@ message DynamicPartitionGroup {
message DynamicPartitionMetadata {
    repeated DynamicPartitionGroup groups = 1;
    optional bool vabc_enabled = 3;
    optional string vabc_compression_param = 4;
}

message DeltaArchiveManifest {