summaryrefslogtreecommitdiff
path: root/src/test/test-cpu-set-util.c
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2019-05-21 08:45:19 +0200
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2019-05-29 10:20:42 +0200
commit0985c7c4e22c8dbbea4398cf3453da45ebf63800 (patch)
treebbb08300ff3c022617628b8cbff223218b2ebc62 /src/test/test-cpu-set-util.c
parentb12ef7141648be40fd8c4b0209a742f2151736d9 (diff)
downloadsystemd-0985c7c4e22c8dbbea4398cf3453da45ebf63800.tar.gz
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/test/test-cpu-set-util.c')
-rw-r--r--src/test/test-cpu-set-util.c177
1 files changed, 96 insertions, 81 deletions
diff --git a/src/test/test-cpu-set-util.c b/src/test/test-cpu-set-util.c
index ff5edb2a69..8c17931f84 100644
--- a/src/test/test-cpu-set-util.c
+++ b/src/test/test-cpu-set-util.c
@@ -5,150 +5,165 @@
#include "macro.h"
static void test_parse_cpu_set(void) {
- cpu_set_t *c = NULL;
+ CPUSet c = {};
_cleanup_free_ char *str = NULL;
- int ncpus;
int cpu;
/* Simple range (from CPUAffinity example) */
- ncpus = parse_cpu_set_and_warn("1 2", &c, NULL, "fake", 1, "CPUAffinity");
- assert_se(ncpus >= 1024);
- assert_se(CPU_ISSET_S(1, CPU_ALLOC_SIZE(ncpus), c));
- assert_se(CPU_ISSET_S(2, CPU_ALLOC_SIZE(ncpus), c));
- assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 2);
-
- assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus)));
+ assert_se(parse_cpu_set_full("1 2", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
+ assert_se(c.set);
+ assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
+ assert_se(CPU_ISSET_S(1, c.allocated, c.set));
+ assert_se(CPU_ISSET_S(2, c.allocated, c.set));
+ assert_se(CPU_COUNT_S(c.allocated, c.set) == 2);
+
+ assert_se(str = cpu_set_to_string(&c));
log_info("cpu_set_to_string: %s", str);
str = mfree(str);
- c = cpu_set_mfree(c);
+ cpu_set_reset(&c);
/* A more interesting range */
- ncpus = parse_cpu_set_and_warn("0 1 2 3 8 9 10 11", &c, NULL, "fake", 1, "CPUAffinity");
- assert_se(ncpus >= 1024);
- assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 8);
+ assert_se(parse_cpu_set_full("0 1 2 3 8 9 10 11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
+ assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
+ assert_se(CPU_COUNT_S(c.allocated, c.set) == 8);
for (cpu = 0; cpu < 4; cpu++)
- assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
+ assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
for (cpu = 8; cpu < 12; cpu++)
- assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
- assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus)));
+ assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
+ assert_se(str = cpu_set_to_string(&c));
log_info("cpu_set_to_string: %s", str);
str = mfree(str);
- c = cpu_set_mfree(c);
+ cpu_set_reset(&c);
/* Quoted strings */
- ncpus = parse_cpu_set_and_warn("8 '9' 10 \"11\"", &c, NULL, "fake", 1, "CPUAffinity");
- assert_se(ncpus >= 1024);
- assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 4);
+ assert_se(parse_cpu_set_full("8 '9' 10 \"11\"", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
+ assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
+ assert_se(CPU_COUNT_S(c.allocated, c.set) == 4);
for (cpu = 8; cpu < 12; cpu++)
- assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
- assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus)));
+ assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
+ assert_se(str = cpu_set_to_string(&c));
log_info("cpu_set_to_string: %s", str);
str = mfree(str);
- c = cpu_set_mfree(c);
+ cpu_set_reset(&c);
/* Use commas as separators */
- ncpus = parse_cpu_set_and_warn("0,1,2,3 8,9,10,11", &c, NULL, "fake", 1, "CPUAffinity");
- assert_se(ncpus >= 1024);
- assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 8);
+ assert_se(parse_cpu_set_full("0,1,2,3 8,9,10,11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
+ assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
+ assert_se(CPU_COUNT_S(c.allocated, c.set) == 8);
for (cpu = 0; cpu < 4; cpu++)
- assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
+ assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
for (cpu = 8; cpu < 12; cpu++)
- assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
- assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus)));
+ assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
+ assert_se(str = cpu_set_to_string(&c));
log_info("cpu_set_to_string: %s", str);
str = mfree(str);
- c = cpu_set_mfree(c);
+ cpu_set_reset(&c);
/* Commas with spaces (and trailing comma, space) */
- ncpus = parse_cpu_set_and_warn("0, 1, 2, 3, 4, 5, 6, 7, ", &c, NULL, "fake", 1, "CPUAffinity");
- assert_se(ncpus >= 1024);
- assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 8);
+ assert_se(parse_cpu_set_full("0, 1, 2, 3, 4, 5, 6, 7, ", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
+ assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
+ assert_se(CPU_COUNT_S(c.allocated, c.set) == 8);
for (cpu = 0; cpu < 8; cpu++)
- assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
- assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus)));
+ assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
+ assert_se(str = cpu_set_to_string(&c));
log_info("cpu_set_to_string: %s", str);
str = mfree(str);
- c = cpu_set_mfree(c);
+ cpu_set_reset(&c);
/* Ranges */
- ncpus = parse_cpu_set_and_warn("0-3,8-11", &c, NULL, "fake", 1, "CPUAffinity");
- assert_se(ncpus >= 1024);
- assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 8);
+ assert_se(parse_cpu_set_full("0-3,8-11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
+ assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
+ assert_se(CPU_COUNT_S(c.allocated, c.set) == 8);
for (cpu = 0; cpu < 4; cpu++)
- assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
+ assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
for (cpu = 8; cpu < 12; cpu++)
- assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
- assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus)));
+ assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
+ assert_se(str = cpu_set_to_string(&c));
log_info("cpu_set_to_string: %s", str);
str = mfree(str);
- c = cpu_set_mfree(c);
+ cpu_set_reset(&c);
/* Ranges with trailing comma, space */
- ncpus = parse_cpu_set_and_warn("0-3 8-11, ", &c, NULL, "fake", 1, "CPUAffinity");
- assert_se(ncpus >= 1024);
- assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 8);
+ assert_se(parse_cpu_set_full("0-3 8-11, ", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
+ assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
+ assert_se(CPU_COUNT_S(c.allocated, c.set) == 8);
for (cpu = 0; cpu < 4; cpu++)
- assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
+ assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
for (cpu = 8; cpu < 12; cpu++)
- assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
- assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus)));
+ assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
+ assert_se(str = cpu_set_to_string(&c));
log_info("cpu_set_to_string: %s", str);
str = mfree(str);
- c = cpu_set_mfree(c);
+ cpu_set_reset(&c);
/* Negative range (returns empty cpu_set) */
- ncpus = parse_cpu_set_and_warn("3-0", &c, NULL, "fake", 1, "CPUAffinity");
- assert_se(ncpus >= 1024);
- assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 0);
- c = cpu_set_mfree(c);
+ assert_se(parse_cpu_set_full("3-0", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
+ assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
+ assert_se(CPU_COUNT_S(c.allocated, c.set) == 0);
+ cpu_set_reset(&c);
/* Overlapping ranges */
- ncpus = parse_cpu_set_and_warn("0-7 4-11", &c, NULL, "fake", 1, "CPUAffinity");
- assert_se(ncpus >= 1024);
- assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 12);
+ assert_se(parse_cpu_set_full("0-7 4-11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
+ assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
+ assert_se(CPU_COUNT_S(c.allocated, c.set) == 12);
for (cpu = 0; cpu < 12; cpu++)
- assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
- assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus)));
+ assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
+ assert_se(str = cpu_set_to_string(&c));
log_info("cpu_set_to_string: %s", str);
str = mfree(str);
- c = cpu_set_mfree(c);
+ cpu_set_reset(&c);
/* Mix ranges and individual CPUs */
- ncpus = parse_cpu_set_and_warn("0,1 4-11", &c, NULL, "fake", 1, "CPUAffinity");
- assert_se(ncpus >= 1024);
- assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 10);
- assert_se(CPU_ISSET_S(0, CPU_ALLOC_SIZE(ncpus), c));
- assert_se(CPU_ISSET_S(1, CPU_ALLOC_SIZE(ncpus), c));
+ assert_se(parse_cpu_set_full("0,1 4-11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
+ assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
+ assert_se(CPU_COUNT_S(c.allocated, c.set) == 10);
+ assert_se(CPU_ISSET_S(0, c.allocated, c.set));
+ assert_se(CPU_ISSET_S(1, c.allocated, c.set));
for (cpu = 4; cpu < 12; cpu++)
- assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
- assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus)));
+ assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
+ assert_se(str = cpu_set_to_string(&c));
log_info("cpu_set_to_string: %s", str);
str = mfree(str);
- c = cpu_set_mfree(c);
+ cpu_set_reset(&c);
/* Garbage */
- ncpus = parse_cpu_set_and_warn("0 1 2 3 garbage", &c, NULL, "fake", 1, "CPUAffinity");
- assert_se(ncpus < 0);
- assert_se(!c);
+ assert_se(parse_cpu_set_full("0 1 2 3 garbage", &c, true, NULL, "fake", 1, "CPUAffinity") == -EINVAL);
+ assert_se(!c.set);
+ assert_se(c.allocated == 0);
/* Range with garbage */
- ncpus = parse_cpu_set_and_warn("0-3 8-garbage", &c, NULL, "fake", 1, "CPUAffinity");
- assert_se(ncpus < 0);
- assert_se(!c);
+ assert_se(parse_cpu_set_full("0-3 8-garbage", &c, true, NULL, "fake", 1, "CPUAffinity") == -EINVAL);
+ assert_se(!c.set);
+ assert_se(c.allocated == 0);
/* Empty string */
- c = NULL;
- ncpus = parse_cpu_set_and_warn("", &c, NULL, "fake", 1, "CPUAffinity");
- assert_se(ncpus == 0); /* empty string returns 0 */
- assert_se(!c);
+ assert_se(parse_cpu_set_full("", &c, true, NULL, "fake", 1, "CPUAffinity") == 0);
+ assert_se(!c.set); /* empty string returns NULL */
+ assert_se(c.allocated == 0);
/* Runaway quoted string */
- ncpus = parse_cpu_set_and_warn("0 1 2 3 \"4 5 6 7 ", &c, NULL, "fake", 1, "CPUAffinity");
- assert_se(ncpus < 0);
- assert_se(!c);
+ assert_se(parse_cpu_set_full("0 1 2 3 \"4 5 6 7 ", &c, true, NULL, "fake", 1, "CPUAffinity") == -EINVAL);
+ assert_se(!c.set);
+ assert_se(c.allocated == 0);
+
+ /* Maximum allocation */
+ assert_se(parse_cpu_set_full("8000-8191", &c, true, NULL, "fake", 1, "CPUAffinity") == 0);
+ assert_se(CPU_COUNT_S(c.allocated, c.set) == 192);
+ assert_se(str = cpu_set_to_string(&c));
+ log_info("cpu_set_to_string: %s", str);
+ str = mfree(str);
+ cpu_set_reset(&c);
}
int main(int argc, char *argv[]) {
+ log_info("CPU_ALLOC_SIZE(1) = %zu", CPU_ALLOC_SIZE(1));
+ log_info("CPU_ALLOC_SIZE(9) = %zu", CPU_ALLOC_SIZE(9));
+ log_info("CPU_ALLOC_SIZE(64) = %zu", CPU_ALLOC_SIZE(64));
+ log_info("CPU_ALLOC_SIZE(65) = %zu", CPU_ALLOC_SIZE(65));
+ log_info("CPU_ALLOC_SIZE(1024) = %zu", CPU_ALLOC_SIZE(1024));
+ log_info("CPU_ALLOC_SIZE(1025) = %zu", CPU_ALLOC_SIZE(1025));
+ log_info("CPU_ALLOC_SIZE(8191) = %zu", CPU_ALLOC_SIZE(8191));
+
test_parse_cpu_set();
return 0;