Merge "Snap for 10011508 from b880578664c9d486b2bae51e540c8e6ff2af8017 to android12-tests-release" into android12-tests-release
diff --git a/fs_mgr/libsnapshot/snapshot.cpp b/fs_mgr/libsnapshot/snapshot.cpp
index 0e36da1..2773be7 100644
--- a/fs_mgr/libsnapshot/snapshot.cpp
+++ b/fs_mgr/libsnapshot/snapshot.cpp
@@ -2784,7 +2784,8 @@
               << " writer.GetCowVersion(): " << writer.GetCowVersion();
 
     bool use_compression = IsCompressionEnabled() && dap_metadata.vabc_enabled() &&
-                           !device_->IsRecovery() && cow_format_support;
+                           !device_->IsRecovery() && cow_format_support &&
+                           KernelSupportsCompressedSnapshots();
 
     std::string compression_algorithm;
     if (use_compression) {
diff --git a/fs_mgr/libsnapshot/snapshot_test.cpp b/fs_mgr/libsnapshot/snapshot_test.cpp
index 6018643..57a2854 100644
--- a/fs_mgr/libsnapshot/snapshot_test.cpp
+++ b/fs_mgr/libsnapshot/snapshot_test.cpp
@@ -125,6 +125,10 @@
         sm->set_use_first_stage_snapuserd(false);
     }
 
