[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