fs_mgr: Refactor mandatory overlayfs kernel patch checks

The check result can just return the exact mount flags to use, this
reduces code duplication at the caller's side.

Bug: 293695109
Test: adb-remount-test
Change-Id: I9b5c918968f2494c0c1be3cb8d8e6b527a9c4eb2
This commit is contained in:
Yi-Yo Chiang 2023-07-22 01:41:10 +08:00
parent f6dc8ee31e
commit d838dde6aa
4 changed files with 35 additions and 54 deletions

View file

@ -2227,8 +2227,8 @@ bool fs_mgr_create_canonical_mount_point(const std::string& mount_point) {
}
bool fs_mgr_mount_overlayfs_fstab_entry(const FstabEntry& entry) {
auto overlayfs_valid_result = fs_mgr_overlayfs_valid();
if (overlayfs_valid_result == OverlayfsValidResult::kNotSupported) {
const auto overlayfs_check_result = android::fs_mgr::CheckOverlayfs();
if (!overlayfs_check_result.supported) {
LERROR << __FUNCTION__ << "(): kernel does not support overlayfs";
return false;
}
@ -2280,10 +2280,7 @@ bool fs_mgr_mount_overlayfs_fstab_entry(const FstabEntry& entry) {
}
}
auto options = "lowerdir=" + lowerdir;
if (overlayfs_valid_result == OverlayfsValidResult::kOverrideCredsRequired) {
options += ",override_creds=off";
}
const auto options = "lowerdir=" + lowerdir + overlayfs_check_result.mount_flags;
// Use "overlay-" + entry.blk_device as the mount() source, so that adb-remout-test don't
// confuse this with adb remount overlay, whose device name is "overlay".
@ -2339,30 +2336,34 @@ std::string fs_mgr_get_context(const std::string& mount_point) {
return context;
}
OverlayfsValidResult fs_mgr_overlayfs_valid() {
// Overlayfs available in the kernel, and patched for override_creds?
if (access("/sys/module/overlay/parameters/override_creds", F_OK) == 0) {
return OverlayfsValidResult::kOverrideCredsRequired;
}
namespace android {
namespace fs_mgr {
OverlayfsCheckResult CheckOverlayfs() {
if (!fs_mgr_filesystem_available("overlay")) {
return OverlayfsValidResult::kNotSupported;
return {.supported = false};
}
struct utsname uts;
if (uname(&uts) == -1) {
return OverlayfsValidResult::kNotSupported;
return {.supported = false};
}
int major, minor;
if (sscanf(uts.release, "%d.%d", &major, &minor) != 2) {
return OverlayfsValidResult::kNotSupported;
return {.supported = false};
}
if (major < 4) {
return OverlayfsValidResult::kOk;
// Overlayfs available in the kernel, and patched for override_creds?
if (access("/sys/module/overlay/parameters/override_creds", F_OK) == 0) {
auto mount_flags = ",override_creds=off"s;
if (major > 5 || (major == 5 && minor >= 15)) {
mount_flags += ",userxattr"s;
}
return {.supported = true, .mount_flags = mount_flags};
}
if (major > 4) {
return OverlayfsValidResult::kNotSupported;
if (major < 4 || (major == 4 && minor <= 3)) {
return {.supported = true};
}
if (minor > 3) {
return OverlayfsValidResult::kNotSupported;
}
return OverlayfsValidResult::kOk;
return {.supported = false};
}
} // namespace fs_mgr
} // namespace android

View file

@ -23,7 +23,6 @@
#include <sys/stat.h>
#include <sys/statvfs.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <sys/vfs.h>
#include <unistd.h>
@ -218,17 +217,6 @@ static std::string fs_mgr_get_overlayfs_candidate(const std::string& mount_point
return "";
}
static inline bool KernelSupportsUserXattrs() {
struct utsname uts;
uname(&uts);
int major, minor;
if (sscanf(uts.release, "%d.%d", &major, &minor) != 2) {
return false;
}
return major > 5 || (major == 5 && minor >= 15);
}
const std::string fs_mgr_mount_point(const std::string& mount_point) {
if ("/"s != mount_point) return mount_point;
return "/system";
@ -240,13 +228,7 @@ static std::string fs_mgr_get_overlayfs_options(const FstabEntry& entry) {
auto candidate = fs_mgr_get_overlayfs_candidate(mount_point);
if (candidate.empty()) return "";
auto ret = kLowerdirOption + mount_point + "," + kUpperdirOption + candidate + kUpperName +
",workdir=" + candidate + kWorkName;
if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kOverrideCredsRequired) {
ret += ",override_creds=off";
}
if (KernelSupportsUserXattrs()) {
ret += ",userxattr";
}
",workdir=" + candidate + kWorkName + android::fs_mgr::CheckOverlayfs().mount_flags;
for (const auto& flag : android::base::Split(entry.fs_options, ",")) {
if (android::base::StartsWith(flag, "context=")) {
ret += "," + flag;
@ -608,7 +590,7 @@ bool OverlayfsSetupAllowed(bool verbose) {
return false;
}
// Check mandatory kernel patches.
if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kNotSupported) {
if (!android::fs_mgr::CheckOverlayfs().supported) {
if (verbose) {
LOG(ERROR) << "Kernel does not support overlayfs";
}

View file

@ -100,18 +100,18 @@ bool fs_mgr_is_f2fs(const std::string& blk_device);
bool fs_mgr_filesystem_available(const std::string& filesystem);
std::string fs_mgr_get_context(const std::string& mount_point);
enum class OverlayfsValidResult {
kNotSupported = 0,
kOk,
kOverrideCredsRequired,
};
OverlayfsValidResult fs_mgr_overlayfs_valid();
namespace android {
namespace fs_mgr {
bool UnmapDevice(const std::string& name);
bool InRecovery();
struct OverlayfsCheckResult {
bool supported;
std::string mount_flags;
};
OverlayfsCheckResult CheckOverlayfs();
} // namespace fs_mgr
} // namespace android

View file

@ -85,10 +85,8 @@ bool fs_mgr_vendor_overlay_mount(const std::pair<std::string, std::string>& moun
return false;
}
auto options = kLowerdirOption + source_directory + ":" + vendor_mount_point;
if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kOverrideCredsRequired) {
options += ",override_creds=off";
}
const auto options = kLowerdirOption + source_directory + ":" + vendor_mount_point +
android::fs_mgr::CheckOverlayfs().mount_flags;
auto report = "__mount(source=overlay,target="s + vendor_mount_point + ",type=overlay," +
options + ")=";
auto ret = mount("overlay", vendor_mount_point.c_str(), "overlay", MS_RDONLY | MS_NOATIME,
@ -120,7 +118,7 @@ bool fs_mgr_vendor_overlay_mount_all() {
const auto vendor_overlay_dirs = fs_mgr_get_vendor_overlay_dirs(vndk_version);
if (vendor_overlay_dirs.empty()) return true;
if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kNotSupported) {
if (!android::fs_mgr::CheckOverlayfs().supported) {
LINFO << "vendor overlay: kernel does not support overlayfs";
return false;
}