fs_mgr: fs_mgr_has_shared_blocks() needs logical blk_device
For logical partitions, the fstab supplied during fs_mgr_overlayfs_setup() does not have the correct blk_device and thus check in fs_mgr_has_shared_blocks() inside fs_mgr_overlayfs_enabled() will fail to provide the correct status. Call fs_mgr_update_logical_partition() to fix this up. Side effect is an API change where fstab can no longer be considered const when passed into fs_mgr_overlayfs_mount_all() and fs_mgr_overlayfs_required_devices(). Some additional minor cleanup as well. Move fs_mgr_rm_all() higher up as-is in the file as it has no dependencies, which will complicate future changes. Add --help to adb-remount-test.sh unit test script, improve error handling and checking. Test: adb-remount-test.sh Bug: 109821005 Bug: 117605276 Change-Id: I548d3797d49661529490d1a0bf96b63e57491704
This commit is contained in:
parent
55d31ecd86
commit
1b066c313b
3 changed files with 92 additions and 73 deletions
|
@ -41,6 +41,7 @@
|
|||
#include <android-base/strings.h>
|
||||
#include <android-base/unique_fd.h>
|
||||
#include <ext4_utils/ext4_utils.h>
|
||||
#include <fs_mgr.h>
|
||||
#include <fs_mgr_dm_linear.h>
|
||||
#include <fs_mgr_overlayfs.h>
|
||||
#include <fstab/fstab.h>
|
||||
|
@ -127,13 +128,63 @@ bool fs_mgr_filesystem_has_space(const char* mount_point) {
|
|||
return (vst.f_bfree >= (vst.f_blocks * kPercentThreshold / 100));
|
||||
}
|
||||
|
||||
bool fs_mgr_overlayfs_enabled(const struct fstab_rec* fsrec) {
|
||||
bool fs_mgr_overlayfs_enabled(struct fstab_rec* fsrec) {
|
||||
// readonly filesystem, can not be mount -o remount,rw
|
||||
// if squashfs or if free space is (near) zero making such a remount
|
||||
// virtually useless, or if there are shared blocks that prevent remount,rw
|
||||
return ("squashfs"s == fsrec->fs_type) ||
|
||||
fs_mgr_has_shared_blocks(fsrec->mount_point, fsrec->blk_device) ||
|
||||
!fs_mgr_filesystem_has_space(fsrec->mount_point);
|
||||
if (("squashfs"s == fsrec->fs_type) || !fs_mgr_filesystem_has_space(fsrec->mount_point)) {
|
||||
return true;
|
||||
}
|
||||
if (fs_mgr_is_logical(fsrec)) {
|
||||
fs_mgr_update_logical_partition(fsrec);
|
||||
}
|
||||
return fs_mgr_has_shared_blocks(fsrec->mount_point, fsrec->blk_device);
|
||||
}
|
||||
|
||||
bool fs_mgr_rm_all(const std::string& path, bool* change = nullptr, int level = 0) {
|
||||
auto save_errno = errno;
|
||||
std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(path.c_str()), closedir);
|
||||
if (!dir) {
|
||||
if (errno == ENOENT) {
|
||||
errno = save_errno;
|
||||
return true;
|
||||
}
|
||||
PERROR << "opendir " << path << " depth=" << level;
|
||||
if ((errno == EPERM) && (level != 0)) {
|
||||
errno = save_errno;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
dirent* entry;
|
||||
auto ret = true;
|
||||
while ((entry = readdir(dir.get()))) {
|
||||
if (("."s == entry->d_name) || (".."s == entry->d_name)) continue;
|
||||
auto file = path + "/" + entry->d_name;
|
||||
if (entry->d_type == DT_UNKNOWN) {
|
||||
struct stat st;
|
||||
save_errno = errno;
|
||||
if (!lstat(file.c_str(), &st) && (st.st_mode & S_IFDIR)) entry->d_type = DT_DIR;
|
||||
errno = save_errno;
|
||||
}
|
||||
if (entry->d_type == DT_DIR) {
|
||||
ret &= fs_mgr_rm_all(file, change, level + 1);
|
||||
if (!rmdir(file.c_str())) {
|
||||
if (change) *change = true;
|
||||
} else {
|
||||
if (errno != ENOENT) ret = false;
|
||||
PERROR << "rmdir " << file << " depth=" << level;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (!unlink(file.c_str())) {
|
||||
if (change) *change = true;
|
||||
} else {
|
||||
if (errno != ENOENT) ret = false;
|
||||
PERROR << "rm " << file << " depth=" << level;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
const auto kUpperName = "upper"s;
|
||||
|
@ -235,7 +286,7 @@ std::vector<std::string> fs_mgr_overlayfs_verity_enabled_list() {
|
|||
return ret;
|
||||
}
|
||||
|
||||
bool fs_mgr_wants_overlayfs(const fstab_rec* fsrec) {
|
||||
bool fs_mgr_wants_overlayfs(fstab_rec* fsrec) {
|
||||
if (!fsrec) return false;
|
||||
|
||||
auto fsrec_mount_point = fsrec->mount_point;
|
||||
|
@ -260,53 +311,6 @@ bool fs_mgr_wants_overlayfs(const fstab_rec* fsrec) {
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool fs_mgr_rm_all(const std::string& path, bool* change = nullptr, int level = 0) {
|
||||
auto save_errno = errno;
|
||||
std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(path.c_str()), closedir);
|
||||
if (!dir) {
|
||||
if (errno == ENOENT) {
|
||||
errno = save_errno;
|
||||
return true;
|
||||
}
|
||||
PERROR << "opendir " << path << " depth=" << level;
|
||||
if ((errno == EPERM) && (level != 0)) {
|
||||
errno = save_errno;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
dirent* entry;
|
||||
auto ret = true;
|
||||
while ((entry = readdir(dir.get()))) {
|
||||
if (("."s == entry->d_name) || (".."s == entry->d_name)) continue;
|
||||
auto file = path + "/" + entry->d_name;
|
||||
if (entry->d_type == DT_UNKNOWN) {
|
||||
struct stat st;
|
||||
save_errno = errno;
|
||||
if (!lstat(file.c_str(), &st) && (st.st_mode & S_IFDIR)) entry->d_type = DT_DIR;
|
||||
errno = save_errno;
|
||||
}
|
||||
if (entry->d_type == DT_DIR) {
|
||||
ret &= fs_mgr_rm_all(file, change, level + 1);
|
||||
if (!rmdir(file.c_str())) {
|
||||
if (change) *change = true;
|
||||
} else {
|
||||
if (errno != ENOENT) ret = false;
|
||||
PERROR << "rmdir " << file << " depth=" << level;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (!unlink(file.c_str())) {
|
||||
if (change) *change = true;
|
||||
} else {
|
||||
if (errno != ENOENT) ret = false;
|
||||
PERROR << "rm " << file << " depth=" << level;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
constexpr char kOverlayfsFileContext[] = "u:object_r:overlayfs_file:s0";
|
||||
|
||||
bool fs_mgr_overlayfs_setup_dir(const std::string& dir, std::string* overlay, bool* change) {
|
||||
|
@ -532,8 +536,7 @@ bool fs_mgr_overlayfs_mount(const std::string& mount_point) {
|
|||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> fs_mgr_candidate_list(const fstab* fstab,
|
||||
const char* mount_point = nullptr) {
|
||||
std::vector<std::string> fs_mgr_candidate_list(fstab* fstab, const char* mount_point = nullptr) {
|
||||
std::vector<std::string> mounts;
|
||||
if (!fstab) return mounts;
|
||||
|
||||
|
@ -734,7 +737,7 @@ bool fs_mgr_overlayfs_scratch_can_be_mounted(const std::string& scratch_device)
|
|||
|
||||
} // namespace
|
||||
|
||||
bool fs_mgr_overlayfs_mount_all(const fstab* fstab) {
|
||||
bool fs_mgr_overlayfs_mount_all(fstab* fstab) {
|
||||
auto ret = false;
|
||||
|
||||
if (!fs_mgr_wants_overlayfs()) return ret;
|
||||
|
@ -761,7 +764,7 @@ bool fs_mgr_overlayfs_mount_all(const fstab* fstab) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
std::vector<std::string> fs_mgr_overlayfs_required_devices(const fstab* fstab) {
|
||||
std::vector<std::string> fs_mgr_overlayfs_required_devices(fstab* fstab) {
|
||||
if (fs_mgr_get_entry_for_mount_point(const_cast<struct fstab*>(fstab), kScratchMountPoint)) {
|
||||
return {};
|
||||
}
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
bool fs_mgr_overlayfs_mount_all(const fstab* fstab);
|
||||
std::vector<std::string> fs_mgr_overlayfs_required_devices(const fstab* fstab);
|
||||
bool fs_mgr_overlayfs_mount_all(fstab* fstab);
|
||||
std::vector<std::string> fs_mgr_overlayfs_required_devices(fstab* fstab);
|
||||
bool fs_mgr_overlayfs_setup(const char* backing = nullptr, const char* mount_point = nullptr,
|
||||
bool* change = nullptr);
|
||||
bool fs_mgr_overlayfs_teardown(const char* mount_point = nullptr, bool* change = nullptr);
|
||||
|
|
|
@ -1,14 +1,21 @@
|
|||
#! /bin/bash
|
||||
#
|
||||
# adb remount tests (overlayfs focus)
|
||||
#
|
||||
# Conditions:
|
||||
# - Must be a userdebug build.
|
||||
# - Must be in adb mode.
|
||||
# - Kernel must have overlayfs enabled and patched to support override_creds.
|
||||
# - Must have either squashfs, ext4-dedupe or right-sized partitions.
|
||||
# - Minimum expectation system and vender are overlayfs covered partitions.
|
||||
#
|
||||
|
||||
USAGE="USAGE: `basename ${0}` [-s <SerialNumber>]
|
||||
|
||||
adb remount tests (overlayfs focus)
|
||||
|
||||
Conditions:
|
||||
- Must be a userdebug build.
|
||||
- Must be in adb mode.
|
||||
- Kernel must have overlayfs enabled and patched to support override_creds.
|
||||
- Must have either squashfs, ext4-dedupe or right-sized partitions.
|
||||
- Minimum expectation system and vender are overlayfs covered partitions.
|
||||
"
|
||||
|
||||
if [ X"${1}" = X"--help" -o X"${1}" = X"-h" -o X"${1}" = X"-?" ]; then
|
||||
echo "${USAGE}" >&2
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Helper Variables
|
||||
|
||||
|
@ -86,11 +93,15 @@ adb_reboot() {
|
|||
adb reboot remount-test
|
||||
}
|
||||
|
||||
[ "USAGE: adb_wait
|
||||
[ "USAGE: adb_wait [timeout]
|
||||
|
||||
Returns: waits until the device has returned" ]
|
||||
Returns: waits until the device has returned or the optional timeout" ]
|
||||
adb_wait() {
|
||||
adb wait-for-device
|
||||
if [ -n "${1}" ]; then
|
||||
timeout --preserve-status --signal=KILL ${1} adb wait-for-device
|
||||
else
|
||||
adb wait-for-device
|
||||
fi
|
||||
}
|
||||
|
||||
[ "USAGE: adb_root
|
||||
|
@ -178,6 +189,10 @@ if [ X"-s" = X"${1}" -a -n "${2}" ]; then
|
|||
fi
|
||||
|
||||
inFastboot && die "device in fastboot mode"
|
||||
if ! inAdb; then
|
||||
echo "${ORANGE}[ WARNING ]${NORMAL} device not in adb mode ... waiting 2 minutes"
|
||||
adb_wait 2m
|
||||
fi
|
||||
inAdb || die "device not in adb mode"
|
||||
isDebuggable || die "device not a debug build"
|
||||
|
||||
|
@ -205,8 +220,9 @@ adb_sh ls -d /cache/overlay </dev/null >/dev/null 2>&1 ||
|
|||
adb_reboot &&
|
||||
adb_wait &&
|
||||
adb_sh df -k </dev/null | head -1 &&
|
||||
adb_sh df -k </dev/null | grep "^overlay " &&
|
||||
adb_sh df -k </dev/null | grep "^overlay .* /system\$" >/dev/null ||
|
||||
adb_sh df -k </dev/null | grep "^overlay " ||
|
||||
die "overlay takeover failed"
|
||||
adb_sh df -k </dev/null | grep "^overlay .* /system\$" >/dev/null ||
|
||||
echo "${ORANGE}[ WARNING ]${NORMAL} overlay takeover before remount not complete" >&2
|
||||
|
||||
adb_root &&
|
||||
|
|
Loading…
Reference in a new issue