[CRIU] Adding checkpoint/restore support to podman question

Adrian Reber adrian at lisas.de
Sat Jul 21 12:38:05 MSK 2018


On Fri, Jul 20, 2018 at 09:30:17PM -0700, Andrei Vagin wrote:
> On Fri, Jul 20, 2018 at 08:31:16PM +0200, Adrian Reber wrote:
> > On Wed, Jul 18, 2018 at 03:25:09PM +0200, Adrian Reber wrote:
> > > > On Fri, May 04, 2018 at 02:01:08PM -0700, Andrei Vagin wrote:
> > > > > On Thu, May 03, 2018 at 07:48:55PM +0200, Adrian Reber wrote:
> > > > > > If you could implement the CRIU part that would be great. I have not
> > > > > > started yet but I would then do the necessary changes in runc (and
> > > > > > higher).
> > > > > 
> > > > > Here is a criu part:
> > > > > https://github.com/avagin/criu/tree/netns_ext
> > > > > 
> > > > > Let me know if you will have any questions or comments.
> > 
> > As your patch does not apply anymore (I guess due to the removal of
> > nested namespaces) I tried to port your patch to the current criu-dev
> > branch. And it almost works. I am storing the ext_key now in
> > 'netns_entry', but the problem is that that image file is read to late.
> > 
> > So at the point the network namespace is restored the necessary
> > information is not yet read from the image file and the network
> > namespace is never restored as described via inherit_fd.
> > 
> > Please have a look at my attached patch and maybe you have an idea how
> > to correctly implement it. Maybe you could just let me know which image
> > file would be best suited for the ext_key of the network namespace and
> > how to make sure it is available at restore time. Thanks.
> >
> 
> Hi Adrian,
> 
> Could you try out this branch
> https://github.com/avagin/criu/tree/netns_ext2

Perfect, that works. Thanks a lot. I have three additional patches on
top of it for RPC. My runc integration patches and my runc test cases
are also successful. This gets my

Acked-by: Adrian Reber <areber at redhat.com>

Do you want to merge this patch and I will submit my patches on top of
it, or do you want to merge the whole series, your patch plus my runc
RPC patches on top of it?

		Adrian

