[CRIU] [PATCH 1/5] ns: Prepare namespaces before tasks

Pavel Emelyanov xemul at parallels.com
Mon Sep 21 04:08:12 PDT 2015


There's already two things we do in criu namespaces before
forking the init task (start unsd and keep netnsfd for back
reference). Next patches will introduce the 3rd action for
mount namespaces, so have a special pre-call for all this
stuff.

Signed-off-by: Pavel Emelyanov <xemul at parallels.com>
---
 cr-restore.c         | 11 +----------
 include/namespaces.h |  2 +-
 include/net.h        |  2 +-
 namespaces.c         | 18 +++++++++++++++++-
 net.c                | 11 ++++++++++-
 5 files changed, 30 insertions(+), 14 deletions(-)

diff --git a/cr-restore.c b/cr-restore.c
index b8b4473..8aa570b 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -1123,15 +1123,6 @@ static inline int fork_with_pid(struct pstree_item *item)
 		BUG_ON(pid != INIT_PID);
 	}
 
-	if (ca.clone_flags & CLONE_NEWNET)
-		/*
-		 * When restoring a net namespace we need to communicate
-		 * with the original (i.e. -- init) one. Thus, prepare for
-		 * that before we leave the existing namespaces.
-		 */
-		if (netns_pre_create())
-			goto err_unlock;
-
 	/*
 	 * Some kernel modules, such as netwrok packet generator
 	 * run kernel thread upon net-namespace creattion taking
@@ -1772,7 +1763,7 @@ static int restore_root_task(struct pstree_item *init)
 		return -1;
 	}
 
-	if (start_usernsd())
+	if (prepare_namespace_before_tasks())
 		return -1;
 
 	futex_set(&task_entries->nr_in_progress,
diff --git a/include/namespaces.h b/include/namespaces.h
index c038281..0e70a7b 100644
--- a/include/namespaces.h
+++ b/include/namespaces.h
@@ -67,6 +67,7 @@ extern int collect_namespaces(bool for_dump);
 extern int collect_mnt_namespaces(bool for_dump);
 extern int dump_mnt_namespaces(void);
 extern int dump_namespaces(struct pstree_item *item, unsigned int ns_flags);
+extern int prepare_namespace_before_tasks(void);
 extern int prepare_namespace(struct pstree_item *item, unsigned long clone_flags);
 extern int try_show_namespaces(int pid);
 
@@ -81,7 +82,6 @@ extern struct ns_id *lookup_ns_by_id(unsigned int id, struct ns_desc *nd);
 
 extern int collect_user_namespaces(bool for_dump);
 extern int prepare_userns(struct pstree_item *item);
-extern int start_usernsd(void);
 extern int stop_usernsd(void);
 extern int userns_uid(int uid);
 extern int userns_gid(int gid);
diff --git a/include/net.h b/include/net.h
index c03105c..900b136 100644
--- a/include/net.h
+++ b/include/net.h
@@ -6,7 +6,7 @@
 struct cr_imgset;
 extern int dump_net_ns(int ns_id);
 extern int prepare_net_ns(int pid);
-extern int netns_pre_create(void);
+extern int netns_keep_nsfd(void);
 
 struct veth_pair {
 	struct list_head node;
diff --git a/namespaces.c b/namespaces.c
index 993b29d..bb38459 100644
--- a/namespaces.c
+++ b/namespaces.c
@@ -1088,7 +1088,7 @@ out:
 	return ret;
 }
 
-int start_usernsd(void)
+static int start_usernsd(void)
 {
 	int sk[2];
 	int one = 1;
@@ -1313,6 +1313,22 @@ int prepare_namespace(struct pstree_item *item, unsigned long clone_flags)
 	return 0;
 }
 
+int prepare_namespace_before_tasks(void)
+{
+	if (start_usernsd())
+		goto err_unds;
+
+	if (netns_keep_nsfd())
+		goto err_netns;
+
+	return 0;
+
+err_netns:
+	stop_usernsd();
+err_unds:
+	return -1;
+}
+
 int try_show_namespaces(int ns_pid)
 {
 	struct cr_imgset *imgset;
diff --git a/net.c b/net.c
index 90f4bb1..dfabecc 100644
--- a/net.c
+++ b/net.c
@@ -748,8 +748,17 @@ int prepare_net_ns(int pid)
 	return ret;
 }
 
-int netns_pre_create(void)
+int netns_keep_nsfd(void)
 {
+	if (!(root_ns_mask & CLONE_NEWNET))
+		return 0;
+
+	/*
+	 * When restoring a net namespace we need to communicate
+	 * with the original (i.e. -- init) one. Thus, prepare for
+	 * that before we leave the existing namespaces.
+	 */
+
 	ns_fd = open("/proc/self/ns/net", O_RDONLY | O_CLOEXEC);
 	if (ns_fd < 0) {
 		pr_perror("Can't cache net fd");
-- 
1.9.3




More information about the CRIU mailing list