[CRIU] [PATCH 2/2] mount: don't clean up propogation options for the root mount (v2)

Andrey Vagin avagin at openvz.org
Thu Mar 20 05:45:46 PDT 2014


Currently we marks all mounts as private before restoring mntns. We do
these to avoid problem with pivot_root.
It's wrong, because the root mount can be slave for an external shared
group. The root mount is not mounted by CRIU, so here is nothing wrong.

Now look at the pivot_root code in kernel
if (IS_MNT_SHARED(old_mnt) ||
	IS_MNT_SHARED(new_mnt->mnt_parent) ||
	IS_MNT_SHARED(root_mnt->mnt_parent))
	goto out4;

So we don't need to change options for all mounts. We need to remount
/ and the parent of the new root. It's safe, because we already in another
mntns.

v2: simplify code

Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
 mount.c | 40 +++++++++++++++++++++++++++++++++-------
 1 file changed, 33 insertions(+), 7 deletions(-)

diff --git a/mount.c b/mount.c
index afead1a..2a6f398 100644
--- a/mount.c
+++ b/mount.c
@@ -1238,6 +1238,11 @@ static int cr_pivot_root(void)
 		return -1;
 	}
 
+	if (mount("none", put_root, "none", MS_REC|MS_PRIVATE, NULL)) {
+		pr_perror("Can't remount root with MS_PRIVATE");
+		return -1;
+	}
+
 	if (umount2(put_root, MNT_DETACH)) {
 		pr_perror("Can't umount %s", put_root);
 		return -1;
@@ -1411,11 +1416,6 @@ int prepare_mnt_ns(int ns_pid)
 	if (!mis)
 		goto out;
 
-	if (mount("none", "/", "none", MS_REC|MS_PRIVATE, NULL)) {
-		pr_perror("Can't remount root with MS_PRIVATE");
-		return -1;
-	}
-
 	if (chdir(opts.root ? : "/")) {
 		pr_perror("chdir(%s) failed", opts.root ? : "/");
 		return -1;
@@ -1426,8 +1426,34 @@ int prepare_mnt_ns(int ns_pid)
 	 * clones from the original one. We have to umount them
 	 * prior to recreating new ones.
 	 */
-	if (!opts.root && clean_mnt_ns())
-		return -1;
+	if (!opts.root) {
+		if (clean_mnt_ns())
+			return -1;
+	} else {
+		struct mount_info *mi;
+
+		/* moving a mount residing under a shared mount is invalid. */
+		mi = mount_resolve_path(opts.root);
+		if (mi == NULL) {
+			pr_err("Unable to find mount point for %s\n", opts.root);
+			return -1;
+		}
+		if (mi->parent == NULL) {
+			pr_err("New root and old root are the same\n");
+			return -1;
+		}
+
+		/* Our root is mounted over the parent (in the same directory) */
+		if (!strcmp(mi->parent->mountpoint, mi->mountpoint)) {
+			pr_err("The parent of the new root is unreachable\n");
+			return -1;
+		}
+
+		if (mount("none", mi->parent->mountpoint, "none", MS_SLAVE, NULL)) {
+			pr_perror("Can't remount the parent of the new root with MS_SLAVE");
+			return -1;
+		}
+	}
 
 	free_mounts();
 
-- 
1.8.5.3



More information about the CRIU mailing list