> > diff --git a/criu/cr-restore.c b/criu/cr-restore.c
> > index 807a582..0e5b064 100644
> > --- a/criu/cr-restore.c
> > +++ b/criu/cr-restore.c
> > @@ -1674,7 +1674,11 @@ static int restore_task_with_children(void *_arg)
> >  		 * ACT_SETUP_NS scripts, so the root netns has to be created here
> >  		 */
> >  		if (root_ns_mask & CLONE_NEWNET) {
> > -			ret = unshare(CLONE_NEWNET);
> > +			struct ns_id *ns = net_get_root_ns();
> > +			if (ns->ext_key)
> > +				ret = net_set_ext(ns);
> > +			else
> > +				ret = unshare(CLONE_NEWNET);
> >  			if (ret) {
> >  				pr_perror("Can't unshare net-namespace");
> >  				goto err;
> > diff --git a/criu/include/namespaces.h b/criu/include/namespaces.h
> > index c0ad0f4..5fe8038 100644
> > --- a/criu/include/namespaces.h
> > +++ b/criu/include/namespaces.h
> > @@ -91,6 +91,7 @@ struct ns_id {
> >  	struct ns_desc *nd;
> >  	struct ns_id *next;
> >  	enum ns_type type;
> > +	char *ext_key;
> >  
> >  	/*
> >  	 * For mount namespaces on restore -- indicates that
> > diff --git a/criu/include/net.h b/criu/include/net.h
> > index 1f6be06..e9419a9 100644
> > --- a/criu/include/net.h
> > +++ b/criu/include/net.h
> > @@ -50,5 +50,6 @@ extern int net_get_nsid(int rtsk, int fd, int *nsid);
> >  extern struct ns_id *net_get_root_ns();
> >  extern int kerndat_nsid(void);
> >  extern void check_has_netns_ioc(int fd, bool *kdat_val, const char *name);
> > +extern int net_set_ext(struct ns_id *ns);
> >  
> >  #endif /* __CR_NET_H__ */
> > diff --git a/criu/net.c b/criu/net.c
> > index cf3ef5c..b7a4fcc 100644
> > --- a/criu/net.c
> > +++ b/criu/net.c
> > @@ -1827,6 +1827,7 @@ static int dump_netns_conf(struct ns_id *ns, struct cr_imgset *fds)
> >  	char all_stable_secret[MAX_STR_CONF_LEN + 1] = {};
> >  	NetnsId	*ids;
> >  	struct netns_id *p;
> > +	char id[64], *val;
> >  
> >  	i = 0;
> >  	list_for_each_entry(p, &ns->net.ids, node)
> > @@ -1840,6 +1841,15 @@ static int dump_netns_conf(struct ns_id *ns, struct cr_imgset *fds)
> >  	if (!buf)
> >  		goto out;
> >  
> > +	snprintf(id, sizeof(id), "net[%u]", ns->kid);
> > +	val = external_lookup_by_key(id);
> > +	if (!IS_ERR_OR_NULL(val)) {
> > +		pr_debug("The %s netns is external\n", id);
> > +		ns->ext_key = val;
> > +	}
> > +
> > +	netns.ext_key = ns->ext_key;
> > +
> >  	netns.nsids = xptr_pull_s(&buf, i * sizeof(NetnsId*));
> >  	ids = xptr_pull_s(&buf, i * sizeof(NetnsId));
> >  	i = 0;
> > @@ -2178,6 +2188,22 @@ static int dump_netns_ids(int rtsk, struct ns_id *ns)
> >  			(void *)&arg);
> >  }
> >  
> > +int net_set_ext(struct ns_id *ns)
> > +{
> > +	int fd, ret;
> > +
> > +	fd = inherit_fd_lookup_id(ns->ext_key);
> > +	if (fd < 0) {
> > +		pr_err("Unable to find an external netns: %s\n", ns->ext_key);
> > +		return -1;
> > +	}
> > +
> > +	ret = switch_ns_by_fd(fd, &net_ns_desc, NULL);
> > +	close(fd);
> > +
> > +	return ret;
> > +}
> > +
> >  int dump_net_ns(struct ns_id *ns)
> >  {
> >  	struct cr_imgset *fds;
> > @@ -2188,7 +2214,7 @@ int dump_net_ns(struct ns_id *ns)
> >  		return -1;
> >  
> >  	ret = mount_ns_sysfs();
> > -	if (!(opts.empty_ns & CLONE_NEWNET)) {
> > +	if (!(opts.empty_ns & CLONE_NEWNET) && !ns->ext_key) {
> >  		int sk;
> >  
> >  		sk = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
> > @@ -2285,7 +2311,7 @@ static int prepare_net_ns_first_stage(struct ns_id *ns)
> >  {
> >  	int ret = 0;
> >  
> > -	if (opts.empty_ns & CLONE_NEWNET)
> > +	if (ns->ext_key || opts.empty_ns & CLONE_NEWNET)
> >  		return 0;
> >  
> >  	ret = restore_netns_conf(ns);
> > @@ -2301,7 +2327,7 @@ static int prepare_net_ns_second_stage(struct ns_id *ns)
> >  {
> >  	int ret = 0, nsid = ns->id;
> >  
> > -	if (!(opts.empty_ns & CLONE_NEWNET)) {
> > +	if (!(opts.empty_ns & CLONE_NEWNET) && !ns->ext_key) {
> >  		if (ns->net.netns)
> >  			netns_entry__free_unpacked(ns->net.netns, NULL);
> >  
> > @@ -2349,7 +2375,13 @@ static int open_net_ns(struct ns_id *nsid)
> >  
> >  static int do_create_net_ns(struct ns_id *ns)
> >  {
> > -	if (unshare(CLONE_NEWNET)) {
> > +	int ret;
> > +
> > +	if (ns->ext_key)
> > +		ret = net_set_ext(ns);
> > +	else
> > +		ret = unshare(CLONE_NEWNET);
> > +	if (ret) {
> >  		pr_perror("Unable to create a new netns");
> >  		return -1;
> >  	}
> > @@ -2378,6 +2410,9 @@ static int __prepare_net_namespaces(void *unused)
> >  		if (nsid->type == NS_ROOT) {
> >  			nsid->net.ns_fd = root_ns;
> >  		} else {
> > +			pr_debug("nsid->net.netns %p\n", nsid->net.netns);
> > +			if (nsid->net.netns && nsid->net.netns->ext_key)
> > +				nsid->ext_key = xstrdup(nsid->net.netns->ext_key);
> >  			if (do_create_net_ns(nsid))
> >  				goto err;
> >  		}
> > diff --git a/images/netdev.proto b/images/netdev.proto
> > index b4b64d2..28b162a 100644
> > --- a/images/netdev.proto
> > +++ b/images/netdev.proto
> > @@ -70,4 +70,6 @@ message netns_entry {
> >  	repeated sysctl_entry all_conf6	= 6;
> >  
> >  	repeated netns_id nsids		= 7;
> > +
> > +	optional string	ext_key		= 8;
> >  }

		Adrian

-- 
Adrian Reber <adrian at lisas.de>            http://lisas.de/~adrian/
RADIO SHACK LEVEL II BASIC
READY
>_


More information about the CRIU mailing list