[CRIU] [PATCH 4/4] net: Make sure the entries exist before read them

Cyrill Gorcunov gorcunov at openvz.org
Thu Apr 30 13:07:58 PDT 2015


Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
 include/net.h |  2 ++
 net.c         | 50 +++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 51 insertions(+), 1 deletion(-)

diff --git a/include/net.h b/include/net.h
index c03105c109bd..c940e15a4021 100644
--- a/include/net.h
+++ b/include/net.h
@@ -30,4 +30,6 @@ extern int restore_link_parms(NetDeviceEntry *nde, int nlsk);
 extern int veth_pair_add(char *in, char *out);
 extern int move_veth_to_bridge(void);
 
+extern int net_init_devconfs(void);
+
 #endif /* __CR_NET_H__ */
diff --git a/net.c b/net.c
index fb64d2ebfb62..448de3c1adbe 100644
--- a/net.c
+++ b/net.c
@@ -79,10 +79,47 @@ static char *devconfs[] = {
 	"shared_media",
 	"src_valid_mark",
 	"tag",
-	NULL,
 };
 
+static int devconfs_status[ARRAY_SIZE(devconfs)] = {
+	[0 ... (ARRAY_SIZE(devconfs) - 1)] = 1,
+};
+
+/*
+ * I case if some entry is missing in
+ * the kernel, simply write DEVCONFS_UNUSED
+ * into the image so we would skip it.
+ */
+#define DEVCONFS_UNUSED	(-1u)
+
 #define NET_CONF_PATH "net/ipv4/conf"
+
+int net_init_devconfs(void)
+{
+	static bool inited = false;
+	size_t i;
+	int dir;
+
+	BUILD_BUG_ON(ARRAY_SIZE(devconfs) != ARRAY_SIZE(devconfs_status));
+
+	if (inited)
+		return 0;
+
+	dir = open("/proc/sys/" NET_CONF_PATH "/all", O_RDONLY);
+	if (dir < 0) {
+		pr_perror("Can't open sysctl dir");
+		return -1;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(devconfs); i++) {
+		if (faccessat(dir, devconfs[i], F_OK, 0)) {
+			pr_debug("devconfs: No %s entry\n", devconfs[i]);
+			devconfs_status[i] = DEVCONFS_UNUSED;
+		}
+	}
+	close(dir);
+	return 0;
+}
 #define MAX_CONF_OPT_PATH IFNAMSIZ+50
 
 static int ipv4_conf_op(char *tgt, int *conf, int op, NetnsEntry **netns)
@@ -101,6 +138,14 @@ static int ipv4_conf_op(char *tgt, int *conf, int op, NetnsEntry **netns)
 			continue;
 		}
 
+		if (op == CTL_READ && devconfs_status[i] == DEVCONFS_UNUSED) {
+			conf[i] = DEVCONFS_UNUSED;
+			continue;
+		} else {
+			if (conf[i] == DEVCONFS_UNUSED)
+				continue;
+		}
+
 		snprintf(path[i], MAX_CONF_OPT_PATH, "%s/%s/%s", NET_CONF_PATH, tgt, devconfs[i]);
 		req[ri].name = path[i];
 		req[ri].arg = &conf[i];
@@ -695,6 +740,9 @@ int dump_net_ns(int ns_id)
 	if (fds == NULL)
 		return -1;
 
+	if (net_init_devconfs())
+		return -1;
+
 	ret = mount_ns_sysfs();
 	if (!ret)
 		ret = dump_netns_conf(fds);
-- 
2.1.0



More information about the CRIU mailing list