[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