[CRIU] [PATCH cr 11/13] restore: mount proc for a new pid namespace

Andrey Vagin avagin at openvz.org
Tue Jun 19 07:53:15 EDT 2012


Create a tmp directory and mount proc from a target pid ns.
This proc will show pid-s from the target pid ns.

crtools uses map_files for restoring sharing mappings.

the tmp directory is removed after restore.

Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
 cr-restore.c |   46 +++++++++++++++++++++++++++++++++++++---------
 1 files changed, 37 insertions(+), 9 deletions(-)

diff --git a/cr-restore.c b/cr-restore.c
index cfcf344..d5c15d9 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -17,6 +17,7 @@
 #include <sys/wait.h>
 #include <sys/file.h>
 #include <sys/shm.h>
+#include <sys/mount.h>
 
 #include <sched.h>
 
@@ -521,17 +522,11 @@ static inline int fork_with_pid(struct pstree_item *item, unsigned long ns_clone
 		goto err_close;
 	}
 
-	/* A process with pid = 1 is "init". It should be restore in new pid ns.
-	 * The first process in pid ns gets pid = 1 automaticaly. */
-	if (pid == 1) {
-		ca.clone_flags |= CLONE_NEWPID;
-		if (item != root_item) {
-			pr_err("Only first task can have pid = 1");
-			goto err_unlock;
-		}
-	} else
+	if (!(ca.clone_flags & CLONE_NEWPID)) {
 		if (write_img_buf(ca.fd, buf, strlen(buf)))
 			goto err_unlock;
+	} else
+		BUG_ON(pid != 1);
 
 	ret = clone(restore_task_with_children, stack + STACK_SIZE,
 			ca.clone_flags | SIGCHLD, &ca);
@@ -620,6 +615,8 @@ static void restore_pgid(void)
 	}
 }
 
+static char proc_mountpoint[PATH_MAX] = "/proc";
+
 static int restore_task_with_children(void *_arg)
 {
 	struct cr_clone_arg *ca = _arg;
@@ -638,6 +635,15 @@ static int restore_task_with_children(void *_arg)
 		exit(-1);
 	}
 
+	if (pid == 1) { /* New pid namespace */
+		ret = mount("proc", proc_mountpoint, "proc", MS_MGC_VAL, NULL);
+		if (ret == -1) {
+			pr_err("mount failed");
+			exit(1);
+		}
+		set_proc_mountpoint(proc_mountpoint);
+	}
+
 	ret = log_init_by_pid();
 	if (ret < 0)
 		exit(1);
@@ -704,6 +710,18 @@ static int restore_root_task(struct pstree_item *init, struct cr_options *opts)
 	 * this later.
 	 */
 
+	if (init->pid.pid == 1) {
+		sprintf(proc_mountpoint, "/tmp/crtools-proc.XXXXXX");
+		if (mkdtemp(proc_mountpoint) == NULL) {
+			pr_err("mkdtemp failed %m");
+			return -1;
+		}
+		/* A process with pid = 1 is "init".
+		 * It should be restore in new pid ns.
+		 * The first process in pid ns gets pid = 1 automaticaly. */
+		opts->namespaces_flags |= CLONE_NEWPID;
+	}
+
 	ret = fork_with_pid(init, opts->namespaces_flags);
 	if (ret < 0)
 		return -1;
@@ -722,6 +740,16 @@ static int restore_root_task(struct pstree_item *init, struct cr_options *opts)
 	ret = (int)futex_get(&task_entries->nr_in_progress);
 
 out:
+	if (init->pid.pid == 1) {
+		int err;
+		err = umount(proc_mountpoint);
+		if (err == -1)
+			pr_err("Can't umount %s\n", proc_mountpoint);
+		err = rmdir(proc_mountpoint);
+		if (err == -1)
+			pr_err("Can't delete %s\n", proc_mountpoint);
+	}
+
 	if (ret < 0) {
 		struct pstree_item *pi;
 		pr_err("Someone can't be restored\n");
-- 
1.7.1



More information about the CRIU mailing list