[CRIU] [PATCH 1/4] restore: create the root netns before running setup-namespaces scripts
Andrei Vagin
avagin at openvz.org
Fri May 5 22:56:48 PDT 2017
From: Andrei Vagin <avagin at virtuozzo.com>
runc restore executes criu with --emptyns network and set
a setup-namespaces script to restore a network namespace.
https://github.com/xemul/criu/issues/314
Fixes: 2189b9c71d3d ("net: allow to dump and restore more than one network namespace")
Signed-off-by: Andrei Vagin <avagin at virtuozzo.com>
---
criu/cr-restore.c | 21 +++++++++++++++++----
criu/net.c | 12 +++++++++++-
2 files changed, 28 insertions(+), 5 deletions(-)
diff --git a/criu/cr-restore.c b/criu/cr-restore.c
index 3b67176..3687dd5 100644
--- a/criu/cr-restore.c
+++ b/criu/cr-restore.c
@@ -1730,10 +1730,23 @@ static int restore_task_with_children(void *_arg)
goto err;
}
- /* Wait prepare_userns */
- if (current->parent == NULL &&
- restore_finish_ns_stage(CR_STATE_ROOT_TASK, CR_STATE_PREPARE_NAMESPACES) < 0)
- goto err;
+ if (current->parent == NULL) {
+ /*
+ * The root task has to be in its namespaces before executing
+ * ACT_SETUP_NS scripts, so the root netns has to be created here
+ */
+ if (root_ns_mask & CLONE_NEWNET) {
+ ret = unshare(CLONE_NEWNET);
+ if (ret) {
+ pr_perror("Can't unshare net-namespace");
+ goto err;
+ }
+ }
+
+ /* Wait prepare_userns */
+ if (restore_finish_ns_stage(CR_STATE_ROOT_TASK, CR_STATE_PREPARE_NAMESPACES) < 0)
+ goto err;
+ }
/*
* Call this _before_ forking to optimize cgroups
diff --git a/criu/net.c b/criu/net.c
index e91d1e8..aa50ebf 100644
--- a/criu/net.c
+++ b/criu/net.c
@@ -1938,6 +1938,9 @@ int dump_net_ns(struct ns_id *ns)
ret = dump_iptables(fds);
if (!ret)
ret = dump_netns_conf(ns, fds);
+ } else if (ns->type != NS_ROOT) {
+ pr_err("Unable to dump more than one netns if the --emptyns is set\n");
+ ret = -1;
}
if (!ret)
ret = dump_nf_ct(fds, CR_FD_NETNF_CT);
@@ -2094,8 +2097,13 @@ static int create_net_ns(void *arg)
static int __prepare_net_namespaces(void *unused)
{
struct ns_id *nsid;
- int ret = -1;
+ int ret = -1, root_ns;
+ root_ns = open_proc(PROC_SELF, "ns/net");
+ if (root_ns < 0)
+ return -1;
+
+ /* Pin one with a file descriptor */
for (nsid = ns_ids; nsid != NULL; nsid = nsid->next) {
if (nsid->nd != &net_ns_desc)
continue;
@@ -2103,6 +2111,8 @@ static int __prepare_net_namespaces(void *unused)
if (root_user_ns && nsid->user_ns != root_user_ns) {
if (call_in_child_process(create_net_ns, nsid) < 0)
goto err;
+ } else if (nsid->type == NS_ROOT) {
+ nsid->net.ns_fd = root_ns;
} else {
if (do_create_net_ns(nsid))
goto err;
--
2.9.3
More information about the CRIU
mailing list