From dcf1c1f46235637a6d1057c88e6d1fed88e1b90a Mon Sep 17 00:00:00 2001 From: Yi-Yo Chiang Date: Wed, 19 May 2021 16:25:34 +0800 Subject: [PATCH] fs_mgr_overlayfs: Polish fs_mgr_overlayfs_mount_fstab_entry() * Add logs. * Append "override_creds=off" overlayfs mount flag only if fs_mgr_overlayfs_valid() returns kOverrideCredsRequired. Pre-4.6 kernels or kernels without the override_creds patch don't need or don't recognize the override_creds mount flag. (Background: I832c8ca3fce0269bdef4ce988541adb7ba9662ed) * mkdir(mount_point) before mount() to ensure the mount point exists. This could happen if the mount point is in a tmpfs, such as /mnt. Bug: 186342252 Test: Boot to normal with overlayfs mount entries in first stage fstab Change-Id: I1a05696346610d7fd61de6d25c379520fd58ca9b --- fs_mgr/fs_mgr_overlayfs.cpp | 28 +++++++++++++++++++++------- fs_mgr/include/fs_mgr_overlayfs.h | 2 +- init/first_stage_mount.cpp | 14 +++++++------- 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/fs_mgr/fs_mgr_overlayfs.cpp b/fs_mgr/fs_mgr_overlayfs.cpp index 9a94d7912..925d03f28 100644 --- a/fs_mgr/fs_mgr_overlayfs.cpp +++ b/fs_mgr/fs_mgr_overlayfs.cpp @@ -92,7 +92,7 @@ bool fs_mgr_overlayfs_mount_all(Fstab*) { return false; } -bool fs_mgr_overlayfs_mount_fstab_entry(const std::string&, const std::string&) { +bool fs_mgr_overlayfs_mount_fstab_entry(const android::fs_mgr::FstabEntry&) { return false; } @@ -1299,16 +1299,30 @@ static void TryMountScratch() { } } -bool fs_mgr_overlayfs_mount_fstab_entry(const std::string& lowers, - const std::string& mount_point) { +bool fs_mgr_overlayfs_mount_fstab_entry(const android::fs_mgr::FstabEntry& entry) { if (fs_mgr_overlayfs_invalid()) return false; - std::string aux = "lowerdir=" + lowers + ",override_creds=off"; - auto rc = mount("overlay", mount_point.c_str(), "overlay", MS_RDONLY | MS_NOATIME, aux.c_str()); + // Create the mount point in case it doesn't exist. + mkdir(entry.mount_point.c_str(), 0755); - if (rc == 0) return true; + auto options = kLowerdirOption + entry.lowerdir; + if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kOverrideCredsRequired) { + options += ",override_creds=off"; + } - return false; + // Use .blk_device as the mount() source for debugging purposes. + // Overlayfs is pseudo filesystem, so the source device is a symbolic value and isn't used to + // back the filesystem. /proc/mounts would show the source as the device name of the mount. + auto report = "__mount(source=" + entry.blk_device + ",target=" + entry.mount_point + + ",type=overlay," + options + ")="; + auto ret = mount(entry.blk_device.c_str(), entry.mount_point.c_str(), "overlay", + MS_RDONLY | MS_NOATIME, options.c_str()); + if (ret) { + PERROR << report << ret; + return false; + } + LINFO << report << ret; + return true; } bool fs_mgr_overlayfs_mount_all(Fstab* fstab) { diff --git a/fs_mgr/include/fs_mgr_overlayfs.h b/fs_mgr/include/fs_mgr_overlayfs.h index ac95ef519..22d12e753 100644 --- a/fs_mgr/include/fs_mgr_overlayfs.h +++ b/fs_mgr/include/fs_mgr_overlayfs.h @@ -27,7 +27,7 @@ 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); -bool fs_mgr_overlayfs_mount_fstab_entry (const std::string& lowers, const std::string& mount_point); +bool fs_mgr_overlayfs_mount_fstab_entry(const android::fs_mgr::FstabEntry& entry); std::vector fs_mgr_overlayfs_required_devices(android::fs_mgr::Fstab* fstab); bool fs_mgr_overlayfs_setup(const char* backing = nullptr, const char* mount_point = nullptr, bool* change = nullptr, bool force = true); diff --git a/init/first_stage_mount.cpp b/init/first_stage_mount.cpp index 87e23abc1..616d28540 100644 --- a/init/first_stage_mount.cpp +++ b/init/first_stage_mount.cpp @@ -542,6 +542,7 @@ bool FirstStageMount::MountPartitions() { continue; } + // Handle overlayfs entries later. if (current->fs_type == "overlay") { ++current; continue; @@ -571,6 +572,12 @@ bool FirstStageMount::MountPartitions() { current = end; } + for (const auto& entry : fstab_) { + if (entry.fs_type == "overlay") { + fs_mgr_overlayfs_mount_fstab_entry(entry); + } + } + // If we don't see /system or / in the fstab, then we need to create an root entry for // overlayfs. if (!GetEntryForMountPoint(&fstab_, "/system") && !GetEntryForMountPoint(&fstab_, "/")) { @@ -596,13 +603,6 @@ bool FirstStageMount::MountPartitions() { }; MapScratchPartitionIfNeeded(&fstab_, init_devices); - for (auto current = fstab_.begin(); current != fstab_.end(); ) { - if (current->fs_type == "overlay") { - fs_mgr_overlayfs_mount_fstab_entry(current->lowerdir, current->mount_point); - } - ++current; - } - fs_mgr_overlayfs_mount_all(&fstab_); return true;