Merge "Disallow exit-time destructors in libutils."
diff --git a/fs_mgr/libsnapshot/android/snapshot/snapshot.proto b/fs_mgr/libsnapshot/android/snapshot/snapshot.proto
index 42bff14..b4e92a2 100644
--- a/fs_mgr/libsnapshot/android/snapshot/snapshot.proto
+++ b/fs_mgr/libsnapshot/android/snapshot/snapshot.proto
@@ -46,7 +46,7 @@
     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 @@
 
     // 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 84372de..34b39ca 100644
--- a/fs_mgr/libsnapshot/partition_cow_creator.h
+++ b/fs_mgr/libsnapshot/partition_cow_creator.h
@@ -58,6 +58,7 @@
     std::vector<ChromeOSExtent> 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 cc2599d..ca4c265 100644
--- a/fs_mgr/libsnapshot/snapshot.cpp
+++ b/fs_mgr/libsnapshot/snapshot.cpp
@@ -359,6 +359,7 @@
     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 @@
     // 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 @@
             .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 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 @@
     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 @@
         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 bde4cca..25500b5 100644
--- a/fs_mgr/libsnapshot/snapshot_test.cpp
+++ b/fs_mgr/libsnapshot/snapshot_test.cpp
@@ -423,6 +423,11 @@
 
     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 @@
         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 @@
     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/snapuserd.cpp b/fs_mgr/libsnapshot/snapuserd.cpp
index d620300..4c4a342 100644
--- a/fs_mgr/libsnapshot/snapuserd.cpp
+++ b/fs_mgr/libsnapshot/snapuserd.cpp
@@ -447,16 +447,15 @@
 }
 
 void Snapuserd::CheckMergeCompletionStatus() {
-    CowHeader header;
-
-    if (merge_initiated_) {
-        reader_->GetHeader(&header);
-        SNAP_LOG(INFO) << "Merge-status: Total-Merged-ops: " << header.num_merge_ops
-                       << " Total-data-ops: " << reader_->total_data_ops();
-    } else {
-        SNAP_LOG(INFO) << "Merge was not initiated. Total-Merged-ops: " << header.num_merge_ops
-                       << " Total-data-ops: " << reader_->total_data_ops();
+    if (!merge_initiated_) {
+        SNAP_LOG(INFO) << "Merge was not initiated. Total-data-ops: " << reader_->total_data_ops();
+        return;
     }
+
+    CowHeader header;
+    reader_->GetHeader(&header);
+    SNAP_LOG(INFO) << "Merge-status: Total-Merged-ops: " << header.num_merge_ops
+                   << " Total-data-ops: " << reader_->total_data_ops();
 }
 
 /*
diff --git a/fs_mgr/libsnapshot/update_engine/update_metadata.proto b/fs_mgr/libsnapshot/update_engine/update_metadata.proto
index 4a97f81..f31ee31 100644
--- a/fs_mgr/libsnapshot/update_engine/update_metadata.proto
+++ b/fs_mgr/libsnapshot/update_engine/update_metadata.proto
@@ -74,6 +74,7 @@
 message DynamicPartitionMetadata {
     repeated DynamicPartitionGroup groups = 1;
     optional bool vabc_enabled = 3;
+    optional string vabc_compression_param = 4;
 }
 
 message DeltaArchiveManifest {
diff --git a/libcutils/include/cutils/threads.h b/libcutils/include/cutils/threads.h
index 0f7f8a8..0082c6c 100644
--- a/libcutils/include/cutils/threads.h
+++ b/libcutils/include/cutils/threads.h
@@ -31,7 +31,9 @@
 //
 // Deprecated: use android::base::GetThreadId instead, which doesn't truncate on Mac/Windows.
 //
+#if !defined(__GLIBC__) || __GLIBC__ >= 2 && __GLIBC_MINOR__ < 32
 extern pid_t gettid();
+#endif
 
 #ifdef __cplusplus
 }
diff --git a/libcutils/threads.cpp b/libcutils/threads.cpp
index 8cfee1e..6ece7a3 100644
--- a/libcutils/threads.cpp
+++ b/libcutils/threads.cpp
@@ -25,8 +25,9 @@
 #include <windows.h>
 #endif
 
-#if defined(__BIONIC__)
+#if defined(__BIONIC__) || defined(__GLIBC__) && __GLIBC_MINOR__ >= 32
 // No definition needed for Android because we'll just pick up bionic's copy.
+// No definition needed for Glibc >= 2.32 because it exposes its own copy.
 #else
 pid_t gettid() {
 #if defined(__APPLE__)