libsnapshot_test: Fix running on DSUs.

Because DSUs mount userdata via a fiemap, libfiemap has trouble creating
additional fiemaps on top of it. The complex stacking of dm-linear is
not supported. For other libfiemap tests we've hacked around this
limitation. If LpMetadata is in a folder named "test", we allow the
backing device search to stop at a dm node, whereas otherwise it would
need to stop at a physical device.

However this was not quite enough for vts_libsnapshot_test, because (1)
the test folder was not included in the pattern match, and (2)
CreateLogicalPartition() could not handle device-mapper names, as it
expects a named physical partition. Addressing both of these allows the
tests to pass on DSUs.

Bug: 156713441
Test: vts_libsnapshot_test on DSU
Change-Id: Ie7ee70e31dff0809a5f0c402ed132d80dd03d9b1
diff --git a/fs_mgr/fs_mgr_dm_linear.cpp b/fs_mgr/fs_mgr_dm_linear.cpp
index ea9c957..9046132 100644
--- a/fs_mgr/fs_mgr_dm_linear.cpp
+++ b/fs_mgr/fs_mgr_dm_linear.cpp
@@ -52,17 +52,27 @@
 using DmTargetZero = android::dm::DmTargetZero;
 using DmTargetLinear = android::dm::DmTargetLinear;
 
-static bool GetPhysicalPartitionDevicePath(const IPartitionOpener& opener,
-                                           const LpMetadata& metadata,
+static bool GetPhysicalPartitionDevicePath(const CreateLogicalPartitionParams& params,
                                            const LpMetadataBlockDevice& block_device,
                                            const std::string& super_device, std::string* result) {
     // If the super device is the source of this block device's metadata,
     // make sure we use the correct super device (and not just "super",
     // which might not exist.)
     std::string name = GetBlockDevicePartitionName(block_device);
-    std::string dev_string = opener.GetDeviceString(name);
-    if (GetMetadataSuperBlockDevice(metadata) == &block_device) {
-        dev_string = opener.GetDeviceString(super_device);
+    if (android::base::StartsWith(name, "dm-")) {
+        // Device-mapper nodes are not normally allowed in LpMetadata, since
+        // they are not consistent across reboots. However for the purposes of
+        // testing it's useful to handle them. For example when running DSUs,
+        // userdata is a device-mapper device, and some stacking will result
+        // when using libfiemap.
+        *result = "/dev/block/" + name;
+        return true;
+    }
+
+    auto opener = params.partition_opener;
+    std::string dev_string = opener->GetDeviceString(name);
+    if (GetMetadataSuperBlockDevice(*params.metadata) == &block_device) {
+        dev_string = opener->GetDeviceString(super_device);
     }
 
     // Note: device-mapper will not accept symlinks, so we must use realpath
@@ -93,8 +103,8 @@
             case LP_TARGET_TYPE_LINEAR: {
                 const auto& block_device = params.metadata->block_devices[extent.target_source];
                 std::string dev_string;
-                if (!GetPhysicalPartitionDevicePath(*params.partition_opener, *params.metadata,
-                                                    block_device, super_device, &dev_string)) {
+                if (!GetPhysicalPartitionDevicePath(params, block_device, super_device,
+                                                    &dev_string)) {
                     LOG(ERROR) << "Unable to complete device-mapper table, unknown block device";
                     return false;
                 }
diff --git a/fs_mgr/libfiemap/image_manager.cpp b/fs_mgr/libfiemap/image_manager.cpp
index 6717922..3ee742f 100644
--- a/fs_mgr/libfiemap/image_manager.cpp
+++ b/fs_mgr/libfiemap/image_manager.cpp
@@ -51,6 +51,7 @@
 using android::fs_mgr::GetPartitionName;
 
 static constexpr char kTestImageMetadataDir[] = "/metadata/gsi/test";
+static constexpr char kOtaTestImageMetadataDir[] = "/metadata/gsi/ota/test";
 
 std::unique_ptr<ImageManager> ImageManager::Open(const std::string& dir_prefix) {
     auto metadata_dir = "/metadata/gsi/" + dir_prefix;
@@ -135,10 +136,13 @@
     return !!FindPartition(*metadata.get(), name);
 }
 
+static bool IsTestDir(const std::string& path) {
+    return android::base::StartsWith(path, kTestImageMetadataDir) ||
+           android::base::StartsWith(path, kOtaTestImageMetadataDir);
+}
+
 static bool IsUnreliablePinningAllowed(const std::string& path) {
-    return android::base::StartsWith(path, "/data/gsi/dsu/") ||
-           android::base::StartsWith(path, "/data/gsi/test/") ||
-           android::base::StartsWith(path, "/data/gsi/ota/test/");
+    return android::base::StartsWith(path, "/data/gsi/dsu/") || IsTestDir(path);
 }
 
 FiemapStatus ImageManager::CreateBackingImage(
@@ -174,8 +178,7 @@
     // if device-mapper is stacked in some complex way not supported by
     // FiemapWriter.
     auto device_path = GetDevicePathForFile(fw.get());
-    if (android::base::StartsWith(device_path, "/dev/block/dm-") &&
-        !android::base::StartsWith(metadata_dir_, kTestImageMetadataDir)) {
+    if (android::base::StartsWith(device_path, "/dev/block/dm-") && !IsTestDir(metadata_dir_)) {
         LOG(ERROR) << "Cannot persist images against device-mapper device: " << device_path;
 
         fw = {};