[CRIU] [PATCH v10 07/11] net: open a netlink socket in criu's netns

Tycho Andersen tycho.andersen at canonical.com
Thu Oct 27 07:24:01 PDT 2016


On Thu, Oct 27, 2016 at 03:49:37PM +0300, Pavel Emelyanov wrote:
> >> +	if (!(root_ns_mask & CLONE_NEWUSER)) {
> >> +		/* FIXME: this whole dance is so we can have a netlink socket to criu's
> >> +		 * netns in case we need it. It should really live on the ns_id struct,
> >> +		 * but those aren't generated on restore yet.
> >> +		 */
> >> +		my_netns = open_proc(PROC_SELF, "ns/net");
> >> +		if (my_netns < 0) {
> >> +			pr_perror("couldn't open my netns");
> >> +			goto out;
> >> +		}
> >> +
> >> +		if (setns(ns_fd, CLONE_NEWNET) < 0) {
> >> +			close(my_netns);
> >> +			pr_perror("couldn't setns to parent ns");
> >> +			goto out;
> >> +		}
> >> +
> >> +		criu_nlsk = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
> > 
> > Why we can't create this socket before forking the root task? In this
> > case it will work for userns too.
> 
> I wanted to have this socket for each netns created in your multi-ns patchset :)
> and sit on ns_id structure.

We could create the socket before forking (or whenever, as long as
it's in CRIU's net ns). We can't use it for the userns case, though,
because the kernel checks that the sender has CAP_NET_ADMIN in both
the namespace of the master and the namespace of the slave device. In
the userns case, the task only has it in the slave device. You can
fake it with a quick hack,

~/packages/criu/test $ git diff
diff --git a/criu/net.c b/criu/net.c
index 35388ee..66edd3a 100644
--- a/criu/net.c
+++ b/criu/net.c
@@ -1235,7 +1235,7 @@ static int restore_one_macvlan(NetDeviceEntry *nde, int nlsk, int criu_nlsk)
                return -1;
        }
 
-       if (root_ns_mask & CLONE_NEWUSER) {
+       if (false && root_ns_mask & CLONE_NEWUSER) {
                struct newlink_req req;
 
                if (populate_newlink_req(&req, RTM_NEWLINK, nde, macvlan_link_info, &extras) < 0)
@@ -1315,7 +1315,7 @@ static int restore_links(int pid, NetnsEntry **netns)
                return -1;
        }
 
-       if (!(root_ns_mask & CLONE_NEWUSER)) {
+       if (true || !(root_ns_mask & CLONE_NEWUSER)) {
                /* FIXME: this whole dance is so we can have a netlink socket to criu's
                 * netns in case we need it. It should really live on the ns_id struct,
                 * but those aren't generated on restore yet.

but it doesn't work:

~/packages/criu/test $ sudo ./zdtm.py run -t zdtm/static/macvlan
Checking feature nsid_manip
=== Run 1/1 ================

======================== Run zdtm/static/macvlan in ns =========================
Start test
Test is SUID
Running zdtm/static/macvlan.hook(--post-start)
./macvlan --pidfile=macvlan.pid --outfile=macvlan.out
Run criu dump
Running zdtm/static/macvlan.hook(--pre-restore)
Cannot find device "zdtmmvlan0"
Run criu restore
Send the 15 signal to  143
Wait for zdtm/static/macvlan(143) to die for 0.100000
Running zdtm/static/macvlan.hook(--clean)
Cannot find device "zdtmmvlan0"
Removing dump/zdtm/static/macvlan/96
======================== Test zdtm/static/macvlan PASS =========================

======================== Run zdtm/static/macvlan in uns ========================
Start test
Test is SUID
Running zdtm/static/macvlan.hook(--post-start)
./macvlan --pidfile=macvlan.pid --outfile=macvlan.out
Run criu dump
Running zdtm/static/macvlan.hook(--pre-restore)
Cannot find device "zdtmmvlan0"
Run criu restore
=[log]=> dump/zdtm/static/macvlan/261/1/restore.log
------------------------ grep Error ------------------------
(00.138300)      1: Error (criu/net.c:1331): couldn't setns to parent ns: Operation not permitted
(00.149331) Error (criu/cr-restore.c:1129): 310 killed by signal 9: Killed
(00.149751) Error (criu/cr-restore.c:2000): Restoring FAILED.
------------------------ ERROR OVER ------------------------
################ Test zdtm/static/macvlan FAIL at CRIU restore #################
##################################### FAIL #####################################

Tycho

> -- Pavel
> 
> >> +		ret = setns(my_netns, CLONE_NEWNET);
> >> +		close(my_netns);
> >> +
> >> +		if (ret < 0) {
> >> +			pr_perror("Can't setns back my netns");
> >> +			goto out;
> >> +		}
> >> +
> >> +		if (criu_nlsk < 0) {
> >> +			pr_perror("Can't create nlk socket");
> >> +			goto out;
> >> +		}
> >> +	}
> >> +
> >>  	while (1) {
> >>  		NetnsEntry **def_netns = netns;
> >>  
> >> @@ -1074,7 +1106,7 @@ static int restore_links(int pid, NetnsEntry **netns)
> >>  		if (ret <= 0)
> >>  			break;
> >>  
> >> -		ret = restore_link(nde, nlsk);
> >> +		ret = restore_link(nde, nlsk, criu_nlsk);
> >>  		if (ret) {
> >>  			pr_err("Can't restore link\n");
> >>  			goto exit;
> >> @@ -1103,6 +1135,9 @@ exit:
> >>  			break;
> >>  	}
> >>  
> >> +out:
> >> +	if (criu_nlsk >= 0)
> >> +		close(criu_nlsk);
> >>  	close(nlsk);
> >>  	close_image(img);
> >>  	return ret;
> >> -- 
> >> 2.7.4
> >>
> >> _______________________________________________
> >> CRIU mailing list
> >> CRIU at openvz.org
> >> https://lists.openvz.org/mailman/listinfo/criu
> > _______________________________________________
> > CRIU mailing list
> > CRIU at openvz.org
> > https://lists.openvz.org/mailman/listinfo/criu
> > .
> > 
> 


More information about the CRIU mailing list