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

Commit f21cb6e6 authored by Martin Stjernholm's avatar Martin Stjernholm
Browse files

Try erofs when mounting OTA partitions.

We don't know which filesystem type the partitions may have, but
currently only ext4 and erofs are in use.

A more generic approach would be to use libext2_blkid or the blkid
binary to find the filesystem type from the block device itself, since
update_engine doesn't divulge this information. However this is good
enough for now.

Test: m dist
      system/update_engine/scripts/update_device.py out/dist/cf_x86_64_phone-ota-eng.*.zip
  on a Cuttlefish device, and check logcat that ext4 mounts fails but
  erofs ones work.
Bug: 270940551
Bug: 202022157
Change-Id: I77b9472418d7996695c2b28b20d43711d5c4d771
parent 5c6bf399
Loading
Loading
Loading
Loading
+27 −12
Original line number Diff line number Diff line
@@ -45,6 +45,10 @@ using android::base::StringPrintf;
namespace android {
namespace installd {

// We don't know the filesystem types of the partitions in the update package,
// so just try the possibilities one by one.
static constexpr std::array kTryMountFsTypes = {"ext4", "erofs"};

static void CloseDescriptor(int fd) {
    if (fd >= 0) {
        int result = close(fd);
@@ -82,6 +86,27 @@ static void DeactivateApexPackages() {
    }
}

static bool TryMountWithFstypes(const char* block_device, const char* target) {
    for (int i = 0; i < kTryMountFsTypes.size(); ++i) {
        const char* fstype = kTryMountFsTypes[i];
        int mount_result = mount(block_device, target, fstype, MS_RDONLY, /* data */ nullptr);
        if (mount_result == 0) {
            return true;
        }
        if (errno == EINVAL && i < kTryMountFsTypes.size() - 1) {
            // Only try the next fstype if mounting failed due to the current one
            // being invalid.
            LOG(WARNING) << "Failed to mount " << block_device << " on " << target << " with "
                         << fstype << " - trying " << kTryMountFsTypes[i + 1];
        } else {
            PLOG(ERROR) << "Failed to mount " << block_device << " on " << target << " with "
                        << fstype;
            return false;
        }
    }
    __builtin_unreachable();
}

static void TryExtraMount(const char* name, const char* slot, const char* target) {
    std::string partition_name = StringPrintf("%s%s", name, slot);

@@ -91,12 +116,7 @@ static void TryExtraMount(const char* name, const char* slot, const char* target
        if (dm.GetState(partition_name) != dm::DmDeviceState::INVALID) {
            std::string path;
            if (dm.GetDmDevicePathByName(partition_name, &path)) {
                int mount_result = mount(path.c_str(),
                                         target,
                                         "ext4",
                                         MS_RDONLY,
                                         /* data */ nullptr);
                if (mount_result == 0) {
                if (TryMountWithFstypes(path.c_str(), target)) {
                    return;
                }
            }
@@ -105,12 +125,7 @@ static void TryExtraMount(const char* name, const char* slot, const char* target

    // Fall back and attempt a direct mount.
    std::string block_device = StringPrintf("/dev/block/by-name/%s", partition_name.c_str());
    int mount_result = mount(block_device.c_str(),
                             target,
                             "ext4",
                             MS_RDONLY,
                             /* data */ nullptr);
    UNUSED(mount_result);
    (void)TryMountWithFstypes(block_device.c_str(), target);
}

// Entry for otapreopt_chroot. Expected parameters are: