diff --git a/fs_mgr/fs_mgr_overlayfs_control.cpp b/fs_mgr/fs_mgr_overlayfs_control.cpp index 69a2ac028..c9a8997f6 100644 --- a/fs_mgr/fs_mgr_overlayfs_control.cpp +++ b/fs_mgr/fs_mgr_overlayfs_control.cpp @@ -71,15 +71,18 @@ namespace { constexpr char kDataScratchSizeMbProp[] = "fs_mgr.overlayfs.data_scratch_size_mb"; +constexpr char kPhysicalDevice[] = "/dev/block/by-name/"; +constexpr char kScratchImageMetadata[] = "/metadata/gsi/remount/lp_metadata"; + +constexpr char kMkF2fs[] = "/system/bin/make_f2fs"; +constexpr char kMkExt4[] = "/system/bin/mke2fs"; + // Return true if everything is mounted, but before adb is started. Right // after 'trigger load_persist_props_action' is done. static bool fs_mgr_boot_completed() { return android::base::GetBoolProperty("ro.persistent_properties.ready", false); } -constexpr auto kPhysicalDevice = "/dev/block/by-name/"; -constexpr char kScratchImageMetadata[] = "/metadata/gsi/remount/lp_metadata"; - // Note: this is meant only for recovery/first-stage init. static bool ScratchIsOnData() { // The scratch partition of DSU is managed by gsid. @@ -131,7 +134,7 @@ static bool fs_mgr_rm_all(const std::string& path, bool* change = nullptr, int l } std::string fs_mgr_overlayfs_setup_dir(const std::string& dir) { - auto top = dir + kOverlayTopDir; + auto top = dir + "/" + kOverlayTopDir; AutoSetFsCreateCon createcon(kOverlayfsFileContext); if (!createcon.Ok()) { @@ -290,7 +293,7 @@ OverlayfsTeardownResult fs_mgr_overlayfs_teardown_scratch(const std::string& ove bool fs_mgr_overlayfs_teardown_one(const std::string& overlay, const std::string& mount_point, bool* change, bool* should_destroy_scratch = nullptr) { - const auto top = overlay + kOverlayTopDir; + const auto top = overlay + "/" + kOverlayTopDir; if (!fs_mgr_access(top)) { if (should_destroy_scratch) *should_destroy_scratch = true; @@ -300,7 +303,7 @@ bool fs_mgr_overlayfs_teardown_one(const std::string& overlay, const std::string auto cleanup_all = mount_point.empty(); const auto partition_name = android::base::Basename(mount_point); const auto oldpath = top + (cleanup_all ? "" : ("/" + partition_name)); - const auto newpath = cleanup_all ? overlay + "/." + (kOverlayTopDir + 1) + ".teardown" + const auto newpath = cleanup_all ? overlay + "/." + kOverlayTopDir + ".teardown" : top + "/." + partition_name + ".teardown"; auto ret = fs_mgr_rm_all(newpath); if (!rename(oldpath.c_str(), newpath.c_str())) { @@ -346,72 +349,6 @@ bool fs_mgr_overlayfs_teardown_one(const std::string& overlay, const std::string return ret; } -// Mount kScratchMountPoint -bool MountScratch(const std::string& device_path, bool readonly = false) { - if (readonly) { - if (!fs_mgr_access(device_path)) { - LOG(ERROR) << "Path does not exist: " << device_path; - return false; - } - } else if (!fs_mgr_rw_access(device_path)) { - LOG(ERROR) << "Path does not exist or is not readwrite: " << device_path; - return false; - } - - std::vector filesystem_candidates; - if (fs_mgr_is_f2fs(device_path)) { - filesystem_candidates = {"f2fs", "ext4"}; - } else if (fs_mgr_is_ext4(device_path)) { - filesystem_candidates = {"ext4", "f2fs"}; - } else { - LOG(ERROR) << "Scratch partition is not f2fs or ext4"; - return false; - } - - AutoSetFsCreateCon createcon(kOverlayfsFileContext); - if (!createcon.Ok()) { - return false; - } - if (mkdir(kScratchMountPoint, 0755) && (errno != EEXIST)) { - PERROR << "create " << kScratchMountPoint; - return false; - } - - FstabEntry entry; - entry.blk_device = device_path; - entry.mount_point = kScratchMountPoint; - entry.flags = MS_NOATIME | MS_RDONLY; - if (!readonly) { - entry.flags &= ~MS_RDONLY; - entry.flags |= MS_SYNCHRONOUS; - entry.fs_options = "nodiscard"; - fs_mgr_set_blk_ro(device_path, false); - } - // check_fs requires apex runtime library - if (fs_mgr_overlayfs_already_mounted("/data", false)) { - entry.fs_mgr_flags.check = true; - } - bool mounted = false; - for (auto fs_type : filesystem_candidates) { - entry.fs_type = fs_type; - if (fs_mgr_do_mount_one(entry) == 0) { - mounted = true; - break; - } - } - if (!createcon.Restore()) { - return false; - } - if (!mounted) { - rmdir(kScratchMountPoint); - return false; - } - return true; -} - -const std::string kMkF2fs("/system/bin/make_f2fs"); -const std::string kMkExt4("/system/bin/mke2fs"); - // Note: The scratch partition of DSU is managed by gsid, and should be initialized during // first-stage-mount. Just check if the DM device for DSU scratch partition is created or not. static std::string GetDsuScratchDevice() { @@ -456,14 +393,14 @@ bool MakeScratchFilesystem(const std::string& scratch_device) { // thus do not rely on fsck to correct problems that could creep in. auto fs_type = ""s; auto command = ""s; - if (!access(kMkF2fs.c_str(), X_OK) && fs_mgr_filesystem_available("f2fs")) { + if (!access(kMkF2fs, X_OK) && fs_mgr_filesystem_available("f2fs")) { fs_type = "f2fs"; - command = kMkF2fs + " -w "; + command = kMkF2fs + " -w "s; command += std::to_string(getpagesize()); command += " -f -d1 -l" + android::base::Basename(kScratchMountPoint); - } else if (!access(kMkExt4.c_str(), X_OK) && fs_mgr_filesystem_available("ext4")) { + } else if (!access(kMkExt4, X_OK) && fs_mgr_filesystem_available("ext4")) { fs_type = "ext4"; - command = kMkExt4 + " -F -b 4096 -t ext4 -m 0 -O has_journal -M " + kScratchMountPoint; + command = kMkExt4 + " -F -b 4096 -t ext4 -m 0 -O has_journal -M "s + kScratchMountPoint; } else { LERROR << "No supported mkfs command or filesystem driver available, supported filesystems " "are: f2fs, ext4"; @@ -697,7 +634,7 @@ bool fs_mgr_overlayfs_setup_scratch(const Fstab& fstab) { // If the partition exists, assume first that it can be mounted. if (partition_exists) { if (MountScratch(scratch_device)) { - if (fs_mgr_access(std::string(kScratchMountPoint) + kOverlayTopDir) || + if (fs_mgr_access(kScratchMountPoint + "/"s + kOverlayTopDir) || fs_mgr_filesystem_has_space(kScratchMountPoint)) { return true; } @@ -717,32 +654,6 @@ bool fs_mgr_overlayfs_setup_scratch(const Fstab& fstab) { return MountScratch(scratch_device); } -// NOTE: OverlayfsSetupAllowed() must be "stricter" than OverlayfsTeardownAllowed(). -// Setup is allowed only if teardown is also allowed. -bool OverlayfsSetupAllowed(bool verbose = false) { - if (!kAllowOverlayfs) { - if (verbose) { - LOG(ERROR) << "Overlayfs remounts can only be used in debuggable builds"; - } - return false; - } - // Check mandatory kernel patches. - if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kNotSupported) { - if (verbose) { - LOG(ERROR) << "Kernel does not support overlayfs"; - } - return false; - } - // in recovery or fastbootd, not allowed! - if (fs_mgr_in_recovery()) { - if (verbose) { - LOG(ERROR) << "Unsupported overlayfs setup from recovery"; - } - return false; - } - return true; -} - constexpr bool OverlayfsTeardownAllowed() { // Never allow on non-debuggable build. return kAllowOverlayfs; diff --git a/fs_mgr/fs_mgr_overlayfs_mount.cpp b/fs_mgr/fs_mgr_overlayfs_mount.cpp index c057c2bc1..e380f8401 100644 --- a/fs_mgr/fs_mgr_overlayfs_mount.cpp +++ b/fs_mgr/fs_mgr_overlayfs_mount.cpp @@ -62,13 +62,16 @@ using namespace android::storage_literals; constexpr char kPreferCacheBackingStorageProp[] = "fs_mgr.overlayfs.prefer_cache_backing_storage"; +constexpr char kCacheMountPoint[] = "/cache"; +constexpr char kPhysicalDevice[] = "/dev/block/by-name/"; + +constexpr char kLowerdirOption[] = "lowerdir="; +constexpr char kUpperdirOption[] = "upperdir="; + bool fs_mgr_access(const std::string& path) { return access(path.c_str(), F_OK) == 0; } -const auto kLowerdirOption = "lowerdir="; -const auto kUpperdirOption = "upperdir="; - bool fs_mgr_in_recovery() { // Check the existence of recovery binary instead of using the compile time // __ANDROID_RECOVERY__ macro. @@ -89,8 +92,6 @@ bool fs_mgr_is_dsu_running() { return android::gsi::IsGsiRunning(); } -const auto kCacheMountPoint = "/cache"; - static bool IsABDevice() { return !android::base::GetProperty("ro.boot.slot_suffix", "").empty(); } @@ -141,8 +142,6 @@ bool fs_mgr_filesystem_has_space(const std::string& mount_point) { (static_cast(vst.f_bfree) * vst.f_frsize) >= kSizeThreshold; } -const auto kPhysicalDevice = "/dev/block/by-name/"; - static bool fs_mgr_update_blk_device(FstabEntry* entry) { if (entry->fs_mgr_flags.logical) { fs_mgr_update_logical_partition(entry); @@ -155,7 +154,7 @@ static bool fs_mgr_update_blk_device(FstabEntry* entry) { } // special case for system-as-root (taimen and others) - auto blk_device = std::string(kPhysicalDevice) + "system"; + auto blk_device = kPhysicalDevice + "system"s; if (!fs_mgr_access(blk_device)) { blk_device += fs_mgr_get_slot_suffix(); if (!fs_mgr_access(blk_device)) { @@ -237,7 +236,7 @@ static std::string fs_mgr_get_overlayfs_candidate(const std::string& mount_point if (!fs_mgr_is_dir(mount_point)) return ""; const auto base = android::base::Basename(mount_point) + "/"; for (const auto& overlay_mount_point : OverlayMountPoints()) { - auto dir = overlay_mount_point + kOverlayTopDir + "/" + base; + auto dir = overlay_mount_point + "/" + kOverlayTopDir + "/" + base; auto upper = dir + kUpperName; if (!fs_mgr_is_dir(upper)) continue; auto work = dir + kWorkName; @@ -527,7 +526,7 @@ static bool fs_mgr_overlayfs_mount(const FstabEntry& entry) { } // Mount kScratchMountPoint -static bool MountScratch(const std::string& device_path, bool readonly = false) { +bool MountScratch(const std::string& device_path, bool readonly) { if (readonly) { if (!fs_mgr_access(device_path)) { LOG(ERROR) << "Path does not exist: " << device_path; @@ -589,9 +588,6 @@ static bool MountScratch(const std::string& device_path, bool readonly = false) return true; } -const std::string kMkF2fs("/system/bin/make_f2fs"); -const std::string kMkExt4("/system/bin/mke2fs"); - // Note: The scratch partition of DSU is managed by gsid, and should be initialized during // first-stage-mount. Just check if the DM device for DSU scratch partition is created or not. static std::string GetDsuScratchDevice() { @@ -633,7 +629,7 @@ static std::string GetBootScratchDevice() { // NOTE: OverlayfsSetupAllowed() must be "stricter" than OverlayfsTeardownAllowed(). // Setup is allowed only if teardown is also allowed. -bool OverlayfsSetupAllowed(bool verbose = false) { +bool OverlayfsSetupAllowed(bool verbose) { if (!kAllowOverlayfs) { if (verbose) { LOG(ERROR) << "Overlayfs remounts can only be used in debuggable builds"; @@ -737,7 +733,7 @@ static void TryMountScratch() { if (!MountScratch(scratch_device, true /* readonly */)) { return; } - auto has_overlayfs_dir = fs_mgr_access(std::string(kScratchMountPoint) + kOverlayTopDir); + auto has_overlayfs_dir = fs_mgr_access(kScratchMountPoint + "/"s + kOverlayTopDir); fs_mgr_overlayfs_umount_scratch(); if (has_overlayfs_dir) { MountScratch(scratch_device); diff --git a/fs_mgr/fs_mgr_overlayfs_mount.h b/fs_mgr/fs_mgr_overlayfs_mount.h index ae3ea84ed..d9a93d4ac 100644 --- a/fs_mgr/fs_mgr_overlayfs_mount.h +++ b/fs_mgr/fs_mgr_overlayfs_mount.h @@ -20,9 +20,12 @@ #include -bool fs_mgr_overlayfs_already_mounted(const std::string& mount_point, bool overlay_only = true); -bool fs_mgr_wants_overlayfs(android::fs_mgr::FstabEntry* entry); -android::fs_mgr::Fstab fs_mgr_overlayfs_candidate_list(const android::fs_mgr::Fstab& fstab); +constexpr char kOverlayfsFileContext[] = "u:object_r:overlayfs_file:s0"; + +constexpr char kScratchMountPoint[] = "/mnt/scratch"; +constexpr char kOverlayTopDir[] = "overlay"; +constexpr char kUpperName[] = "upper"; +constexpr char kWorkName[] = "work"; #if ALLOW_ADBD_DISABLE_VERITY constexpr bool kAllowOverlayfs = true; @@ -45,18 +48,16 @@ class AutoSetFsCreateCon final { bool restored_ = false; }; -constexpr auto kScratchMountPoint = "/mnt/scratch"; -constexpr char kOverlayfsFileContext[] = "u:object_r:overlayfs_file:s0"; - -constexpr auto kUpperName = "upper"; -constexpr auto kWorkName = "work"; -constexpr auto kOverlayTopDir = "/overlay"; - bool fs_mgr_is_dsu_running(); bool fs_mgr_in_recovery(); bool fs_mgr_access(const std::string& path); bool fs_mgr_rw_access(const std::string& path); bool fs_mgr_filesystem_has_space(const std::string& mount_point); const std::string fs_mgr_mount_point(const std::string& mount_point); +bool OverlayfsSetupAllowed(bool verbose = false); +bool MountScratch(const std::string& device_path, bool readonly = false); bool fs_mgr_overlayfs_umount_scratch(); std::vector OverlayMountPoints(); +bool fs_mgr_overlayfs_already_mounted(const std::string& mount_point, bool overlay_only = true); +bool fs_mgr_wants_overlayfs(android::fs_mgr::FstabEntry* entry); +android::fs_mgr::Fstab fs_mgr_overlayfs_candidate_list(const android::fs_mgr::Fstab& fstab);