Message ID | 1555410131-1588-1-git-send-email-jan.dakinevich@virtuozzo.com |
---|---|
State | New |
Series | "net: add support for "net/core/*" sysctls" |
Headers | show |
diff --git a/criu/net.c b/criu/net.c index 3eebf48..6aa8bc6 100644 --- a/criu/net.c +++ b/criu/net.c @@ -334,6 +334,61 @@ static int ipv6_conf_op(char *tgt, SysctlEntry **conf, int n, int op, SysctlEntr devconfs6, def_conf); } +static char *coreconfs[] = { + "somaxconn", +}; + +static int core_conf_op(SysctlEntry **conf, int n, int op) +{ + struct sysctl_req req[ARRAY_SIZE(coreconfs)]; + char path[ARRAY_SIZE(coreconfs)][256]; + SysctlEntry *rconf[ARRAY_SIZE(coreconfs)]; + int ret = 0; + int i, ri; + + if (n > ARRAY_SIZE(coreconfs)) + pr_warn("The image contains unknown sysctl-s\n"); + + for (i = 0, ri = 0; i < ARRAY_SIZE(coreconfs); i++) { + if (i >= n) { + pr_warn("Skip %s\n", coreconfs[i]); + continue; + } + + if (conf[i]->type != SYSCTL_TYPE__CTL_32) + continue; + if (op == CTL_WRITE && !conf[i]->has_iarg) + continue; + + snprintf(path[i], sizeof(path[i]), "net/core/%s", coreconfs[i]); + req[ri].name = path[i]; + req[ri].type = CTL_32; + req[ri].arg = &conf[i]->iarg; + if (op == CTL_READ || opts.weak_sysctls) + req[ri].flags = CTL_FLAGS_OPTIONAL; + else + req[ri].flags = 0; + + rconf[ri] = conf[i]; + ri++; + } + + ret = sysctl_op(req, ri, op, CLONE_NEWNET); + if (ret < 0) { + pr_err("Failed to %s\n", (op == CTL_READ ? "read" : "write")); + return ret; + } + + if (op == CTL_READ) { + for (i = 0; i < ri; i++) { + if (req[i].flags & CTL_FLAGS_HAS) + rconf[i]->has_iarg = true; + } + } + + return ret; +} + /* * I case if some entry is missing in * the kernel, simply write DEVCONFS_UNUSED @@ -1827,6 +1882,8 @@ static int dump_netns_conf(struct ns_id *ns, struct cr_imgset *fds) char all_stable_secret[MAX_STR_CONF_LEN + 1] = {}; NetnsId *ids; struct netns_id *p; + int core_size = ARRAY_SIZE(coreconfs); + SysctlEntry *core_confs = NULL; i = 0; list_for_each_entry(p, &ns->net.ids, node) @@ -1835,7 +1892,8 @@ static int dump_netns_conf(struct ns_id *ns, struct cr_imgset *fds) o_buf = buf = xmalloc( i * (sizeof(NetnsId*) + sizeof(NetnsId)) + size4 * (sizeof(SysctlEntry*) + sizeof(SysctlEntry)) * 2 + - size6 * (sizeof(SysctlEntry*) + sizeof(SysctlEntry)) * 2 + size6 * (sizeof(SysctlEntry*) + sizeof(SysctlEntry)) * 2 + + core_size * (sizeof(SysctlEntry*) + sizeof(SysctlEntry)) ); if (!buf) goto out; @@ -1891,6 +1949,16 @@ static int dump_netns_conf(struct ns_id *ns, struct cr_imgset *fds) } } + netns.n_core_conf = core_size; + netns.core_conf = xptr_pull_s(&buf, core_size * sizeof(SysctlEntry*)); + core_confs = xptr_pull_s(&buf, core_size * sizeof(SysctlEntry)); + + for (i = 0; i < core_size; i++) { + sysctl_entry__init(&core_confs[i]); + netns.core_conf[i] = &core_confs[i]; + netns.core_conf[i]->type = CTL_32; + } + ret = ipv4_conf_op("default", netns.def_conf4, size4, CTL_READ, NULL); if (ret < 0) goto err_free; @@ -1905,6 +1973,10 @@ static int dump_netns_conf(struct ns_id *ns, struct cr_imgset *fds) if (ret < 0) goto err_free; + ret = core_conf_op(netns.core_conf, core_size, CTL_READ); + if (ret < 0) + goto err_free; + ret = pb_write_one(img_from_set(fds, CR_FD_NETNS), &netns, PB_NETNS); err_free: xfree(o_buf); @@ -2114,6 +2186,12 @@ static int restore_netns_conf(struct ns_id *ns) ret = ipv6_conf_op("default", (netns)->def_conf6, (netns)->n_def_conf6, CTL_WRITE, NULL); } + if ((netns)->core_conf) { + ret = core_conf_op((netns)->core_conf, (netns)->n_core_conf, CTL_WRITE); + if (ret) + goto out; + } + ns->net.netns = netns; out: return ret; diff --git a/images/netdev.proto b/images/netdev.proto index 476a92c..7b9ab8d 100644 --- a/images/netdev.proto +++ b/images/netdev.proto @@ -71,4 +71,6 @@ message netns_entry { repeated netns_id nsids = 7; optional string ext_key = 8; + + repeated sysctl_entry core_conf = 9; }
Looks good to me except for a small naming confusion, e.g. ipv6_conf_op was named for "/proc/sys/net/ipv6/conf/" path to it, but in "/proc/sys/net/core" we don't have any conf, though we have coreconfs, core_conf_op, also arrays rconf and conf, and image field core_conf =). Think we can leave as is. Reviewed-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com> On 4/16/19 1:22 PM, Jan Dakinevich wrote: > - handle 'somaxconn' option. > > https://jira.sw.ru/browse/PSBM-91415 > Signed-off-by: Jan Dakinevich <jan.dakinevich@virtuozzo.com> > --- > criu/net.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++- > images/netdev.proto | 2 ++ > 2 files changed, 81 insertions(+), 1 deletion(-) > > diff --git a/criu/net.c b/criu/net.c > index 3eebf48..6aa8bc6 100644 > --- a/criu/net.c > +++ b/criu/net.c > @@ -334,6 +334,61 @@ static int ipv6_conf_op(char *tgt, SysctlEntry **conf, int n, int op, SysctlEntr > devconfs6, def_conf); > } > > +static char *coreconfs[] = { > + "somaxconn", > +}; > + > +static int core_conf_op(SysctlEntry **conf, int n, int op) > +{ > + struct sysctl_req req[ARRAY_SIZE(coreconfs)]; > + char path[ARRAY_SIZE(coreconfs)][256]; > + SysctlEntry *rconf[ARRAY_SIZE(coreconfs)]; > + int ret = 0; > + int i, ri; > + > + if (n > ARRAY_SIZE(coreconfs)) > + pr_warn("The image contains unknown sysctl-s\n"); > + > + for (i = 0, ri = 0; i < ARRAY_SIZE(coreconfs); i++) { > + if (i >= n) { > + pr_warn("Skip %s\n", coreconfs[i]); > + continue; > + } > + > + if (conf[i]->type != SYSCTL_TYPE__CTL_32) > + continue; > + if (op == CTL_WRITE && !conf[i]->has_iarg) > + continue; > + > + snprintf(path[i], sizeof(path[i]), "net/core/%s", coreconfs[i]); > + req[ri].name = path[i]; > + req[ri].type = CTL_32; > + req[ri].arg = &conf[i]->iarg; > + if (op == CTL_READ || opts.weak_sysctls) > + req[ri].flags = CTL_FLAGS_OPTIONAL; > + else > + req[ri].flags = 0; > + > + rconf[ri] = conf[i]; > + ri++; > + } > + > + ret = sysctl_op(req, ri, op, CLONE_NEWNET); > + if (ret < 0) { > + pr_err("Failed to %s\n", (op == CTL_READ ? "read" : "write")); > + return ret; > + } > + > + if (op == CTL_READ) { > + for (i = 0; i < ri; i++) { > + if (req[i].flags & CTL_FLAGS_HAS) > + rconf[i]->has_iarg = true; > + } > + } > + > + return ret; > +} > + > /* > * I case if some entry is missing in > * the kernel, simply write DEVCONFS_UNUSED > @@ -1827,6 +1882,8 @@ static int dump_netns_conf(struct ns_id *ns, struct cr_imgset *fds) > char all_stable_secret[MAX_STR_CONF_LEN + 1] = {}; > NetnsId *ids; > struct netns_id *p; > + int core_size = ARRAY_SIZE(coreconfs); > + SysctlEntry *core_confs = NULL; > > i = 0; > list_for_each_entry(p, &ns->net.ids, node) > @@ -1835,7 +1892,8 @@ static int dump_netns_conf(struct ns_id *ns, struct cr_imgset *fds) > o_buf = buf = xmalloc( > i * (sizeof(NetnsId*) + sizeof(NetnsId)) + > size4 * (sizeof(SysctlEntry*) + sizeof(SysctlEntry)) * 2 + > - size6 * (sizeof(SysctlEntry*) + sizeof(SysctlEntry)) * 2 > + size6 * (sizeof(SysctlEntry*) + sizeof(SysctlEntry)) * 2 + > + core_size * (sizeof(SysctlEntry*) + sizeof(SysctlEntry)) > ); > if (!buf) > goto out; > @@ -1891,6 +1949,16 @@ static int dump_netns_conf(struct ns_id *ns, struct cr_imgset *fds) > } > } > > + netns.n_core_conf = core_size; > + netns.core_conf = xptr_pull_s(&buf, core_size * sizeof(SysctlEntry*)); > + core_confs = xptr_pull_s(&buf, core_size * sizeof(SysctlEntry)); > + > + for (i = 0; i < core_size; i++) { > + sysctl_entry__init(&core_confs[i]); > + netns.core_conf[i] = &core_confs[i]; > + netns.core_conf[i]->type = CTL_32; > + } > + > ret = ipv4_conf_op("default", netns.def_conf4, size4, CTL_READ, NULL); > if (ret < 0) > goto err_free; > @@ -1905,6 +1973,10 @@ static int dump_netns_conf(struct ns_id *ns, struct cr_imgset *fds) > if (ret < 0) > goto err_free; > > + ret = core_conf_op(netns.core_conf, core_size, CTL_READ); > + if (ret < 0) > + goto err_free; > + > ret = pb_write_one(img_from_set(fds, CR_FD_NETNS), &netns, PB_NETNS); > err_free: > xfree(o_buf); > @@ -2114,6 +2186,12 @@ static int restore_netns_conf(struct ns_id *ns) > ret = ipv6_conf_op("default", (netns)->def_conf6, (netns)->n_def_conf6, CTL_WRITE, NULL); > } > > + if ((netns)->core_conf) { > + ret = core_conf_op((netns)->core_conf, (netns)->n_core_conf, CTL_WRITE); > + if (ret) > + goto out; > + } > + > ns->net.netns = netns; > out: > return ret; > diff --git a/images/netdev.proto b/images/netdev.proto > index 476a92c..7b9ab8d 100644 > --- a/images/netdev.proto > +++ b/images/netdev.proto > @@ -71,4 +71,6 @@ message netns_entry { > > repeated netns_id nsids = 7; > optional string ext_key = 8; > + > + repeated sysctl_entry core_conf = 9; > } >
One more thing, we likely need a test for it to zdtm, something like test/zdtm/static/netns-dev.c On 4/17/19 11:40 AM, Pavel Tikhomirov wrote: > Looks good to me except for a small naming confusion, e.g. ipv6_conf_op > was named for "/proc/sys/net/ipv6/conf/" path to it, but in > "/proc/sys/net/core" we don't have any conf, though we have coreconfs, > core_conf_op, also arrays rconf and conf, and image field core_conf =). > Think we can leave as is. > > Reviewed-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com> > > On 4/16/19 1:22 PM, Jan Dakinevich wrote: >> - handle 'somaxconn' option. >> >> https://jira.sw.ru/browse/PSBM-91415 >> Signed-off-by: Jan Dakinevich <jan.dakinevich@virtuozzo.com> >> --- >> criu/net.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++- >> images/netdev.proto | 2 ++ >> 2 files changed, 81 insertions(+), 1 deletion(-) >> >> diff --git a/criu/net.c b/criu/net.c >> index 3eebf48..6aa8bc6 100644 >> --- a/criu/net.c >> +++ b/criu/net.c >> @@ -334,6 +334,61 @@ static int ipv6_conf_op(char *tgt, SysctlEntry **conf, int n, int op, SysctlEntr >> devconfs6, def_conf); >> } >> >> +static char *coreconfs[] = { >> + "somaxconn", >> +}; >> + >> +static int core_conf_op(SysctlEntry **conf, int n, int op) >> +{ >> + struct sysctl_req req[ARRAY_SIZE(coreconfs)]; >> + char path[ARRAY_SIZE(coreconfs)][256]; >> + SysctlEntry *rconf[ARRAY_SIZE(coreconfs)]; >> + int ret = 0; >> + int i, ri; >> + >> + if (n > ARRAY_SIZE(coreconfs)) >> + pr_warn("The image contains unknown sysctl-s\n"); >> + >> + for (i = 0, ri = 0; i < ARRAY_SIZE(coreconfs); i++) { >> + if (i >= n) { >> + pr_warn("Skip %s\n", coreconfs[i]); >> + continue; >> + } >> + >> + if (conf[i]->type != SYSCTL_TYPE__CTL_32) >> + continue; >> + if (op == CTL_WRITE && !conf[i]->has_iarg) >> + continue; >> + >> + snprintf(path[i], sizeof(path[i]), "net/core/%s", coreconfs[i]); >> + req[ri].name = path[i]; >> + req[ri].type = CTL_32; >> + req[ri].arg = &conf[i]->iarg; >> + if (op == CTL_READ || opts.weak_sysctls) >> + req[ri].flags = CTL_FLAGS_OPTIONAL; >> + else >> + req[ri].flags = 0; >> + >> + rconf[ri] = conf[i]; >> + ri++; >> + } >> + >> + ret = sysctl_op(req, ri, op, CLONE_NEWNET); >> + if (ret < 0) { >> + pr_err("Failed to %s\n", (op == CTL_READ ? "read" : "write")); >> + return ret; >> + } >> + >> + if (op == CTL_READ) { >> + for (i = 0; i < ri; i++) { >> + if (req[i].flags & CTL_FLAGS_HAS) >> + rconf[i]->has_iarg = true; >> + } >> + } >> + >> + return ret; >> +} >> + >> /* >> * I case if some entry is missing in >> * the kernel, simply write DEVCONFS_UNUSED >> @@ -1827,6 +1882,8 @@ static int dump_netns_conf(struct ns_id *ns, struct cr_imgset *fds) >> char all_stable_secret[MAX_STR_CONF_LEN + 1] = {}; >> NetnsId *ids; >> struct netns_id *p; >> + int core_size = ARRAY_SIZE(coreconfs); >> + SysctlEntry *core_confs = NULL; >> >> i = 0; >> list_for_each_entry(p, &ns->net.ids, node) >> @@ -1835,7 +1892,8 @@ static int dump_netns_conf(struct ns_id *ns, struct cr_imgset *fds) >> o_buf = buf = xmalloc( >> i * (sizeof(NetnsId*) + sizeof(NetnsId)) + >> size4 * (sizeof(SysctlEntry*) + sizeof(SysctlEntry)) * 2 + >> - size6 * (sizeof(SysctlEntry*) + sizeof(SysctlEntry)) * 2 >> + size6 * (sizeof(SysctlEntry*) + sizeof(SysctlEntry)) * 2 + >> + core_size * (sizeof(SysctlEntry*) + sizeof(SysctlEntry)) >> ); >> if (!buf) >> goto out; >> @@ -1891,6 +1949,16 @@ static int dump_netns_conf(struct ns_id *ns, struct cr_imgset *fds) >> } >> } >> >> + netns.n_core_conf = core_size; >> + netns.core_conf = xptr_pull_s(&buf, core_size * sizeof(SysctlEntry*)); >> + core_confs = xptr_pull_s(&buf, core_size * sizeof(SysctlEntry)); >> + >> + for (i = 0; i < core_size; i++) { >> + sysctl_entry__init(&core_confs[i]); >> + netns.core_conf[i] = &core_confs[i]; >> + netns.core_conf[i]->type = CTL_32; >> + } >> + >> ret = ipv4_conf_op("default", netns.def_conf4, size4, CTL_READ, NULL); >> if (ret < 0) >> goto err_free; >> @@ -1905,6 +1973,10 @@ static int dump_netns_conf(struct ns_id *ns, struct cr_imgset *fds) >> if (ret < 0) >> goto err_free; >> >> + ret = core_conf_op(netns.core_conf, core_size, CTL_READ); >> + if (ret < 0) >> + goto err_free; >> + >> ret = pb_write_one(img_from_set(fds, CR_FD_NETNS), &netns, PB_NETNS); >> err_free: >> xfree(o_buf); >> @@ -2114,6 +2186,12 @@ static int restore_netns_conf(struct ns_id *ns) >> ret = ipv6_conf_op("default", (netns)->def_conf6, (netns)->n_def_conf6, CTL_WRITE, NULL); >> } >> >> + if ((netns)->core_conf) { >> + ret = core_conf_op((netns)->core_conf, (netns)->n_core_conf, CTL_WRITE); >> + if (ret) >> + goto out; >> + } >> + >> ns->net.netns = netns; >> out: >> return ret; >> diff --git a/images/netdev.proto b/images/netdev.proto >> index 476a92c..7b9ab8d 100644 >> --- a/images/netdev.proto >> +++ b/images/netdev.proto >> @@ -71,4 +71,6 @@ message netns_entry { >> >> repeated netns_id nsids = 7; >> optional string ext_key = 8; >> + >> + repeated sysctl_entry core_conf = 9; >> } >> >
On Wed, Apr 17, 2019 at 11:46:25AM +0300, Pavel Tikhomirov wrote: > One more thing, we likely need a test for it to zdtm, something like > test/zdtm/static/netns-dev.c > Yes, Jan, please make a test once time permit.
- handle 'somaxconn' option. https://jira.sw.ru/browse/PSBM-91415 Signed-off-by: Jan Dakinevich <jan.dakinevich@virtuozzo.com> --- criu/net.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++- images/netdev.proto | 2 ++ 2 files changed, 81 insertions(+), 1 deletion(-)