libsnapshot: OTA upgrade when vendor partition is S

In Android S, snapuserd binary was on vendor partition.
When there is an OTA update from S -> T, it is possible
that vendor partitions are not updated. In that case,
successive OTA updates T1 -> T2 will continue to have
snapuserd from Android S as vendor partition wasn't updated
to T. All this means, we should disable user-space snapshots.

When installing OTA during runtime, check for property
ro.vendor.build.version.release_or_codename; if the property
is set to "12", then skip userspace-snapshots.

Bug: 227614163

Test: Simulate OTA test on Pixel 6 from T1 -> T2 by forcefully
setting the property to 12 and verify OTA is applied
successfully by falling back to dm-snapshot.

Signed-off-by: Akilesh Kailash <akailash@google.com>
Change-Id: I95f29145e5cd9ffb8d03d28ae414f0037b88be90
diff --git a/fs_mgr/libsnapshot/snapshot.cpp b/fs_mgr/libsnapshot/snapshot.cpp
index 797d627..d086f29 100644
--- a/fs_mgr/libsnapshot/snapshot.cpp
+++ b/fs_mgr/libsnapshot/snapshot.cpp
@@ -3205,15 +3205,27 @@
     status.set_compression_enabled(cow_creator.compression_enabled);
     if (cow_creator.compression_enabled) {
         if (!device()->IsTestDevice()) {
+            bool userSnapshotsEnabled = IsUserspaceSnapshotsEnabled();
+            const std::string UNKNOWN = "unknown";
+            const std::string vendor_release = android::base::GetProperty(
+                    "ro.vendor.build.version.release_or_codename", UNKNOWN);
+
+            // No user-space snapshots if vendor partition is on Android 12
+            if (vendor_release.find("12") != std::string::npos) {
+                LOG(INFO) << "Userspace snapshots disabled as vendor partition is on Android: "
+                          << vendor_release;
+                userSnapshotsEnabled = false;
+            }
+
             // Userspace snapshots is enabled only if compression is enabled
-            status.set_userspace_snapshots(IsUserspaceSnapshotsEnabled());
-            if (IsUserspaceSnapshotsEnabled()) {
+            status.set_userspace_snapshots(userSnapshotsEnabled);
+            if (userSnapshotsEnabled) {
                 is_snapshot_userspace_ = true;
                 status.set_io_uring_enabled(IsIouringEnabled());
-                LOG(INFO) << "User-space snapshots enabled";
+                LOG(INFO) << "Userspace snapshots enabled";
             } else {
                 is_snapshot_userspace_ = false;
-                LOG(INFO) << "User-space snapshots disabled";
+                LOG(INFO) << "Userspace snapshots disabled";
             }
 
             // Terminate stale daemon if any
diff --git a/fs_mgr/libsnapshot/snapuserd/dm-snapshot-merge/cow_snapuserd_test.cpp b/fs_mgr/libsnapshot/snapuserd/dm-snapshot-merge/cow_snapuserd_test.cpp
index b86a802..484a9c4 100644
--- a/fs_mgr/libsnapshot/snapuserd/dm-snapshot-merge/cow_snapuserd_test.cpp
+++ b/fs_mgr/libsnapshot/snapuserd/dm-snapshot-merge/cow_snapuserd_test.cpp
@@ -932,7 +932,6 @@
 
     ASSERT_EQ(area_sz, 2);
 
-    size_t new_chunk = 263;
     // Verify the partially filled area
     void* buffer = snapuserd_->GetExceptionBuffer(1);
     loff_t offset = 0;
@@ -941,7 +940,6 @@
         de = reinterpret_cast<struct disk_exception*>((char*)buffer + offset);
         ASSERT_EQ(de->old_chunk, i);
         offset += sizeof(struct disk_exception);
-        new_chunk += 1;
     }
 
     de = reinterpret_cast<struct disk_exception*>((char*)buffer + offset);
diff --git a/fs_mgr/libsnapshot/snapuserd/snapuserd_daemon.cpp b/fs_mgr/libsnapshot/snapuserd/snapuserd_daemon.cpp
index c31772b..2f7775c 100644
--- a/fs_mgr/libsnapshot/snapuserd/snapuserd_daemon.cpp
+++ b/fs_mgr/libsnapshot/snapuserd/snapuserd_daemon.cpp
@@ -34,6 +34,17 @@
 namespace snapshot {
 
 bool Daemon::IsUserspaceSnapshotsEnabled() {
+    const std::string UNKNOWN = "unknown";
+    const std::string vendor_release =
+            android::base::GetProperty("ro.vendor.build.version.release_or_codename", UNKNOWN);
+
+    // No user-space snapshots if vendor partition is on Android 12
+    if (vendor_release.find("12") != std::string::npos) {
+        LOG(INFO) << "Userspace snapshots disabled as vendor partition is on Android: "
+                  << vendor_release;
+        return false;
+    }
+
     return android::base::GetBoolProperty("ro.virtual_ab.userspace.snapshots.enabled", false);
 }