switch-root: when switching root via MS_MOVE unmount all remaining mounts first

Let's try to unmount anything left, since if we don't they will remain
as "shadow" mounts, hidden underneath our new root.

This is only necessary when we transition into a new root via MS_MOVE.
If we do so via pivot_root() this is not necessary as the kernel will
get rid of the mounts anyway for us.
This commit is contained in:
Lennart Poettering
2023-05-15 21:25:12 +02:00
parent 4e9ef660e6
commit 268d1244e8

View File

@@ -114,6 +114,14 @@ int switch_root(const char *new_root,
if (r < 0) {
log_debug_errno(r, "Pivoting root file system failed, moving mounts instead: %m");
/* If we have to use MS_MOVE let's first try to get rid of *all* mounts we can, with the
* exception of the path we want to switch to, plus everything leading to it and within
* it. This is necessary because unlike pivot_root() just moving the mount to the root via
* MS_MOVE won't magically unmount anything below it. Once the chroot() succeeds the mounts
* below would still be around but invisible to us, because not accessible via
* /proc/self/mountinfo. Hence, let's clean everything up first, as long as we still can. */
(void) umount_recursive_full(NULL, MNT_DETACH, STRV_MAKE(new_root));
if (mount(".", "/", NULL, MS_MOVE, NULL) < 0)
return log_error_errno(errno, "Failed to move %s to /: %m", new_root);