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 = {};