diff options
author | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2019-05-21 08:45:19 +0200 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2019-05-29 10:20:42 +0200 |
commit | 0985c7c4e22c8dbbea4398cf3453da45ebf63800 (patch) | |
tree | bbb08300ff3c022617628b8cbff223218b2ebc62 /src/nspawn/nspawn-oci.c | |
parent | shared/cpu-set-util: remove now-unused CPU_SIZE_TO_NUM() (diff) | |
download | systemd-0985c7c4e22c8dbbea4398cf3453da45ebf63800.tar.xz systemd-0985c7c4e22c8dbbea4398cf3453da45ebf63800.zip |
Rework cpu affinity parsing
The CPU_SET_S api is pretty bad. In particular, it has a parameter for the size
of the array, but operations which take two (CPU_EQUAL_S) or even three arrays
(CPU_{AND,OR,XOR}_S) still take just one size. This means that all arrays must
be of the same size, or buffer overruns will occur. This is exactly what our
code would do, if it received an array of unexpected size over the network.
("Unexpected" here means anything different from what cpu_set_malloc() detects
as the "right" size.)
Let's rework this, and store the size in bytes of the allocated storage area.
The code will now parse any number up to 8191, independently of what the current
kernel supports. This matches the kernel maximum setting for any architecture,
to make things more portable.
Fixes #12605.
Diffstat (limited to 'src/nspawn/nspawn-oci.c')
-rw-r--r-- | src/nspawn/nspawn-oci.c | 25 |
1 files changed, 11 insertions, 14 deletions
diff --git a/src/nspawn/nspawn-oci.c b/src/nspawn/nspawn-oci.c index 97323f31dd..f5e52bef5e 100644 --- a/src/nspawn/nspawn-oci.c +++ b/src/nspawn/nspawn-oci.c @@ -1266,8 +1266,7 @@ struct cpu_data { uint64_t shares; uint64_t quota; uint64_t period; - cpu_set_t *cpuset; - unsigned ncpus; + CPUSet cpu_set; }; static int oci_cgroup_cpu_shares(const char *name, JsonVariant *v, JsonDispatchFlags flags, void *userdata) { @@ -1302,21 +1301,20 @@ static int oci_cgroup_cpu_quota(const char *name, JsonVariant *v, JsonDispatchFl static int oci_cgroup_cpu_cpus(const char *name, JsonVariant *v, JsonDispatchFlags flags, void *userdata) { struct cpu_data *data = userdata; - cpu_set_t *set; + CPUSet set; const char *n; - int ncpus; + int r; assert(data); assert_se(n = json_variant_string(v)); - ncpus = parse_cpu_set(n, &set); - if (ncpus < 0) - return json_log(v, flags, ncpus, "Failed to parse CPU set specification: %s", n); + r = parse_cpu_set(n, &set); + if (r < 0) + return json_log(v, flags, r, "Failed to parse CPU set specification: %s", n); - CPU_FREE(data->cpuset); - data->cpuset = set; - data->ncpus = ncpus; + cpu_set_reset(&data->cpu_set); + data->cpu_set = set; return 0; } @@ -1345,13 +1343,12 @@ static int oci_cgroup_cpu(const char *name, JsonVariant *v, JsonDispatchFlags fl r = json_dispatch(v, table, oci_unexpected, flags, &data); if (r < 0) { - CPU_FREE(data.cpuset); + cpu_set_reset(&data.cpu_set); return r; } - CPU_FREE(s->cpuset); - s->cpuset = data.cpuset; - s->cpuset_ncpus = data.ncpus; + cpu_set_reset(&s->cpu_set); + s->cpu_set = data.cpu_set; if (data.shares != UINT64_MAX) { r = settings_allocate_properties(s); |