]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/basic/cpu-set-util.c
tree-wide: remove Lennart's copyright lines
[thirdparty/systemd.git] / src / basic / cpu-set-util.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
618234a5 2/***
618234a5 3 Copyright 2015 Filipe Brandenburger
618234a5
LP
4***/
5
11c3a366
TA
6#include <errno.h>
7#include <stddef.h>
8#include <syslog.h>
9
b5efdb8a 10#include "alloc-util.h"
6bedfcbb 11#include "cpu-set-util.h"
84ac7bea 12#include "extract-word.h"
11c3a366
TA
13#include "log.h"
14#include "macro.h"
93cc7779 15#include "parse-util.h"
b11d6a7b 16#include "string-util.h"
618234a5
LP
17
18cpu_set_t* cpu_set_malloc(unsigned *ncpus) {
19 cpu_set_t *c;
20 unsigned n = 1024;
21
22 /* Allocates the cpuset in the right size */
23
24 for (;;) {
25 c = CPU_ALLOC(n);
26 if (!c)
27 return NULL;
28
29 if (sched_getaffinity(0, CPU_ALLOC_SIZE(n), c) >= 0) {
30 CPU_ZERO_S(CPU_ALLOC_SIZE(n), c);
31
32 if (ncpus)
33 *ncpus = n;
34
35 return c;
36 }
37
38 CPU_FREE(c);
39
40 if (errno != EINVAL)
41 return NULL;
42
43 n *= 2;
44 }
45}
46
6d8a29b2 47int parse_cpu_set_internal(
618234a5
LP
48 const char *rvalue,
49 cpu_set_t **cpu_set,
6d8a29b2 50 bool warn,
618234a5
LP
51 const char *unit,
52 const char *filename,
53 unsigned line,
54 const char *lvalue) {
55
618234a5 56 _cleanup_cpu_free_ cpu_set_t *c = NULL;
6d8a29b2 57 const char *p = rvalue;
618234a5
LP
58 unsigned ncpus = 0;
59
618234a5
LP
60 assert(rvalue);
61
62 for (;;) {
63 _cleanup_free_ char *word = NULL;
a26662ce 64 unsigned cpu, cpu_lower, cpu_upper;
618234a5
LP
65 int r;
66
6d8a29b2
YW
67 r = extract_first_word(&p, &word, WHITESPACE ",", EXTRACT_QUOTES);
68 if (r == -ENOMEM)
69 return warn ? log_oom() : -ENOMEM;
a26662ce 70 if (r < 0)
6d8a29b2 71 return warn ? log_syntax(unit, LOG_ERR, filename, line, r, "Invalid value for %s: %s", lvalue, rvalue) : r;
618234a5
LP
72 if (r == 0)
73 break;
74
75 if (!c) {
76 c = cpu_set_malloc(&ncpus);
77 if (!c)
6d8a29b2 78 return warn ? log_oom() : -ENOMEM;
618234a5
LP
79 }
80
a26662ce
FB
81 r = parse_range(word, &cpu_lower, &cpu_upper);
82 if (r < 0)
6d8a29b2 83 return warn ? log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse CPU affinity '%s'", word) : r;
a26662ce 84 if (cpu_lower >= ncpus || cpu_upper >= ncpus)
6d8a29b2 85 return warn ? log_syntax(unit, LOG_ERR, filename, line, EINVAL, "CPU out of range '%s' ncpus is %u", word, ncpus) : -EINVAL;
032cf8e4 86
6d8a29b2
YW
87 if (cpu_lower > cpu_upper) {
88 if (warn)
89 log_syntax(unit, LOG_WARNING, filename, line, 0, "Range '%s' is invalid, %u > %u, ignoring", word, cpu_lower, cpu_upper);
90 continue;
032cf8e4
YW
91 }
92
6d8a29b2
YW
93 for (cpu = cpu_lower; cpu <= cpu_upper; cpu++)
94 CPU_SET_S(cpu, CPU_ALLOC_SIZE(ncpus), c);
032cf8e4
YW
95 }
96
97 /* On success, sets *cpu_set and returns ncpus for the system. */
1cc6c93a
YW
98 if (c)
99 *cpu_set = TAKE_PTR(c);
032cf8e4
YW
100
101 return (int) ncpus;
102}