[1/3] net: read network namespace images before forking tasks

Submitted by Andrey Vagin on July 23, 2018, 4:20 p.m.

Details

Message ID 20180723162053.12443-2-avagin@virtuozzo.com
State Accepted
Series "criu: add support for external net namespaces"
Headers show

Commit Message

Andrey Vagin July 23, 2018, 4:20 p.m.
We need to know which namespaces are external to restore them properly.

Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
---
 criu/include/net.h |  1 +
 criu/namespaces.c  |  3 +++
 criu/net.c         | 49 +++++++++++++++++++++++++++++++++++--------------
 3 files changed, 39 insertions(+), 14 deletions(-)

Patch hide | download patch | download mbox

diff --git a/criu/include/net.h b/criu/include/net.h
index 1f6be068d..38b33a727 100644
--- a/criu/include/net.h
+++ b/criu/include/net.h
@@ -50,5 +50,6 @@  extern int net_get_nsid(int rtsk, int fd, int *nsid);
 extern struct ns_id *net_get_root_ns();
 extern int kerndat_nsid(void);
 extern void check_has_netns_ioc(int fd, bool *kdat_val, const char *name);
+extern int read_net_ns_img();
 
 #endif /* __CR_NET_H__ */
diff --git a/criu/namespaces.c b/criu/namespaces.c
index 87a8dadb2..f58f310ad 100644
--- a/criu/namespaces.c
+++ b/criu/namespaces.c
@@ -1739,6 +1739,9 @@  int prepare_namespace_before_tasks(void)
 	if (read_mnt_ns_img())
 		goto err_img;
 
+	if (read_net_ns_img())
+		goto err_img;
+
 	return 0;
 
 err_img:
diff --git a/criu/net.c b/criu/net.c
index cf3ef5cbf..e5b35fb54 100644
--- a/criu/net.c
+++ b/criu/net.c
@@ -2048,26 +2048,48 @@  out:
 	return ret;
 }
 
+int read_net_ns_img(void)
+{
+	struct ns_id *ns;
+
+	for (ns = ns_ids; ns != NULL; ns = ns->next) {
+		struct cr_img *img;
+		int ret;
+
+		if (ns->nd != &net_ns_desc)
+			continue;
+
+		img = open_image(CR_FD_NETNS, O_RSTR, ns->id);
+		if (!img)
+			return -1;
+
+		if (empty_image(img)) {
+			/* Backward compatibility */
+			close_image(img);
+			continue;
+		}
+
+		ret = pb_read_one(img, &ns->net.netns, PB_NETNS);
+		close_image(img);
+		if (ret < 0) {
+			pr_err("Can not read netns object\n");
+			return -1;
+		}
+		ns->ext_key = ns->net.netns->ext_key;
+	}
+
+	return 0;
+}
+
 static int restore_netns_conf(struct ns_id *ns)
 {
-	NetnsEntry *netns;
+	NetnsEntry *netns = ns->net.netns;
 	int ret = 0;
-	struct cr_img *img;
 
-	img = open_image(CR_FD_NETNS, O_RSTR, ns->id);
-	if (!img)
-		return -1;
-
-	if (empty_image(img))
+	if (ns->net.netns == NULL)
 		/* Backward compatibility */
 		goto out;
 
-	ret = pb_read_one(img, &netns, PB_NETNS);
-	if (ret < 0) {
-		pr_err("Can not read netns object\n");
-		return -1;
-	}
-
 	if ((netns)->def_conf4) {
 		ret = ipv4_conf_op("all", (netns)->all_conf4, (netns)->n_all_conf4, CTL_WRITE, NULL);
 		if (ret)
@@ -2094,7 +2116,6 @@  static int restore_netns_conf(struct ns_id *ns)
 
 	ns->net.netns = netns;
 out:
-	close_image(img);
 	return ret;
 }