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

Andrew Vagin avagin at parallels.com
Mon Sep 30 08:19:21 PDT 2013


On Mon, Sep 30, 2013 at 06:53:15PM +0400, Pavel Emelyanov wrote:
> 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?

Pavel, this patch doesn't remove check for nested namespaces from
generate_ns_id(). CRIU can't dump nested namespaces.
It's only preparation. If we will add an exception, all
namespace will be dumped automatically.

Now I started to devel support of nested mount namespaces, which is
required for dumping/restoring systemd.

> 
> > 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