diff --git a/fs_mgr/libsnapshot/android/snapshot/snapshot.proto b/fs_mgr/libsnapshot/android/snapshot/snapshot.proto index 42bff14bc..b4e92a275 100644 --- a/fs_mgr/libsnapshot/android/snapshot/snapshot.proto +++ b/fs_mgr/libsnapshot/android/snapshot/snapshot.proto @@ -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 diff --git a/fs_mgr/libsnapshot/partition_cow_creator.h b/fs_mgr/libsnapshot/partition_cow_creator.h index 84372de9c..34b39ca72 100644 --- a/fs_mgr/libsnapshot/partition_cow_creator.h +++ b/fs_mgr/libsnapshot/partition_cow_creator.h @@ -58,6 +58,7 @@ struct PartitionCowCreator { std::vector extra_extents = {}; // True if compression is enabled. bool compression_enabled = false; + std::string compression_algorithm; struct Return { SnapshotStatus snapshot_status; diff --git a/fs_mgr/libsnapshot/snapshot.cpp b/fs_mgr/libsnapshot/snapshot.cpp index cc2599d1f..ca4c2658f 100644 --- a/fs_mgr/libsnapshot/snapshot.cpp +++ b/fs_mgr/libsnapshot/snapshot.cpp @@ -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 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; diff --git a/fs_mgr/libsnapshot/snapshot_test.cpp b/fs_mgr/libsnapshot/snapshot_test.cpp index bde4ccadd..25500b5f3 100644 --- a/fs_mgr/libsnapshot/snapshot_test.cpp +++ b/fs_mgr/libsnapshot/snapshot_test.cpp @@ -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)); diff --git a/fs_mgr/libsnapshot/update_engine/update_metadata.proto b/fs_mgr/libsnapshot/update_engine/update_metadata.proto index 4a97f81a3..f31ee31c1 100644 --- a/fs_mgr/libsnapshot/update_engine/update_metadata.proto +++ b/fs_mgr/libsnapshot/update_engine/update_metadata.proto @@ -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 {