fs_mgr: overlayfs: export fs_mgr_overlayfs_candidate_list
Refactor fs_mgr_candidate_list into fs_mgr_overlayfs_candidate_list that reports all the possible candidates. The caller is responsible for filtering out any that have verity enabled. Sundry improvements to the adb-remount-test.sh script to improve stability and feedback. Test: adb-remount-test.sh Bug: 122602260 Change-Id: I2399f83d8ed77d8f3d2ad1405d0c187ccbace764
This commit is contained in:
parent
111e38e5bc
commit
dffdb4374b
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 ||
|
||||
|
|
Loading…
Reference in New Issue