|
43 | 43 | #include "capability-util.h" |
44 | 44 | #include "cgroup-util.h" |
45 | 45 | #include "copy.h" |
| 46 | +#include "cpu-set-util.h" |
46 | 47 | #include "dev-setup.h" |
47 | 48 | #include "dissect-image.h" |
48 | 49 | #include "env-util.h" |
@@ -207,6 +208,8 @@ static struct rlimit *arg_rlimit[_RLIMIT_MAX] = {}; |
207 | 208 | static bool arg_no_new_privileges = false; |
208 | 209 | static int arg_oom_score_adjust = 0; |
209 | 210 | static bool arg_oom_score_adjust_set = false; |
| 211 | +static cpu_set_t *arg_cpuset = NULL; |
| 212 | +static unsigned arg_cpuset_ncpus = 0; |
210 | 213 |
|
211 | 214 | static void help(void) { |
212 | 215 |
|
@@ -278,6 +281,7 @@ static void help(void) { |
278 | 281 | " --rlimit=NAME=LIMIT Set a resource limit for the payload\n" |
279 | 282 | " --oom-score-adjust=VALUE\n" |
280 | 283 | " Adjust the OOM score value for the payload\n" |
| 284 | + " --cpu-affinity=CPUS Adjust the CPU affinity of the container\n" |
281 | 285 | " --kill-signal=SIGNAL Select signal to use for shutting down PID 1\n" |
282 | 286 | " --link-journal=MODE Link up guest journal, one of no, auto, guest, \n" |
283 | 287 | " host, try-guest, try-host\n" |
@@ -457,6 +461,7 @@ static int parse_argv(int argc, char *argv[]) { |
457 | 461 | ARG_HOSTNAME, |
458 | 462 | ARG_NO_NEW_PRIVILEGES, |
459 | 463 | ARG_OOM_SCORE_ADJUST, |
| 464 | + ARG_CPU_AFFINITY, |
460 | 465 | }; |
461 | 466 |
|
462 | 467 | static const struct option options[] = { |
@@ -514,6 +519,7 @@ static int parse_argv(int argc, char *argv[]) { |
514 | 519 | { "system-call-filter", required_argument, NULL, ARG_SYSTEM_CALL_FILTER }, |
515 | 520 | { "rlimit", required_argument, NULL, ARG_RLIMIT }, |
516 | 521 | { "oom-score-adjust", required_argument, NULL, ARG_OOM_SCORE_ADJUST }, |
| 522 | + { "cpu-affinity", required_argument, NULL, ARG_CPU_AFFINITY }, |
517 | 523 | {} |
518 | 524 | }; |
519 | 525 |
|
@@ -1186,6 +1192,22 @@ static int parse_argv(int argc, char *argv[]) { |
1186 | 1192 | arg_settings_mask |= SETTING_OOM_SCORE_ADJUST; |
1187 | 1193 | break; |
1188 | 1194 |
|
| 1195 | + case ARG_CPU_AFFINITY: { |
| 1196 | + _cleanup_cpu_free_ cpu_set_t *cpuset = NULL; |
| 1197 | + |
| 1198 | + r = parse_cpu_set(optarg, &cpuset); |
| 1199 | + if (r < 0) |
| 1200 | + return log_error_errno(r, "Failed to parse CPU affinity mask: %s", optarg); |
| 1201 | + |
| 1202 | + if (arg_cpuset) |
| 1203 | + CPU_FREE(arg_cpuset); |
| 1204 | + |
| 1205 | + arg_cpuset = TAKE_PTR(cpuset); |
| 1206 | + arg_cpuset_ncpus = r; |
| 1207 | + arg_settings_mask |= SETTING_CPU_AFFINITY; |
| 1208 | + break; |
| 1209 | + } |
| 1210 | + |
1189 | 1211 | case '?': |
1190 | 1212 | return -EINVAL; |
1191 | 1213 |
|
@@ -2476,6 +2498,10 @@ static int inner_child( |
2476 | 2498 | return log_error_errno(r, "Failed to adjust OOM score: %m"); |
2477 | 2499 | } |
2478 | 2500 |
|
| 2501 | + if (arg_cpuset) |
| 2502 | + if (sched_setaffinity(0, CPU_ALLOC_SIZE(arg_cpuset_ncpus), arg_cpuset) < 0) |
| 2503 | + return log_error_errno(errno, "Failed to set CPU affinity: %m"); |
| 2504 | + |
2479 | 2505 | r = drop_capabilities(); |
2480 | 2506 | if (r < 0) |
2481 | 2507 | return log_error_errno(r, "drop_capabilities() failed: %m"); |
@@ -3397,6 +3423,19 @@ static int load_settings(void) { |
3397 | 3423 | } |
3398 | 3424 | } |
3399 | 3425 |
|
| 3426 | + if ((arg_settings_mask & SETTING_CPU_AFFINITY) == 0 && |
| 3427 | + settings->cpuset) { |
| 3428 | + |
| 3429 | + if (!arg_settings_trusted) |
| 3430 | + log_warning("Ignoring CPUAffinity= setting, file '%s' is not trusted.", p); |
| 3431 | + else { |
| 3432 | + if (arg_cpuset) |
| 3433 | + CPU_FREE(arg_cpuset); |
| 3434 | + arg_cpuset = TAKE_PTR(settings->cpuset); |
| 3435 | + arg_cpuset_ncpus = settings->cpuset_ncpus; |
| 3436 | + } |
| 3437 | + } |
| 3438 | + |
3400 | 3439 | return 0; |
3401 | 3440 | } |
3402 | 3441 |
|
@@ -4375,6 +4414,7 @@ int main(int argc, char *argv[]) { |
4375 | 4414 | expose_port_free_all(arg_expose_ports); |
4376 | 4415 | free(arg_root_hash); |
4377 | 4416 | rlimit_free_all(arg_rlimit); |
| 4417 | + arg_cpuset = cpu_set_mfree(arg_cpuset); |
4378 | 4418 |
|
4379 | 4419 | return r < 0 ? EXIT_FAILURE : ret; |
4380 | 4420 | } |
0 commit comments