From e3f5ba3c37d7bdea1c08bc06de5a95a4dcca6c0f Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Mon, 21 Sep 2015 14:08:12 +0300 Subject: [PATCH] ns: Prepare namespaces before tasks 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 --- 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 b8b447399..8aa570b99 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 c03828164..0e70a7b68 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 c03105c10..900b13656 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 993b29dac..bb38459b3 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 a45ac304d..f525c4898 100644 --- a/net.c +++ b/net.c @@ -762,8 +762,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");