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

Commit fa130f3a authored by Mark Salyzyn's avatar Mark Salyzyn Committed by Gerrit Code Review
Browse files

Merge "fs_mgr: overlayfs: export fs_mgr_overlayfs_candidate_list"

parents da20bc76 dffdb437
Loading
Loading
Loading
Loading
+64 −47
Original line number Diff line number Diff line
@@ -78,6 +78,10 @@ bool fs_mgr_overlayfs_filesystem_available(const std::string& filesystem) {

#if ALLOW_ADBD_DISABLE_VERITY == 0  // If we are a user build, provide stubs

Fstab fs_mgr_overlayfs_candidate_list(const Fstab&) {
    return {};
}

bool fs_mgr_overlayfs_mount_all(Fstab*) {
    return false;
}
@@ -238,8 +242,7 @@ std::string fs_mgr_get_overlayfs_options(const std::string& mount_point) {
    return ret;
}

const char* fs_mgr_mount_point(const char* mount_point) {
    if (!mount_point) return mount_point;
const std::string fs_mgr_mount_point(const std::string& mount_point) {
    if ("/"s != mount_point) return mount_point;
    return "/system";
}
@@ -526,40 +529,6 @@ bool fs_mgr_overlayfs_mount(const std::string& mount_point) {
    }
}

std::vector<std::string> fs_mgr_candidate_list(Fstab* fstab, const char* mount_point = nullptr) {
    std::vector<std::string> mounts;
    for (auto& entry : *fstab) {
        if (!fs_mgr_overlayfs_already_mounted(entry.mount_point) &&
            !fs_mgr_wants_overlayfs(&entry)) {
            continue;
        }
        std::string new_mount_point(fs_mgr_mount_point(entry.mount_point.c_str()));
        if (mount_point && (new_mount_point != mount_point)) continue;

        auto saved_errno = errno;
        auto verity_enabled = fs_mgr_is_verity_enabled(entry);
        if (errno == ENOENT || errno == ENXIO) errno = saved_errno;
        if (verity_enabled) continue;

        auto duplicate_or_more_specific = false;
        for (auto it = mounts.begin(); it != mounts.end();) {
            if ((*it == new_mount_point) ||
                (android::base::StartsWith(new_mount_point, *it + "/"))) {
                duplicate_or_more_specific = true;
                break;
            }
            if (android::base::StartsWith(*it, new_mount_point + "/")) {
                it = mounts.erase(it);
            } else {
                ++it;
            }
        }
        if (!duplicate_or_more_specific) mounts.emplace_back(new_mount_point);
    }

    return mounts;
}

// Mount kScratchMountPoint
bool fs_mgr_overlayfs_mount_scratch(const std::string& device_path, const std::string mnt_type,
                                    bool readonly = false) {
@@ -802,12 +771,42 @@ bool fs_mgr_overlayfs_invalid() {

}  // namespace

Fstab fs_mgr_overlayfs_candidate_list(const Fstab& fstab) {
    Fstab candidates;
    for (const auto& entry : fstab) {
        FstabEntry new_entry = entry;
        if (!fs_mgr_overlayfs_already_mounted(entry.mount_point) &&
            !fs_mgr_wants_overlayfs(&new_entry)) {
            continue;
        }
        auto new_mount_point = fs_mgr_mount_point(entry.mount_point);
        auto duplicate_or_more_specific = false;
        for (auto it = candidates.begin(); it != candidates.end();) {
            auto it_mount_point = fs_mgr_mount_point(it->mount_point);
            if ((it_mount_point == new_mount_point) ||
                (android::base::StartsWith(new_mount_point, it_mount_point + "/"))) {
                duplicate_or_more_specific = true;
                break;
            }
            if (android::base::StartsWith(it_mount_point, new_mount_point + "/")) {
                it = candidates.erase(it);
            } else {
                ++it;
            }
        }
        if (!duplicate_or_more_specific) candidates.emplace_back(std::move(new_entry));
    }
    return candidates;
}

bool fs_mgr_overlayfs_mount_all(Fstab* fstab) {
    auto ret = false;
    if (fs_mgr_overlayfs_invalid()) return ret;

    auto scratch_can_be_mounted = true;
    for (const auto& mount_point : fs_mgr_candidate_list(fstab)) {
    for (const auto& entry : fs_mgr_overlayfs_candidate_list(*fstab)) {
        if (fs_mgr_is_verity_enabled(entry)) continue;
        auto mount_point = fs_mgr_mount_point(entry.mount_point);
        if (fs_mgr_overlayfs_already_mounted(mount_point)) {
            ret = true;
            continue;
@@ -840,8 +839,9 @@ std::vector<std::string> fs_mgr_overlayfs_required_devices(Fstab* fstab) {
        return {};
    }

    for (const auto& mount_point : fs_mgr_candidate_list(fstab)) {
        if (fs_mgr_overlayfs_already_mounted(mount_point)) continue;
    for (const auto& entry : fs_mgr_overlayfs_candidate_list(*fstab)) {
        if (fs_mgr_is_verity_enabled(entry)) continue;
        if (fs_mgr_overlayfs_already_mounted(fs_mgr_mount_point(entry.mount_point))) continue;
        auto device = fs_mgr_overlayfs_scratch_device();
        if (!fs_mgr_overlayfs_scratch_can_be_mounted(device)) break;
        return {device};
@@ -867,8 +867,24 @@ bool fs_mgr_overlayfs_setup(const char* backing, const char* mount_point, bool*
        return false;
    }
    errno = save_errno;
    auto mounts = fs_mgr_candidate_list(&fstab, fs_mgr_mount_point(mount_point));
    if (mounts.empty()) return ret;
    auto candidates = fs_mgr_overlayfs_candidate_list(fstab);
    for (auto it = candidates.begin(); it != candidates.end();) {
        if (mount_point &&
            (fs_mgr_mount_point(it->mount_point) != fs_mgr_mount_point(mount_point))) {
            it = candidates.erase(it);
            continue;
        }
        save_errno = errno;
        auto verity_enabled = fs_mgr_is_verity_enabled(*it);
        if (errno == ENOENT || errno == ENXIO) errno = save_errno;
        if (verity_enabled) {
            it = candidates.erase(it);
            continue;
        }
        ++it;
    }

    if (candidates.empty()) return ret;

    std::string dir;
    for (const auto& overlay_mount_point : kOverlayMountPoints) {
@@ -891,8 +907,8 @@ bool fs_mgr_overlayfs_setup(const char* backing, const char* mount_point, bool*

    std::string overlay;
    ret |= fs_mgr_overlayfs_setup_dir(dir, &overlay, change);
    for (const auto& fsrec_mount_point : mounts) {
        ret |= fs_mgr_overlayfs_setup_one(overlay, fsrec_mount_point, change);
    for (const auto& entry : candidates) {
        ret |= fs_mgr_overlayfs_setup_one(overlay, fs_mgr_mount_point(entry.mount_point), change);
    }
    return ret;
}
@@ -901,7 +917,6 @@ bool fs_mgr_overlayfs_setup(const char* backing, const char* mount_point, bool*
// If something is altered, set *change.
bool fs_mgr_overlayfs_teardown(const char* mount_point, bool* change) {
    if (change) *change = false;
    mount_point = fs_mgr_mount_point(mount_point);
    auto ret = true;
    // If scratch exists, but is not mounted, lets gain access to clean
    // specific override entries.
@@ -919,7 +934,8 @@ bool fs_mgr_overlayfs_teardown(const char* mount_point, bool* change) {
                                                       fs_mgr_overlayfs_scratch_mount_type());
    }
    for (const auto& overlay_mount_point : kOverlayMountPoints) {
        ret &= fs_mgr_overlayfs_teardown_one(overlay_mount_point, mount_point ?: "", change);
        ret &= fs_mgr_overlayfs_teardown_one(
                overlay_mount_point, mount_point ? fs_mgr_mount_point(mount_point) : "", change);
    }
    if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kNotSupported) {
        // After obligatory teardown to make sure everything is clean, but if
@@ -946,8 +962,9 @@ bool fs_mgr_overlayfs_is_setup() {
        return false;
    }
    if (fs_mgr_overlayfs_invalid()) return false;
    for (const auto& mount_point : fs_mgr_candidate_list(&fstab)) {
        if (fs_mgr_overlayfs_already_mounted(mount_point)) return true;
    for (const auto& entry : fs_mgr_overlayfs_candidate_list(fstab)) {
        if (fs_mgr_is_verity_enabled(entry)) continue;
        if (fs_mgr_overlayfs_already_mounted(fs_mgr_mount_point(entry.mount_point))) return true;
    }
    return false;
}
+2 −0
Original line number Diff line number Diff line
@@ -21,6 +21,8 @@
#include <string>
#include <vector>

android::fs_mgr::Fstab fs_mgr_overlayfs_candidate_list(const android::fs_mgr::Fstab& fstab);

bool fs_mgr_overlayfs_mount_all(android::fs_mgr::Fstab* fstab);
std::vector<std::string> fs_mgr_overlayfs_required_devices(android::fs_mgr::Fstab* fstab);
bool fs_mgr_overlayfs_setup(const char* backing = nullptr, const char* mount_point = nullptr,
+37 −10
Original line number Diff line number Diff line
@@ -210,6 +210,21 @@ adb_wait() {
  fi
}

[ "USAGE: usb_status > stdout

If adb_wait failed, check if device is in fastboot mode and report status

Returns: \"(USB stack borken?)\", \"(In fastboot mode)\" or \"(in adb mode)\"" ]
usb_status() {
  if inFastboot; then
    echo "(In fastboot mode)"
  elif inAdb; then
    echo "(In adb mode)"
  else
    echo "(USB stack borken?)"
  fi
}

[ "USAGE: fastboot_wait [timeout]

Returns: waits until the device has returned for fastboot or optional timeout" ]
@@ -383,6 +398,17 @@ skip_administrative_mounts() {
    -e " /\(cache\|mnt/scratch\|mnt/vendor/persist\|persist\|metadata\) "
}

[ "USAGE: skip_unrelated_mounts < /proc/mounts

or output from df

Filters out all apex and vendor override administrative overlay mounts
uninteresting to the test" ]
skip_unrelated_mounts() {
    grep -v "^overlay.* /\(apex\|bionic\|system\|vendor\)/[^ ]" |
      grep -v "[%] /\(apex\|bionic\|system\|vendor\)/[^ ][^ ]*$"
}

##
##  MAINLINE
##
@@ -484,9 +510,9 @@ if ${reboot}; then
  echo "${ORANGE}[  WARNING ]${NORMAL} rebooting before test" >&2
  adb_reboot &&
    adb_wait 2m ||
    die "lost device after reboot after wipe (USB stack broken?)"
    die "lost device after reboot after wipe `usb_status`"
  adb_root ||
    die "lost device after elevation to root after wipe (USB stack broken?)"
    die "lost device after elevation to root after wipe `usb_status`"
fi
D=`adb_sh df -k </dev/null` &&
  H=`echo "${D}" | head -1` &&
@@ -509,7 +535,8 @@ for d in ${D}; do
    grep "Filesystem features:.*shared_blocks" >/dev/null &&
  no_dedupe=false
done
D=`adb_sh df -k ${D} </dev/null`
D=`adb_sh df -k ${D} </dev/null |
   sed 's@\([%] /\)\(apex\|bionic\|system\|vendor\)/[^ ][^ ]*$@\1@'`
echo "${D}"
if [ X"${D}" = X"${D##* 100[%] }" ] && ${no_dedupe} ; then
  overlayfs_needed=false
@@ -548,9 +575,9 @@ if [ X"${D}" != X"${H}" ]; then
  L=`adb_logcat -b all -v nsec -t ${T} 2>&1`
  adb_reboot &&
    adb_wait 2m ||
    die "lost device after reboot requested (USB stack broken?)"
    die "lost device after reboot requested `usb_status`"
  adb_root ||
    die "lost device after elevation to root (USB stack broken?)"
    die "lost device after elevation to root `usb_status`"
  rebooted=true
  # re-disable verity to see the setup remarks expected
  T=`adb_date`
@@ -593,7 +620,7 @@ adb remount ||
  die -t "${T}" "adb remount failed"
D=`adb_sh df -k </dev/null` &&
  H=`echo "${D}" | head -1` &&
  D=`echo "${D}" | grep -v " /vendor/..*$" | grep "^overlay "` ||
  D=`echo "${D}" | skip_unrelated_mounts | grep "^overlay "` ||
  ( [ -n "${L}" ] && echo "${L}" && false )
ret=${?}
uses_dynamic_scratch=false
@@ -637,7 +664,7 @@ if ${overlayfs_needed}; then
    echo "${D}" | grep "^overlay .* /system\$" >/dev/null ||
    die  "overlay takeover after remount"
  !(adb_sh grep "^overlay " /proc/mounts </dev/null |
    grep -v "^overlay /\(vendor\|system\|bionic\)/..* overlay ro," |
    skip_unrelated_mounts |
    grep " overlay ro,") &&
    !(adb_sh grep " rw," /proc/mounts </dev/null |
      skip_administrative_mounts data) ||
@@ -694,7 +721,7 @@ if ${overlayfs_needed}; then

  adb_su sed -n '1,/overlay \/system/p' /proc/mounts </dev/null |
    skip_administrative_mounts |
    grep -v ' \(squashfs\|ext4\|f2fs\) ' &&
    grep -v ' \(squashfs\|ext4\|f2fs\|vfat\) ' &&
    echo "${ORANGE}[  WARNING ]${NORMAL} overlay takeover after first stage init" >&2 ||
    echo "${GREEN}[       OK ]${NORMAL} overlay takeover in first stage init" >&2
fi
@@ -782,7 +809,7 @@ else
    adb_root &&
      D=`adb_sh df -k </dev/null` &&
      H=`echo "${D}" | head -1` &&
      D=`echo "${D}" | grep -v " /vendor/..*$" | grep "^overlay "` &&
      D=`echo "${D}" | skip_unrelated_mounts | grep "^overlay "` &&
      echo "${H}" &&
      echo "${D}" &&
      echo "${D}" | grep "^overlay .* /system\$" >/dev/null ||
@@ -888,7 +915,7 @@ echo "${GREEN}[ RUN ]${NORMAL} test raw remount commands" >&2
# Prerequisite is a prepped device from above.
adb_reboot &&
  adb_wait 2m ||
  die "lost device after reboot to ro state (USB stack broken?)"
  die "lost device after reboot to ro state `usb_status`"
adb_sh grep " /vendor .* rw," /proc/mounts >/dev/null &&
  die "/vendor is not read-only"
adb_su mount -o rw,remount /vendor ||