+    bool DeviceSupportsCompression() {
+        return IsCompressionEnabled() && KernelSupportsCompressedSnapshots();
+    }
+
     void CleanupTestArtifacts() {
         // Normally cancelling inside a merge is not allowed. Since these
         // are tests, we don't care, destroy everything that might exist.
@@ -327,7 +331,7 @@
         DeltaArchiveManifest manifest;
 
         auto dynamic_partition_metadata = manifest.mutable_dynamic_partition_metadata();
-        dynamic_partition_metadata->set_vabc_enabled(IsCompressionEnabled());
+        dynamic_partition_metadata->set_vabc_enabled(DeviceSupportsCompression());
         dynamic_partition_metadata->set_cow_version(android::snapshot::kCowVersionMajor);
 
         auto group = dynamic_partition_metadata->add_groups();
@@ -366,7 +370,7 @@
             if (!res) {
                 return res;
             }
-        } else if (!IsCompressionEnabled()) {
+        } else if (!DeviceSupportsCompression()) {
             std::string ignore;
             if (!MapUpdateSnapshot("test_partition_b", &ignore)) {
                 return AssertionFailure() << "Failed to map test_partition_b";
@@ -425,7 +429,7 @@
     ASSERT_TRUE(AcquireLock());
 
     PartitionCowCreator cow_creator;
-    cow_creator.compression_enabled = IsCompressionEnabled();
+    cow_creator.compression_enabled = DeviceSupportsCompression();
     if (cow_creator.compression_enabled) {
         cow_creator.compression_algorithm = "gz";
     } else {
@@ -466,7 +470,7 @@
     ASSERT_TRUE(AcquireLock());
 
     PartitionCowCreator cow_creator;
-    cow_creator.compression_enabled = IsCompressionEnabled();
+    cow_creator.compression_enabled = DeviceSupportsCompression();
 
     static const uint64_t kDeviceSize = 1024 * 1024;
     SnapshotStatus status;
@@ -585,7 +589,7 @@
     SnapshotStatus status;
     ASSERT_TRUE(init->ReadSnapshotStatus(lock_.get(), "test_partition_b", &status));
     ASSERT_EQ(status.state(), SnapshotState::CREATED);
-    if (IsCompressionEnabled()) {
+    if (DeviceSupportsCompression()) {
         ASSERT_EQ(status.compression_algorithm(), "gz");
     } else {
         ASSERT_EQ(status.compression_algorithm(), "none");
@@ -855,7 +859,7 @@
         opener_ = std::make_unique<TestPartitionOpener>(fake_super);
 
         auto dynamic_partition_metadata = manifest_.mutable_dynamic_partition_metadata();
-        dynamic_partition_metadata->set_vabc_enabled(IsCompressionEnabled());
+        dynamic_partition_metadata->set_vabc_enabled(DeviceSupportsCompression());
         dynamic_partition_metadata->set_cow_version(android::snapshot::kCowVersionMajor);
 
         // Create a fake update package metadata.
@@ -975,7 +979,7 @@
     }
 
     AssertionResult MapOneUpdateSnapshot(const std::string& name) {
-        if (IsCompressionEnabled()) {
+        if (DeviceSupportsCompression()) {
             std::unique_ptr<ISnapshotWriter> writer;
             return MapUpdateSnapshot(name, &writer);
         } else {
@@ -985,7 +989,7 @@
     }
 
     AssertionResult WriteSnapshotAndHash(const std::string& name) {
-        if (IsCompressionEnabled()) {
+        if (DeviceSupportsCompression()) {
             std::unique_ptr<ISnapshotWriter> writer;
             auto res = MapUpdateSnapshot(name, &writer);
             if (!res) {
@@ -1158,7 +1162,7 @@
 
     // Initiate the merge and wait for it to be completed.
     ASSERT_TRUE(init->InitiateMerge());
-    ASSERT_EQ(init->IsSnapuserdRequired(), IsCompressionEnabled());
+    ASSERT_EQ(init->IsSnapuserdRequired(), DeviceSupportsCompression());
     {
         // We should have started in SECOND_PHASE since nothing shrinks.
         ASSERT_TRUE(AcquireLock());
@@ -1187,7 +1191,7 @@
 // Test that shrinking and growing partitions at the same time is handled
 // correctly in VABC.
 TEST_F(SnapshotUpdateTest, SpaceSwapUpdate) {
-    if (!IsCompressionEnabled()) {
+    if (!DeviceSupportsCompression()) {
         // b/179111359
         GTEST_SKIP() << "Skipping Virtual A/B Compression test";
     }
@@ -1255,7 +1259,7 @@
 
     // Initiate the merge and wait for it to be completed.
     ASSERT_TRUE(init->InitiateMerge());
-    ASSERT_EQ(init->IsSnapuserdRequired(), IsCompressionEnabled());
+    ASSERT_EQ(init->IsSnapuserdRequired(), DeviceSupportsCompression());
     {
         // Check that the merge phase is FIRST_PHASE until at least one call
         // to ProcessUpdateState() occurs.
@@ -1879,8 +1883,8 @@
         ASSERT_TRUE(AcquireLock());
 
         PartitionCowCreator cow_creator = {
-                .compression_enabled = IsCompressionEnabled(),
-                .compression_algorithm = IsCompressionEnabled() ? "gz" : "none",
+                .compression_enabled = DeviceSupportsCompression(),
+                .compression_algorithm = DeviceSupportsCompression() ? "gz" : "none",
         };
         SnapshotStatus status;
         status.set_name("sys_a");
@@ -1974,7 +1978,7 @@
 
 // Test for overflow bit after update
 TEST_F(SnapshotUpdateTest, Overflow) {
-    if (IsCompressionEnabled()) {
+    if (DeviceSupportsCompression()) {
         GTEST_SKIP() << "No overflow bit set for userspace COWs";
     }
 
@@ -2040,7 +2044,7 @@
 };
 
 TEST_F(SnapshotUpdateTest, DaemonTransition) {
-    if (!IsCompressionEnabled()) {
+    if (!DeviceSupportsCompression()) {
         GTEST_SKIP() << "Skipping Virtual A/B Compression test";
     }
 
diff --git a/fs_mgr/libsnapshot/utility.cpp b/fs_mgr/libsnapshot/utility.cpp
index 4a2af1c..e46bffb 100644
--- a/fs_mgr/libsnapshot/utility.cpp
+++ b/fs_mgr/libsnapshot/utility.cpp
@@ -25,7 +25,9 @@
 #include <android-base/properties.h>
 #include <android-base/strings.h>
 #include <fs_mgr/roots.h>
+#include <libdm/dm.h>
 
+using android::dm::DeviceMapper;
 using android::dm::kSectorSize;
 using android::fiemap::FiemapStatus;
 using android::fs_mgr::EnsurePathMounted;
@@ -195,5 +197,10 @@
     return name.substr(0, name.size() - suffix.size()) + other_suffix;
 }
 
+bool KernelSupportsCompressedSnapshots() {
+    auto& dm = DeviceMapper::Instance();
+    return dm.GetTargetByName("user", nullptr);
+}
+
 }  // namespace snapshot
 }  // namespace android
diff --git a/fs_mgr/libsnapshot/utility.h b/fs_mgr/libsnapshot/utility.h
index 671de9d..b0e565c 100644
--- a/fs_mgr/libsnapshot/utility.h
+++ b/fs_mgr/libsnapshot/utility.h
@@ -129,6 +129,7 @@
 void AppendExtent(google::protobuf::RepeatedPtrField<chromeos_update_engine::Extent>* extents,
                   uint64_t start_block, uint64_t num_blocks);
 
+bool KernelSupportsCompressedSnapshots();
 bool IsCompressionEnabled();
 
 // Swap the suffix of a partition name.