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");