[CRIU] [PATCH v9 06/15] dump/net/ipv6: net device and def/all configuration
Pavel Tikhomirov
ptikhomirov at virtuozzo.com
Tue May 10 01:00:44 PDT 2016
* old MAX_CONF_OPT_PATH should be enough for ipv6 path array as
len('net/ipv6/conf//mldv2_unsolicited_report_interval') is 48
but len and size are almost back to back, so increase it a bit,
to don't worry about it.
reading stable_secret before it is initialized fails with EIO,
we can safely skip dumping it in that case as in new netns it
will be uninitialized by default
v6: use __CTL_STR without len in image type
v9: set flag CTL_FLAGS_READ_EIO_SKIP for stable_secret dumping
https://jira.sw.ru/browse/PSBM-30942
Signed-off-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
---
criu/net.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 89 insertions(+), 2 deletions(-)
diff --git a/criu/net.c b/criu/net.c
index 83eecf1..b623e8c 100644
--- a/criu/net.c
+++ b/criu/net.c
@@ -155,7 +155,7 @@ char *devconfs6[] = {
};
#define CONF_OPT_PATH "net/%s/conf/%s/%s"
-#define MAX_CONF_OPT_PATH IFNAMSIZ+50
+#define MAX_CONF_OPT_PATH IFNAMSIZ+60
#define MAX_STR_CONF_LEN 200
static int net_conf_op(char *tgt, SysctlEntry **conf, int n, int op, char *proto,
@@ -200,6 +200,8 @@ static int net_conf_op(char *tgt, SysctlEntry **conf, int n, int op, char *proto
break;
case __CTL_STR:
req[ri].type = CTL_STR(MAX_STR_CONF_LEN);
+ flags |= op == CTL_READ && !strcmp(devconfs[i], "stable_secret")
+ ? CTL_FLAGS_READ_EIO_SKIP : 0;
/* skip non-existing sysctl */
if (op == CTL_WRITE && !conf[i]->sarg)
@@ -248,6 +250,16 @@ static int ipv4_conf_op(char *tgt, SysctlEntry **conf, int n, int op, SysctlEntr
devconfs4, def_conf);
}
+static int ipv6_conf_op(char *tgt, SysctlEntry **conf, int n, int op, SysctlEntry **def_conf)
+{
+ struct sysctl_req req[ARRAY_SIZE(devconfs6)];
+ char path[ARRAY_SIZE(devconfs6)][MAX_CONF_OPT_PATH];
+
+ return net_conf_op(tgt, conf, n, op, "ipv6",
+ req, path, ARRAY_SIZE(devconfs6),
+ devconfs6, def_conf);
+}
+
/*
* I case if some entry is missing in
* the kernel, simply write DEVCONFS_UNUSED
@@ -313,6 +325,9 @@ static int dump_one_netdev(int type, struct ifinfomsg *ifi,
NetDeviceEntry netdev = NET_DEVICE_ENTRY__INIT;
SysctlEntry *confs4 = NULL;
int size4 = ARRAY_SIZE(devconfs4);
+ SysctlEntry *confs6 = NULL;
+ int size6 = ARRAY_SIZE(devconfs6);
+ char stable_secret[MAX_STR_CONF_LEN + 1];
if (!tb[IFLA_IFNAME]) {
pr_err("No name for link %d\n", ifi->ifi_index);
@@ -349,17 +364,43 @@ static int dump_one_netdev(int type, struct ifinfomsg *ifi,
netdev.conf4[i]->type = CTL_32;
}
+ netdev.n_conf6 = size6;
+ netdev.conf6 = xmalloc(sizeof(SysctlEntry *) * size6);
+ if (!netdev.conf6)
+ goto err_free;
+
+ confs6 = xmalloc(sizeof(SysctlEntry) * size6);
+ if (!confs6)
+ goto err_free;
+
+ for (i = 0; i < size6; i++) {
+ sysctl_entry__init(&confs6[i]);
+ netdev.conf6[i] = &confs6[i];
+ if (strcmp(devconfs6[i], "stable_secret")) {
+ netdev.conf6[i]->type = CTL_32;
+ } else {
+ netdev.conf6[i]->type = __CTL_STR;
+ netdev.conf6[i]->sarg = stable_secret;
+ }
+ }
+
ret = ipv4_conf_op(netdev.name, netdev.conf4, size4, CTL_READ, NULL);
if (ret < 0)
goto err_free;
+ ret = ipv6_conf_op(netdev.name, netdev.conf6, size6, CTL_READ, NULL);
+ if (ret < 0)
+ goto err_free;
+
if (!dump)
dump = write_netdev_img;
ret = dump(&netdev, fds);
err_free:
- xfree(confs4);
xfree(netdev.conf4);
+ xfree(confs4);
+ xfree(netdev.conf6);
+ xfree(confs6);
return ret;
}
@@ -1080,6 +1121,10 @@ static int dump_netns_conf(struct cr_imgset *fds)
NetnsEntry netns = NETNS_ENTRY__INIT;
SysctlEntry *def_confs4 = NULL, *all_confs4 = NULL;
int size4 = ARRAY_SIZE(devconfs4);
+ SysctlEntry *def_confs6 = NULL, *all_confs6 = NULL;
+ int size6 = ARRAY_SIZE(devconfs6);
+ char def_stable_secret[MAX_STR_CONF_LEN + 1];
+ char all_stable_secret[MAX_STR_CONF_LEN + 1];
netns.n_def_conf4 = size4;
netns.n_all_conf4 = size4;
@@ -1105,6 +1150,37 @@ static int dump_netns_conf(struct cr_imgset *fds)
netns.all_conf4[i]->type = CTL_32;
}
+ netns.n_def_conf6 = size6;
+ netns.n_all_conf6 = size6;
+ netns.def_conf6 = xmalloc(sizeof(SysctlEntry *) * size6);
+ if (!netns.def_conf6)
+ goto err_free;
+ netns.all_conf6 = xmalloc(sizeof(SysctlEntry *) * size6);
+ if (!netns.all_conf6)
+ goto err_free;
+ def_confs6 = xmalloc(sizeof(SysctlEntry) * size6);
+ if (!def_confs6)
+ goto err_free;
+ all_confs6 = xmalloc(sizeof(SysctlEntry) * size6);
+ if (!all_confs6)
+ goto err_free;
+
+ for (i = 0; i < size6; i++) {
+ sysctl_entry__init(&def_confs6[i]);
+ sysctl_entry__init(&all_confs6[i]);
+ netns.def_conf6[i] = &def_confs6[i];
+ netns.all_conf6[i] = &all_confs6[i];
+ if (strcmp(devconfs6[i], "stable_secret")) {
+ netns.def_conf6[i]->type = CTL_32;
+ netns.all_conf6[i]->type = CTL_32;
+ } else {
+ netns.def_conf6[i]->type = __CTL_STR;
+ netns.all_conf6[i]->type = __CTL_STR;
+ netns.def_conf6[i]->sarg = def_stable_secret;
+ netns.all_conf6[i]->sarg = all_stable_secret;
+ }
+ }
+
ret = ipv4_conf_op("default", netns.def_conf4, size4, CTL_READ, NULL);
if (ret < 0)
goto err_free;
@@ -1112,12 +1188,23 @@ static int dump_netns_conf(struct cr_imgset *fds)
if (ret < 0)
goto err_free;
+ ret = ipv6_conf_op("default", netns.def_conf6, size6, CTL_READ, NULL);
+ if (ret < 0)
+ goto err_free;
+ ret = ipv6_conf_op("all", netns.all_conf6, size6, CTL_READ, NULL);
+ if (ret < 0)
+ goto err_free;
+
ret = pb_write_one(img_from_set(fds, CR_FD_NETNS), &netns, PB_NETNS);
err_free:
xfree(netns.def_conf4);
xfree(netns.all_conf4);
xfree(def_confs4);
xfree(all_confs4);
+ xfree(netns.def_conf6);
+ xfree(netns.all_conf6);
+ xfree(def_confs6);
+ xfree(all_confs6);
return ret;
}
--
2.5.5
More information about the CRIU
mailing list