[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