[CRIU] [PATCH 03/16] namespaces: dump mount namespaces before tasks
Pavel Emelyanov
xemul at parallels.com
Wed Apr 9 05:46:20 PDT 2014
On 04/09/2014 03:34 AM, Andrey Vagin wrote:
> 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)
Detach dumping mount namespace from dump_namespaces and call the
resulting fn. Don't generate this strange if (before_task) mess.
> + 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");
>
More information about the CRIU
mailing list