[PATCH] mount: rework perparation for pivot_root

Andrey Vagin avagin at openvz.org
Fri Jul 25 05:22:06 PDT 2014


We can't bind-mount the required root into itself instead of
resolving a parent mount.

This patch is required to support userns, because if we want to make
pivot_root, the parent mount can't be locked. When we create userns
and mntns, all inherited mounts are marked as locked.

Cc: Tycho Andersen <tycho.andersen at canonical.com>
Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
 mount.c | 49 ++++++++++++++++++++++++-------------------------
 1 file changed, 24 insertions(+), 25 deletions(-)

diff --git a/mount.c b/mount.c
index 3287282..3612d02 100644
--- a/mount.c
+++ b/mount.c
@@ -1910,20 +1910,13 @@ int fini_mnt_ns(void)
 int prepare_mnt_ns(void)
 {
 	int ret = -1;
-	struct mount_info *mis, *old;
-	struct ns_id ns = { .pid = PROC_SELF, .nd = &mnt_ns_desc };
+	struct mount_info *mis;
 
 	if (!(root_ns_mask & CLONE_NEWNS))
 		return rst_collect_local_mntns();
 
 	pr_info("Restoring mount namespace\n");
 
-	old = collect_mntinfo(&ns);
-	if (old == NULL)
-		return -1;
-
-	close_proc();
-
 	mis = read_mnt_ns_img();
 	if (!mis)
 		goto out;
@@ -1939,36 +1932,42 @@ int prepare_mnt_ns(void)
 	 * prior to recreating new ones.
 	 */
 	if (!opts.root) {
-		if (clean_mnt_ns(ns.mnt.mntinfo_tree))
+		struct ns_id ns = { .pid = PROC_SELF, .nd = &mnt_ns_desc };
+		struct mount_info *old;
+		int err;
+
+		old = collect_mntinfo(&ns);
+		if (old == NULL)
+			return -1;
+
+		close_proc();
+
+		err = clean_mnt_ns(ns.mnt.mntinfo_tree);
+		free_mntinfo(old);
+		if (err)
 			return -1;
 	} else {
-		struct mount_info *mi;
+		close_proc();
 
-		/* moving a mount residing under a shared mount is invalid. */
-		mi = mount_resolve_path(ns.mnt.mntinfo_tree, opts.root);
-		if (mi == NULL) {
-			pr_err("Unable to find mount point for %s\n", opts.root);
+		if (mount(opts.root, opts.root, NULL, MS_BIND, NULL)) {
+			pr_perror("Unable to bind-mount %s", opts.root);
 			return -1;
 		}
-		if (mi->parent == NULL) {
-			pr_err("New root and old root are the same\n");
+		/* pivot_root fails, if a parent mount is shared */
+		if (mount("none", opts.root, "none", MS_SLAVE, NULL)) {
+			pr_perror("Can't remount the parent of the new root with MS_SLAVE");
 			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");
+		if (mount(opts.root, opts.root, NULL, MS_BIND, NULL)) {
+			pr_perror("Unable to bind-mount %s", opts.root);
 			return -1;
 		}
-
-		if (mount("none", mi->parent->mountpoint + 1, "none", MS_SLAVE, NULL)) {
-			pr_perror("Can't remount the parent of the new root with MS_SLAVE");
+		if (chdir(opts.root)) {
+			pr_perror("chdir(%s) failed", opts.root);
 			return -1;
 		}
 	}
 
-	free_mntinfo(old);
-
 	ret = populate_mnt_ns(mis);
 	if (ret)
 		goto out;
-- 
1.9.3


--Dxnq1zWXvFF0Q93v--


More information about the CRIU mailing list