[Devel] [PATCH] net: add support for "net/core/*" sysctls
Pavel Tikhomirov
ptikhomirov at virtuozzo.com
Wed Apr 17 11:46:25 MSK 2019
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 at 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 at 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;
>> }
>>
>
--
Best regards, Tikhomirov Pavel
Software Developer, Virtuozzo.
More information about the Devel
mailing list