fs_mgr_overlayfs: Fix "/" mount propagation type after remount
If remounting "/system" caused "/" to be set to MS_PRIVATE, restore it
to MS_SHARED after remount.
Bug: 306124139
Test: adb-remount-test
Test: remount /system and verify /proc/self/mountinfo
Change-Id: I12bc2ccdaf7d2b2de330064b61a8533b96defe00
diff --git a/fs_mgr/fs_mgr_overlayfs_mount.cpp b/fs_mgr/fs_mgr_overlayfs_mount.cpp
index 4cadeec..cdbac00 100644
--- a/fs_mgr/fs_mgr_overlayfs_mount.cpp
+++ b/fs_mgr/fs_mgr_overlayfs_mount.cpp
@@ -288,10 +288,6 @@
if (ret) {
PERROR << "__mount(target=" << mount_point
<< ",flag=" << (shared_flag ? "MS_SHARED" : "MS_PRIVATE") << ")=" << ret;
- // If "/system" doesn't look like a mountpoint, retry with "/".
- if (errno == EINVAL && mount_point == "/system") {
- return fs_mgr_overlayfs_set_shared_mount("/", shared_flag);
- }
return false;
}
return true;
@@ -393,6 +389,8 @@
bool retval = true;
bool move_dir_shared = true;
bool parent_shared = true;
+ bool root_shared = true;
+ bool root_made_private = false;
// There could be multiple mount entries with the same mountpoint.
// Group these entries together with stable_sort, and keep only the last entry of a group.
@@ -419,6 +417,9 @@
(mount_point == "/system" && entry.mount_point == "/")) {
parent_shared = entry.shared_flag;
}
+ if (entry.mount_point == "/") {
+ root_shared = entry.shared_flag;
+ }
}
// Precondition is that kMoveMountTempDir is MS_PRIVATE, otherwise don't try to move any
@@ -429,7 +430,13 @@
// Need to make the original mountpoint MS_PRIVATE, so that the overlayfs can be MS_MOVE.
// This could happen if its parent mount is remounted later.
- fs_mgr_overlayfs_set_shared_mount(mount_point, false);
+ if (!fs_mgr_overlayfs_set_shared_mount(mount_point, false)) {
+ // If failed to set "/system" mount type, it might be due to "/system" not being a valid
+ // mountpoint after switch root. Retry with "/" in this case.
+ if (errno == EINVAL && mount_point == "/system") {
+ root_made_private = fs_mgr_overlayfs_set_shared_mount("/", false);
+ }
+ }
for (const auto& entry : mountinfo) {
// Find all immediate submounts.
@@ -515,6 +522,9 @@
if (parent_shared) {
fs_mgr_overlayfs_set_shared_mount(mount_point, true);
}
+ if (root_shared && root_made_private) {
+ fs_mgr_overlayfs_set_shared_mount("/", true);
+ }
return retval;
}