From d838dde6aa27bc137855313798988d70f4305adf Mon Sep 17 00:00:00 2001 From: Yi-Yo Chiang Date: Sat, 22 Jul 2023 01:41:10 +0800 Subject: [PATCH] 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 --- fs_mgr/fs_mgr.cpp | 45 ++++++++++++++++--------------- fs_mgr/fs_mgr_overlayfs_mount.cpp | 22 ++------------- fs_mgr/fs_mgr_priv.h | 14 +++++----- fs_mgr/fs_mgr_vendor_overlay.cpp | 8 +++--- 4 files changed, 35 insertions(+), 54 deletions(-) diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp index e568a9bd6..d55f8d3bf 100644 --- a/fs_mgr/fs_mgr.cpp +++ b/fs_mgr/fs_mgr.cpp @@ -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 diff --git a/fs_mgr/fs_mgr_overlayfs_mount.cpp b/fs_mgr/fs_mgr_overlayfs_mount.cpp index 37e30585a..8fb63b174 100644 --- a/fs_mgr/fs_mgr_overlayfs_mount.cpp +++ b/fs_mgr/fs_mgr_overlayfs_mount.cpp @@ -23,7 +23,6 @@ #include #include #include -#include #include #include @@ -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"; } diff --git a/fs_mgr/fs_mgr_priv.h b/fs_mgr/fs_mgr_priv.h index 678dd69cb..12a4a6d7f 100644 --- a/fs_mgr/fs_mgr_priv.h +++ b/fs_mgr/fs_mgr_priv.h @@ -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 diff --git a/fs_mgr/fs_mgr_vendor_overlay.cpp b/fs_mgr/fs_mgr_vendor_overlay.cpp index 6b32b4d6f..bacfa4b59 100644 --- a/fs_mgr/fs_mgr_vendor_overlay.cpp +++ b/fs_mgr/fs_mgr_vendor_overlay.cpp @@ -85,10 +85,8 @@ bool fs_mgr_vendor_overlay_mount(const std::pair& 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; }