[CRIU] [PATCH v2 06/57] net: Do not change net_ns of root_item in create_net_ns()
Kirill Tkhai
ktkhai at virtuozzo.com
Tue Mar 28 08:34:49 PDT 2017
Currently, we do unshare(CLONE_NEWNET), but do not restore
old net ns. So, net_ns of criu task and root_item becomes
different. Unpredictible net_ns of root_item is not good,
so this patch fixes the problem.
Later, we will use this property to create transport sockets
for tasks items and usernsd in the only net.
Also, disable tun test before "Problem of restoring tun in
nested net namespace" from criu ml is not fixed.
v2: Rebase on new criu
Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
---
criu/net.c | 119 ++++++++++++++++++++++-----------------------
test/zdtm/static/tun.desc | 2 -
2 files changed, 60 insertions(+), 61 deletions(-)
diff --git a/criu/net.c b/criu/net.c
index e06d32bc..e9e58e32 100644
--- a/criu/net.c
+++ b/criu/net.c
@@ -1385,18 +1385,25 @@ struct net_link *lookup_net_link(struct ns_id *ns, uint32_t ifindex)
return NULL;
}
-static int __restore_links(struct ns_id *nsid, int *nrlinks, int *nrcreated)
+static int __links_nrlinks;
+static int __links_nrcreated;
+
+static int __restore_links(void *arg)
{
+ struct ns_id *nsid = arg;
struct net_link *link, *t;
int ret;
+ if (switch_ns_by_fd(nsid->net.ns_fd, &net_ns_desc, NULL))
+ return -1;
+
list_for_each_entry_safe(link, t, &nsid->net.links, node) {
struct net_link *mlink = NULL;
if (link->created)
continue;
- (*nrlinks)++;
+ __links_nrlinks++;
pr_debug("Try to restore a link %d:%d:%s",
nsid->id, link->nde->ifindex, link->nde->name);
@@ -1419,7 +1426,7 @@ static int __restore_links(struct ns_id *nsid, int *nrlinks, int *nrcreated)
return -1;
if (ret == 0) {
- (*nrcreated)++;
+ __links_nrcreated++;
link->created = true;
if (mlink && restore_master_link(nsid->net.nlsk, nsid, link))
@@ -1432,26 +1439,22 @@ static int __restore_links(struct ns_id *nsid, int *nrlinks, int *nrcreated)
static int restore_links()
{
- int nrcreated, nrlinks;
struct ns_id *nsid;
while (true) {
- nrcreated = 0;
- nrlinks = 0;
+ __links_nrcreated = 0;
+ __links_nrlinks = 0;
for (nsid = ns_ids; nsid != NULL; nsid = nsid->next) {
if (nsid->nd != &net_ns_desc)
continue;
- if (switch_ns_by_fd(nsid->net.ns_fd, &net_ns_desc, NULL))
- return -1;
-
- if (__restore_links(nsid, &nrlinks, &nrcreated))
+ if (call_in_child_process(__restore_links, nsid))
return -1;
}
- if (nrcreated == nrlinks)
+ if (__links_nrcreated == __links_nrlinks)
break;
- if (nrcreated == 0) {
+ if (__links_nrcreated == 0) {
pr_err("Unable to restore network links");
return -1;
}
@@ -1990,26 +1993,39 @@ static int restore_netns_ids(struct ns_id *ns)
return exit_code;
}
-static int prepare_net_ns_first_stage(struct ns_id *ns)
+static int prepare_net_ns_first_stage(void *arg)
{
- int ret = 0;
+ struct ns_id *ns = arg;
- if (opts.empty_ns & CLONE_NEWNET)
- return 0;
+ if (switch_ns_by_fd(ns->net.ns_fd, &net_ns_desc, NULL))
+ return -1;
- ret = restore_netns_conf(ns);
- if (!ret)
- ret = restore_netns_ids(ns);
- if (!ret)
- ret = read_links(ns);
+ if (!(opts.empty_ns & CLONE_NEWNET)) {
+ if (restore_netns_conf(ns))
+ return -1;
+ if (restore_netns_ids(ns))
+ return -1;
+ if (read_links(ns))
+ return -1;
+ }
- return ret;
+ ns->net.nlsk = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+ if (ns->net.nlsk < 0) {
+ pr_perror("Can't create nlk socket");
+ return -1;
+ }
+
+ return 0;
}
-static int prepare_net_ns_second_stage(struct ns_id *ns)
+static int prepare_net_ns_second_stage(void *arg)
{
+ struct ns_id *ns = arg;
int ret = 0, nsid = ns->id;
+ if (switch_ns_by_fd(ns->net.ns_fd, &net_ns_desc, NULL))
+ return -1;
+
if (!(opts.empty_ns & CLONE_NEWNET)) {
if (ns->net.netns)
netns_entry__free_unpacked(ns->net.netns, NULL);
@@ -2038,6 +2054,7 @@ static int prepare_net_ns_second_stage(struct ns_id *ns)
close(fd);
}
+ close_safe(&ns->net.nlsk);
ns->ns_populated = true;
return ret;
@@ -2073,20 +2090,22 @@ static int create_net_ns(void *arg)
int ufd, ret;
uns = ns->user_ns;
- ufd = fdstore_get(uns->user.nsfd_id);
- if (ufd < 0) {
- pr_err("Can't get user ns\n");
- exit(1);
- }
- if (setns(ufd, CLONE_NEWUSER) < 0) {
- pr_perror("Can't set user ns");
- exit(2);
- }
- if (prepare_userns_creds() < 0) {
- pr_err("Can't prepare creds\n");
- exit(3);
+ if (uns && uns != root_user_ns) {
+ ufd = fdstore_get(uns->user.nsfd_id);
+ if (ufd < 0) {
+ pr_err("Can't get user ns\n");
+ exit(1);
+ }
+ if (setns(ufd, CLONE_NEWUSER) < 0) {
+ pr_perror("Can't set user ns");
+ exit(2);
+ }
+ close(ufd);
+ if (prepare_userns_creds() < 0) {
+ pr_err("Can't prepare creds\n");
+ exit(3);
+ }
}
- close(ufd);
ret = do_create_net_ns(ns) ? 3 : 0;
exit(ret);
}
@@ -2103,31 +2122,16 @@ int prepare_net_namespaces()
if (nsid->nd != &net_ns_desc)
continue;
- if (root_user_ns && nsid->user_ns != root_user_ns) {
- if (call_in_child_process(create_net_ns, nsid) < 0)
- goto err;
- } else {
- if (do_create_net_ns(nsid))
- goto err;
- }
+ if (call_in_child_process(create_net_ns, nsid) < 0)
+ goto err;
}
for (nsid = ns_ids; nsid != NULL; nsid = nsid->next) {
if (nsid->nd != &net_ns_desc)
continue;
- if (switch_ns_by_fd(nsid->net.ns_fd, &net_ns_desc, NULL))
- goto err;
-
- if (prepare_net_ns_first_stage(nsid))
- goto err;
-
- nsid->net.nlsk = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
- if (nsid->net.nlsk < 0) {
- pr_perror("Can't create nlk socket");
+ if (call_in_child_process(prepare_net_ns_first_stage, nsid))
goto err;
- }
-
}
if (restore_links())
@@ -2137,13 +2141,8 @@ int prepare_net_namespaces()
if (nsid->nd != &net_ns_desc)
continue;
- if (switch_ns_by_fd(nsid->net.ns_fd, &net_ns_desc, NULL))
+ if (call_in_child_process(prepare_net_ns_second_stage, nsid))
goto err;
-
- if (prepare_net_ns_second_stage(nsid))
- goto err;
-
- close_safe(&nsid->net.nlsk);
}
close_service_fd(NS_FD_OFF);
diff --git a/test/zdtm/static/tun.desc b/test/zdtm/static/tun.desc
index 8c7cfe86..eac32c2d 100644
--- a/test/zdtm/static/tun.desc
+++ b/test/zdtm/static/tun.desc
@@ -1 +1 @@
-{'flavor': 'ns uns', 'flags': 'suid', 'feature': 'tun'}
+{'flavor': 'ns uns', 'flags': 'suid noauto', 'feature': 'tun'}
More information about the CRIU
mailing list