[CRIU] [PATCH 3/4] netdevconf: dump device ipv4 configuration options if in netnamespace

Pavel Tikhomirov ptikhomirov at parallels.com
Wed Sep 10 01:02:27 PDT 2014


implemented for_each_entry_do to list devices conf directories
call function for every sub-file(directory), can pass argumens
for it in data(pass netdev and fds here)

first list conf directory to get devices, and for each device
save config options

Signed-off-by: Pavel Tikhomirov <ptikhomirov at parallels.com>
---
 net.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 101 insertions(+)

diff --git a/net.c b/net.c
index 6d9a5f7..5619fe4 100644
--- a/net.c
+++ b/net.c
@@ -511,6 +511,105 @@ int get_opt_index(char *opt) {
 	return -1;
 }
 
+static int for_each_entry_do(char *dir_path,
+		int (*f)(char *entry, char *path, void *data), void *data)
+{
+	int ret;
+	DIR *dirp;
+	struct dirent *de;
+
+	dirp = opendir(dir_path);
+	if (dirp == NULL) {
+		pr_perror("opendir %s", dir_path);
+		return -1;
+	}
+
+	while ((de = readdir(dirp)) != NULL) {
+		char path[PATH_MAX];
+		/*
+		 * Exclude ".*" files from search
+		 */
+		if (de->d_name[0] == '.')
+			continue;
+
+		snprintf(path, sizeof(path), "%s/%s", dir_path, de->d_name);
+
+		ret = (*f)(de->d_name, path, data);
+		if (ret < 0)
+			return -1;
+	}
+	closedir(dirp);
+	return 0;
+}
+
+static int save_one_option(char *option, char *path, void *data)
+{
+	int ret;
+	int val;
+	FILE *fp;
+	NetDeviceIpv4ConfEntry *netdev = (NetDeviceIpv4ConfEntry*)data;
+
+	fp = fopen(path, "r");
+	if (fp == NULL) {
+		pr_perror("fopen");
+		return -1;
+	}
+
+	ret = fscanf(fp, "%d", &val);
+	if (ret == EOF) {
+		pr_perror("fscanf");
+		return -1;
+	}
+
+	ret = get_opt_index(option);
+	if (ret < 0)
+		return -1;
+
+	netdev->data[ret] = val;
+
+	pr_debug("	%s = %d\n", option, val);
+	fclose(fp);
+	return 0;
+}
+
+#define MAX_NET_DEV_CONF 28
+
+static int save_one_device(char *device, char *path, void *data)
+{
+	int ret;
+	struct cr_fdset *fds = (struct cr_fdset*) data;
+	NetDeviceIpv4ConfEntry netdev = NET_DEVICE_IPV4_CONF_ENTRY__INIT;
+
+	netdev.dev_name = device;
+	netdev.n_data = MAX_NET_DEV_CONF;
+	netdev.data = xmalloc(MAX_NET_DEV_CONF * sizeof(unsigned));
+
+	pr_debug("Dumping netdev %s configuration\n", device);
+	ret = for_each_entry_do(path, save_one_option, (void*)&netdev);
+	if (ret < 0)
+		return -1;
+
+	ret = pb_write_one(fdset_fd(fds, CR_FD_NETDEV_CONF), &netdev, PB_NETDEV_CONF);
+	if (ret < 0)
+		return -1;
+
+	xfree(netdev.data);
+	return 0;
+}
+
+#define NET_IPV4_CONF_DIR "/proc/sys/net/ipv4/conf"
+
+static int dump_net_devs_conf(struct cr_fdset *fds)
+{
+	int ret;
+
+	ret = for_each_entry_do(NET_IPV4_CONF_DIR, save_one_device, (void*)fds);
+	if (ret < 0)
+		return -1;
+
+	return 0;
+}
+
 static int restore_ip_dump(int type, int pid, char *cmd)
 {
 	int fd, ret;
@@ -607,6 +706,8 @@ int dump_net_ns(int pid, int ns_id)
 		ret = dump_route(fds);
 	if (!ret)
 		ret = dump_iptables(fds);
+	if (!ret)
+		ret = dump_net_devs_conf(fds);
 
 	close(ns_sysfs_fd);
 	ns_sysfs_fd = -1;
-- 
1.9.3



More information about the CRIU mailing list