Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0d2bcd4a authored by David Anderson's avatar David Anderson
Browse files

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
parent f3a570b8
Loading
Loading
Loading
Loading
+17 −7
Original line number Diff line number Diff line
@@ -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;
                }
+8 −5
Original line number Diff line number Diff line
@@ -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> 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 = {};