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
This commit is contained in:
David Anderson 2021-02-24 22:05:35 -08:00
parent e886702132
commit cbc204b39b
5 changed files with 36 additions and 6 deletions

View file

@ -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

View file

@ -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;

View file

@ -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;

View file

@ -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));

View file

@ -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 {