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

Commit 31c14e15 authored by Mark Salyzyn's avatar Mark Salyzyn
Browse files

fs_mgr: overlayfs: dig harder for /dev/root equivalent

Check for A/B /dev/block/by-name/system<slot> and also non-A/B
/dev/block/by-name/system to discover what /dev/root can be when
evaluating candidates for using overlayfs.

This is to handle a misconfigured (or legacy) system-as-root device.
It is recommended that the default fstab specifically mentions the
root mount's device node to prevent going down this path.

Test: adb-remount-test.sh
Bug: 138407617
Change-Id: I3853d203b9376d0f848cb490150ff00cc4ed3d5f
parent ef0bc630
Loading
Loading
Loading
Loading
+32 −9
Original line number Diff line number Diff line
@@ -150,6 +150,31 @@ bool fs_mgr_filesystem_has_space(const std::string& mount_point) {
    return (vst.f_bfree >= (vst.f_blocks * kPercentThreshold / 100));
}

const auto kPhysicalDevice = "/dev/block/by-name/"s;

bool fs_mgr_update_blk_device(FstabEntry* entry) {
    if (entry->fs_mgr_flags.logical) {
        fs_mgr_update_logical_partition(entry);
    }
    if (fs_mgr_access(entry->blk_device)) {
        return true;
    }
    if (entry->blk_device != "/dev/root") {
        return false;
    }

    // special case for system-as-root (taimen and others)
    auto blk_device = kPhysicalDevice + "system";
    if (!fs_mgr_access(blk_device)) {
        blk_device += fs_mgr_get_slot_suffix();
        if (!fs_mgr_access(blk_device)) {
            return false;
        }
    }
    entry->blk_device = blk_device;
    return true;
}

bool fs_mgr_overlayfs_enabled(FstabEntry* entry) {
    // readonly filesystem, can not be mount -o remount,rw
    // for squashfs, erofs or if free space is (near) zero making such a remount
@@ -157,19 +182,19 @@ bool fs_mgr_overlayfs_enabled(FstabEntry* entry) {
    if (!fs_mgr_filesystem_has_space(entry->mount_point)) {
        return true;
    }
    if (entry->fs_mgr_flags.logical) {
        fs_mgr_update_logical_partition(entry);

    // blk_device needs to be setup so we can check superblock.
    // If we fail here, because during init first stage and have doubts.
    if (!fs_mgr_update_blk_device(entry)) {
        return true;
    }

    // check if ext4 de-dupe
    auto save_errno = errno;
    errno = 0;
    auto has_shared_blocks = fs_mgr_has_shared_blocks(entry->mount_point, entry->blk_device);
    if (!has_shared_blocks && (entry->mount_point == "/system")) {
        has_shared_blocks = fs_mgr_has_shared_blocks("/", entry->blk_device);
    }
    // special case for first stage init for system as root (taimen)
    if (!has_shared_blocks && (errno == ENOENT) && (entry->blk_device == "/dev/root")) {
        has_shared_blocks = true;
    }
    errno = save_errno;
    return has_shared_blocks;
}
@@ -388,8 +413,6 @@ uint32_t fs_mgr_overlayfs_slot_number() {
    return SlotNumberForSlotSuffix(fs_mgr_get_slot_suffix());
}

const auto kPhysicalDevice = "/dev/block/by-name/"s;

std::string fs_mgr_overlayfs_super_device(uint32_t slot_number) {
    return kPhysicalDevice + fs_mgr_get_super_partition_name(slot_number);
}