[CRIU] [PATCH 03/16] namespaces: dump mount namespaces before tasks

Andrey Vagin avagin at openvz.org
Tue Apr 8 16:34:55 PDT 2014


because we want to check, that all files are reachable.
For that we need to collect all mounts from all namespaces.

Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
 cr-dump.c            | 12 ++++++----
 include/namespaces.h |  3 ++-
 namespaces.c         | 66 ++++++++++++++++++++++++++++++----------------------
 3 files changed, 48 insertions(+), 33 deletions(-)

diff --git a/cr-dump.c b/cr-dump.c
index d326cbf..23bd13a 100644
--- a/cr-dump.c
+++ b/cr-dump.c
@@ -1753,11 +1753,19 @@ int cr_dump_tasks(pid_t pid)
 	if (!glob_fdset)
 		goto err;
 
+	if (root_ns_mask)
+		if (dump_namespaces(root_item, root_ns_mask, true) < 0)
+			goto err;
+
 	for_each_pstree_item(item) {
 		if (dump_one_task(item))
 			goto err;
 	}
 
+	if (root_ns_mask)
+		if (dump_namespaces(root_item, root_ns_mask, false) < 0)
+			goto err;
+
 	if (dump_verify_tty_sids())
 		goto err;
 
@@ -1767,10 +1775,6 @@ int cr_dump_tasks(pid_t pid)
 	if (dump_pstree(root_item))
 		goto err;
 
-	if (root_ns_mask)
-		if (dump_namespaces(root_item, root_ns_mask) < 0)
-			goto err;
-
 	ret = cr_dump_shmem();
 	if (ret)
 		goto err;
diff --git a/include/namespaces.h b/include/namespaces.h
index ed7681f..494470b 100644
--- a/include/namespaces.h
+++ b/include/namespaces.h
@@ -35,7 +35,8 @@ extern unsigned long root_ns_mask;
 extern const struct fdtype_ops nsfile_dump_ops;
 extern struct collect_image_info nsfile_cinfo;
 
-extern int dump_namespaces(struct pstree_item *item, unsigned int ns_flags);
+extern int dump_namespaces(struct pstree_item *item,
+				unsigned int ns_flags, bool before_tasks);
 extern int prepare_namespace(struct pstree_item *item, unsigned long clone_flags);
 extern int try_show_namespaces(int pid);
 
diff --git a/namespaces.c b/namespaces.c
index aefd538..2965036 100644
--- a/namespaces.c
+++ b/namespaces.c
@@ -450,7 +450,8 @@ static int do_dump_namespaces(struct ns_id *ns)
 
 }
 
-int dump_namespaces(struct pstree_item *item, unsigned int ns_flags)
+int dump_namespaces(struct pstree_item *item,
+			unsigned int ns_flags, bool before_tasks)
 {
 	struct pid *ns_pid = &item->pid;
 	struct ns_id *ns;
@@ -470,42 +471,51 @@ int dump_namespaces(struct pstree_item *item, unsigned int ns_flags)
 
 	pr_info("Dumping %d(%d)'s namespaces\n", ns_pid->virt, ns_pid->real);
 
-	if ((ns_flags & CLONE_NEWPID) && ns_pid->virt != 1) {
+	if (!before_tasks && (ns_flags & CLONE_NEWPID) && ns_pid->virt != 1) {
 		pr_err("Can't dump a pid namespace without the process init\n");
 		return -1;
 	}
 
-	ns = ns_ids;
-
-	while (ns) {
+	for (ns = ns_ids; ns; ns = ns->next) {
 		/* Skip current namespaces, which are in the list too  */
-		if (ns->pid == getpid()) {
-			ns = ns->next;
+		if (ns->pid == getpid())
 			continue;
-		}
 
-		pid = fork();
-		if (pid < 0) {
-			pr_perror("Can't fork ns dumper");
-			return -1;
-		}
-
-		if (pid == 0) {
-			ret = do_dump_namespaces(ns);
-			exit(ret);
-		}
-
-		ret = waitpid(pid, &status, 0);
-		if (ret != pid) {
-			pr_perror("Can't wait ns dumper");
-			return -1;
-		}
+		if ((ns->nd->cflag & CLONE_NEWNS)) {
+			if (!before_tasks)
+				continue;
+			/*
+			 * Don't fork, because we are going to collect data,
+			 * which will be used for dumping tasks.
+			 */
+			if (do_dump_namespaces(ns))
+				return -1;
+		} else {
+			if (before_tasks)
+				continue;
 
-		if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
-			pr_err("Namespaces dumping finished with error %d\n", status);
-			return -1;
+			pid = fork();
+			if (pid < 0) {
+				pr_perror("Can't fork ns dumper");
+				return -1;
+			}
+
+			if (pid == 0) {
+				ret = do_dump_namespaces(ns);
+				exit(ret);
+			}
+
+			ret = waitpid(pid, &status, 0);
+			if (ret != pid) {
+				pr_perror("Can't wait ns dumper");
+				return -1;
+			}
+
+			if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
+				pr_err("Namespaces dumping finished with error %d\n", status);
+				return -1;
+			}
 		}
-		ns = ns->next;
 	}
 
 	pr_info("Namespaces dump complete\n");
-- 
1.8.5.3



More information about the CRIU mailing list