From 0d2bcd4afe2f7b5fdda21059614da3daf0eb36e0 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Tue, 19 May 2020 05:52:57 +0000 Subject: [PATCH] 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 --- fs_mgr/fs_mgr_dm_linear.cpp | 24 +++++++++++++++++------- fs_mgr/libfiemap/image_manager.cpp | 13 ++++++++----- 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/fs_mgr/fs_mgr_dm_linear.cpp b/fs_mgr/fs_mgr_dm_linear.cpp index ea9c957b5..9046132f8 100644 --- a/fs_mgr/fs_mgr_dm_linear.cpp +++ b/fs_mgr/fs_mgr_dm_linear.cpp @@ -52,17 +52,27 @@ using DmTarget = android::dm::DmTarget; 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 @@ bool CreateDmTableInternal(const CreateLogicalPartitionParams& params, DmTable* 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 67179220c..3ee742f5e 100644 --- a/fs_mgr/libfiemap/image_manager.cpp +++ b/fs_mgr/libfiemap/image_manager.cpp @@ -51,6 +51,7 @@ using android::fs_mgr::GetBlockDevicePartitionNames; using android::fs_mgr::GetPartitionName; static constexpr char kTestImageMetadataDir[] = "/metadata/gsi/test"; +static constexpr char kOtaTestImageMetadataDir[] = "/metadata/gsi/ota/test"; std::unique_ptr ImageManager::Open(const std::string& dir_prefix) { auto metadata_dir = "/metadata/gsi/" + dir_prefix; @@ -135,10 +136,13 @@ bool ImageManager::BackingImageExists(const std::string& name) { 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 @@ FiemapStatus ImageManager::CreateBackingImage( // 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 = {};