[CRIU] [PATCH 11/11] ns: dump all namespaces

Pavel Emelyanov xemul at parallels.com
Mon Sep 30 07:53:15 PDT 2013


On 09/30/2013 05:16 PM, Andrey Vagin wrote:
> Before this patch only namespaces of the root task are dumped.
> Now we dump all namespace, which have been collected.

What if two net namespaces are connected with veth, will criu dump and restore
this properly? I really doubt it.

What about mount namespaces? Will interconnections be checked properly on dump?

> I'm not sure, that we want to create a new process for each namespace.
> 
> Signed-off-by: Andrey Vagin <avagin at openvz.org>
> ---
>  namespaces.c | 91 ++++++++++++++++++++++++++++++++++--------------------------
>  1 file changed, 51 insertions(+), 40 deletions(-)
> 
> diff --git a/namespaces.c b/namespaces.c
> index fde76a1..24bdef3 100644
> --- a/namespaces.c
> +++ b/namespaces.c
> @@ -350,36 +350,35 @@ int dump_task_ns_ids(struct pstree_item *item)
>  	return 0;
>  }
>  
> -static int do_dump_namespaces(struct pstree_item *item, unsigned int ns_flags)
> +static int do_dump_namespaces(struct ns_id *ns)
>  {
> -	struct pid *ns_pid = &item->pid;
> -	int ret = 0;
> +	int ret = -1;
>  
> -	if (ns_flags & CLONE_NEWUTS) {
> +	switch (ns->nd->cflag) {
> +	case CLONE_NEWPID:
> +		ret = 0;
> +		break;
> +	case CLONE_NEWUTS:
>  		pr_info("Dump UTS namespace\n");
> -		ret = dump_uts_ns(ns_pid->real, item->ids->uts_ns_id);
> -		if (ret < 0)
> -			goto err;
> -	}
> -	if (ns_flags & CLONE_NEWIPC) {
> +		ret = dump_uts_ns(ns->pid, ns->id);
> +		break;
> +	case CLONE_NEWIPC:
>  		pr_info("Dump IPC namespace\n");
> -		ret = dump_ipc_ns(ns_pid->real, item->ids->ipc_ns_id);
> -		if (ret < 0)
> -			goto err;
> -	}
> -	if (ns_flags & CLONE_NEWNS) {
> +		ret = dump_ipc_ns(ns->pid, ns->id);
> +		break;
> +	case CLONE_NEWNS:
>  		pr_info("Dump MNT namespace (mountpoints)\n");
> -		ret = dump_mnt_ns(ns_pid->real, item->ids->mnt_ns_id);
> -		if (ret < 0)
> -			goto err;
> -	}
> -	if (ns_flags & CLONE_NEWNET) {
> +		ret = dump_mnt_ns(ns->pid, ns->id);
> +		break;
> +	case CLONE_NEWNET:
>  		pr_info("Dump NET namespace info\n");
> -		ret = dump_net_ns(ns_pid->real, item->ids->net_ns_id);
> -		if (ret < 0)
> -			goto err;
> +		ret = dump_net_ns(ns->pid, ns->id);
> +		break;
> +	default:
> +		pr_err("Unknown namespace flag %x", ns->nd->cflag);
> +		break;
>  	}
> -err:
> +
>  	return ret;
>  
>  }
> @@ -387,6 +386,7 @@ err:
>  int dump_namespaces(struct pstree_item *item, unsigned int ns_flags)
>  {
>  	struct pid *ns_pid = &item->pid;
> +	struct ns_id *ns;
>  	int pid, status;
>  	int ret = 0;
>  
> @@ -408,26 +408,37 @@ int dump_namespaces(struct pstree_item *item, unsigned int ns_flags)
>  		return -1;
>  	}
>  
> -	pid = fork();
> -	if (pid < 0) {
> -		pr_perror("Can't fork ns dumper");
> -		return -1;
> -	}
> +	ns = ns_ids;
>  
> -	if (pid == 0) {
> -		ret = do_dump_namespaces(item, ns_flags);
> -		exit(ret);
> -	}
> +	while (ns) {
> +		/* Skip current namespaces, which are in the list too  */
> +		if (ns->pid == getpid()) {
> +			ns = ns->next;
> +			continue;
> +		}
>  
> -	ret = waitpid(pid, &status, 0);
> -	if (ret != pid) {
> -		pr_perror("Can't wait ns dumper");
> -		return -1;
> -	}
> +		pid = fork();
> +		if (pid < 0) {
> +			pr_perror("Can't fork ns dumper");
> +			return -1;
> +		}
>  
> -	if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
> -		pr_err("Namespaces dumping finished with error %d\n", status);
> -		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