mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-12-23 17:34:00 +03:00
nspawn: add a new --cpu-affinity= switch
Similar as the other options added before, this is primarily useful to provide comprehensive OCI runtime compatbility, but might be useful otherwise, too.
This commit is contained in:
parent
50ebcf6cb7
commit
d107bb7d63
@ -796,6 +796,15 @@
|
|||||||
integer in the range -1000…1000.</para></listitem>
|
integer in the range -1000…1000.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--cpu-affinity=</option></term>
|
||||||
|
|
||||||
|
<listitem><para>Controls the CPU affinity of the container payload. Takes a comma separated list of CPU numbers
|
||||||
|
or number ranges (the latter's start and end value separated by dashes). See <citerefentry
|
||||||
|
project='man-pages'><refentrytitle>sched_setaffinity</refentrytitle><manvolnum>2</manvolnum></citerefentry> for
|
||||||
|
details.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>--kill-signal=</option></term>
|
<term><option>--kill-signal=</option></term>
|
||||||
|
|
||||||
|
@ -322,6 +322,15 @@
|
|||||||
details.</para></listitem>
|
details.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>CPUAffinity=</varname></term>
|
||||||
|
|
||||||
|
<listitem><para>Configures the CPU affinity. This is equivalent to the <option>--cpu-affinity=</option> command
|
||||||
|
line switch, and takes the same argument. See
|
||||||
|
<citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry> for
|
||||||
|
details.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>Hostname=</varname></term>
|
<term><varname>Hostname=</varname></term>
|
||||||
|
|
||||||
|
@ -52,6 +52,7 @@ Exec.LimitRTTIME, config_parse_rlimit, RLIMIT_RTTIME, of
|
|||||||
Exec.Hostname, config_parse_hostname, 0, offsetof(Settings, hostname)
|
Exec.Hostname, config_parse_hostname, 0, offsetof(Settings, hostname)
|
||||||
Exec.NoNewPrivileges, config_parse_tristate, 0, offsetof(Settings, no_new_privileges)
|
Exec.NoNewPrivileges, config_parse_tristate, 0, offsetof(Settings, no_new_privileges)
|
||||||
Exec.OOMScoreAdjust, config_parse_oom_score_adjust, 0, 0
|
Exec.OOMScoreAdjust, config_parse_oom_score_adjust, 0, 0
|
||||||
|
Exec.CPUAffinity, config_parse_cpu_affinity, 0, 0
|
||||||
Files.ReadOnly, config_parse_tristate, 0, offsetof(Settings, read_only)
|
Files.ReadOnly, config_parse_tristate, 0, offsetof(Settings, read_only)
|
||||||
Files.Volatile, config_parse_volatile_mode, 0, offsetof(Settings, volatile_mode)
|
Files.Volatile, config_parse_volatile_mode, 0, offsetof(Settings, volatile_mode)
|
||||||
Files.Bind, config_parse_bind, 0, 0
|
Files.Bind, config_parse_bind, 0, 0
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include "alloc-util.h"
|
#include "alloc-util.h"
|
||||||
#include "cap-list.h"
|
#include "cap-list.h"
|
||||||
#include "conf-parser.h"
|
#include "conf-parser.h"
|
||||||
|
#include "cpu-set-util.h"
|
||||||
#include "hostname-util.h"
|
#include "hostname-util.h"
|
||||||
#include "nspawn-network.h"
|
#include "nspawn-network.h"
|
||||||
#include "nspawn-settings.h"
|
#include "nspawn-settings.h"
|
||||||
@ -85,6 +86,7 @@ Settings* settings_free(Settings *s) {
|
|||||||
strv_free(s->syscall_blacklist);
|
strv_free(s->syscall_blacklist);
|
||||||
rlimit_free_all(s->rlimit);
|
rlimit_free_all(s->rlimit);
|
||||||
free(s->hostname);
|
free(s->hostname);
|
||||||
|
s->cpuset = cpu_set_mfree(s->cpuset);
|
||||||
|
|
||||||
strv_free(s->network_interfaces);
|
strv_free(s->network_interfaces);
|
||||||
strv_free(s->network_macvlan);
|
strv_free(s->network_macvlan);
|
||||||
@ -673,3 +675,52 @@ int config_parse_oom_score_adjust(
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int config_parse_cpu_affinity(
|
||||||
|
const char *unit,
|
||||||
|
const char *filename,
|
||||||
|
unsigned line,
|
||||||
|
const char *section,
|
||||||
|
unsigned section_line,
|
||||||
|
const char *lvalue,
|
||||||
|
int ltype,
|
||||||
|
const char *rvalue,
|
||||||
|
void *data,
|
||||||
|
void *userdata) {
|
||||||
|
|
||||||
|
_cleanup_cpu_free_ cpu_set_t *cpuset = NULL;
|
||||||
|
Settings *settings = data;
|
||||||
|
int ncpus;
|
||||||
|
|
||||||
|
assert(rvalue);
|
||||||
|
assert(settings);
|
||||||
|
|
||||||
|
ncpus = parse_cpu_set_and_warn(rvalue, &cpuset, unit, filename, line, lvalue);
|
||||||
|
if (ncpus < 0)
|
||||||
|
return ncpus;
|
||||||
|
|
||||||
|
if (ncpus == 0) {
|
||||||
|
/* An empty assignment resets the CPU list */
|
||||||
|
settings->cpuset = cpu_set_mfree(settings->cpuset);
|
||||||
|
settings->cpuset_ncpus = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!settings->cpuset) {
|
||||||
|
settings->cpuset = TAKE_PTR(cpuset);
|
||||||
|
settings->cpuset_ncpus = (unsigned) ncpus;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings->cpuset_ncpus < (unsigned) ncpus) {
|
||||||
|
CPU_OR_S(CPU_ALLOC_SIZE(settings->cpuset_ncpus), cpuset, settings->cpuset, cpuset);
|
||||||
|
CPU_FREE(settings->cpuset);
|
||||||
|
settings->cpuset = TAKE_PTR(cpuset);
|
||||||
|
settings->cpuset_ncpus = (unsigned) ncpus;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CPU_OR_S(CPU_ALLOC_SIZE((unsigned) ncpus), settings->cpuset, settings->cpuset, cpuset);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
Copyright 2015 Lennart Poettering
|
Copyright 2015 Lennart Poettering
|
||||||
***/
|
***/
|
||||||
|
|
||||||
|
#include <sched.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "sd-id128.h"
|
#include "sd-id128.h"
|
||||||
@ -52,9 +53,10 @@ typedef enum SettingsMask {
|
|||||||
SETTING_HOSTNAME = UINT64_C(1) << 17,
|
SETTING_HOSTNAME = UINT64_C(1) << 17,
|
||||||
SETTING_NO_NEW_PRIVILEGES = UINT64_C(1) << 18,
|
SETTING_NO_NEW_PRIVILEGES = UINT64_C(1) << 18,
|
||||||
SETTING_OOM_SCORE_ADJUST = UINT64_C(1) << 19,
|
SETTING_OOM_SCORE_ADJUST = UINT64_C(1) << 19,
|
||||||
SETTING_RLIMIT_FIRST = UINT64_C(1) << 20, /* we define one bit per resource limit here */
|
SETTING_CPU_AFFINITY = UINT64_C(1) << 20,
|
||||||
SETTING_RLIMIT_LAST = UINT64_C(1) << (20 + _RLIMIT_MAX - 1),
|
SETTING_RLIMIT_FIRST = UINT64_C(1) << 21, /* we define one bit per resource limit here */
|
||||||
_SETTINGS_MASK_ALL = (UINT64_C(1) << (20 + _RLIMIT_MAX)) - 1
|
SETTING_RLIMIT_LAST = UINT64_C(1) << (21 + _RLIMIT_MAX - 1),
|
||||||
|
_SETTINGS_MASK_ALL = (UINT64_C(1) << (21 + _RLIMIT_MAX)) - 1
|
||||||
} SettingsMask;
|
} SettingsMask;
|
||||||
|
|
||||||
typedef struct Settings {
|
typedef struct Settings {
|
||||||
@ -81,6 +83,8 @@ typedef struct Settings {
|
|||||||
int no_new_privileges;
|
int no_new_privileges;
|
||||||
int oom_score_adjust;
|
int oom_score_adjust;
|
||||||
bool oom_score_adjust_set;
|
bool oom_score_adjust_set;
|
||||||
|
cpu_set_t *cpuset;
|
||||||
|
unsigned cpuset_ncpus;
|
||||||
|
|
||||||
/* [Image] */
|
/* [Image] */
|
||||||
int read_only;
|
int read_only;
|
||||||
@ -127,3 +131,4 @@ int config_parse_private_users(const char *unit, const char *filename, unsigned
|
|||||||
int config_parse_syscall_filter(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
int config_parse_syscall_filter(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
||||||
int config_parse_hostname(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
int config_parse_hostname(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
||||||
int config_parse_oom_score_adjust(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
int config_parse_oom_score_adjust(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
||||||
|
int config_parse_cpu_affinity(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
#include "capability-util.h"
|
#include "capability-util.h"
|
||||||
#include "cgroup-util.h"
|
#include "cgroup-util.h"
|
||||||
#include "copy.h"
|
#include "copy.h"
|
||||||
|
#include "cpu-set-util.h"
|
||||||
#include "dev-setup.h"
|
#include "dev-setup.h"
|
||||||
#include "dissect-image.h"
|
#include "dissect-image.h"
|
||||||
#include "env-util.h"
|
#include "env-util.h"
|
||||||
@ -207,6 +208,8 @@ static struct rlimit *arg_rlimit[_RLIMIT_MAX] = {};
|
|||||||
static bool arg_no_new_privileges = false;
|
static bool arg_no_new_privileges = false;
|
||||||
static int arg_oom_score_adjust = 0;
|
static int arg_oom_score_adjust = 0;
|
||||||
static bool arg_oom_score_adjust_set = false;
|
static bool arg_oom_score_adjust_set = false;
|
||||||
|
static cpu_set_t *arg_cpuset = NULL;
|
||||||
|
static unsigned arg_cpuset_ncpus = 0;
|
||||||
|
|
||||||
static void help(void) {
|
static void help(void) {
|
||||||
|
|
||||||
@ -278,6 +281,7 @@ static void help(void) {
|
|||||||
" --rlimit=NAME=LIMIT Set a resource limit for the payload\n"
|
" --rlimit=NAME=LIMIT Set a resource limit for the payload\n"
|
||||||
" --oom-score-adjust=VALUE\n"
|
" --oom-score-adjust=VALUE\n"
|
||||||
" Adjust the OOM score value for the payload\n"
|
" Adjust the OOM score value for the payload\n"
|
||||||
|
" --cpu-affinity=CPUS Adjust the CPU affinity of the container\n"
|
||||||
" --kill-signal=SIGNAL Select signal to use for shutting down PID 1\n"
|
" --kill-signal=SIGNAL Select signal to use for shutting down PID 1\n"
|
||||||
" --link-journal=MODE Link up guest journal, one of no, auto, guest, \n"
|
" --link-journal=MODE Link up guest journal, one of no, auto, guest, \n"
|
||||||
" host, try-guest, try-host\n"
|
" host, try-guest, try-host\n"
|
||||||
@ -457,6 +461,7 @@ static int parse_argv(int argc, char *argv[]) {
|
|||||||
ARG_HOSTNAME,
|
ARG_HOSTNAME,
|
||||||
ARG_NO_NEW_PRIVILEGES,
|
ARG_NO_NEW_PRIVILEGES,
|
||||||
ARG_OOM_SCORE_ADJUST,
|
ARG_OOM_SCORE_ADJUST,
|
||||||
|
ARG_CPU_AFFINITY,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct option options[] = {
|
static const struct option options[] = {
|
||||||
@ -514,6 +519,7 @@ static int parse_argv(int argc, char *argv[]) {
|
|||||||
{ "system-call-filter", required_argument, NULL, ARG_SYSTEM_CALL_FILTER },
|
{ "system-call-filter", required_argument, NULL, ARG_SYSTEM_CALL_FILTER },
|
||||||
{ "rlimit", required_argument, NULL, ARG_RLIMIT },
|
{ "rlimit", required_argument, NULL, ARG_RLIMIT },
|
||||||
{ "oom-score-adjust", required_argument, NULL, ARG_OOM_SCORE_ADJUST },
|
{ "oom-score-adjust", required_argument, NULL, ARG_OOM_SCORE_ADJUST },
|
||||||
|
{ "cpu-affinity", required_argument, NULL, ARG_CPU_AFFINITY },
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1186,6 +1192,22 @@ static int parse_argv(int argc, char *argv[]) {
|
|||||||
arg_settings_mask |= SETTING_OOM_SCORE_ADJUST;
|
arg_settings_mask |= SETTING_OOM_SCORE_ADJUST;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ARG_CPU_AFFINITY: {
|
||||||
|
_cleanup_cpu_free_ cpu_set_t *cpuset = NULL;
|
||||||
|
|
||||||
|
r = parse_cpu_set(optarg, &cpuset);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to parse CPU affinity mask: %s", optarg);
|
||||||
|
|
||||||
|
if (arg_cpuset)
|
||||||
|
CPU_FREE(arg_cpuset);
|
||||||
|
|
||||||
|
arg_cpuset = TAKE_PTR(cpuset);
|
||||||
|
arg_cpuset_ncpus = r;
|
||||||
|
arg_settings_mask |= SETTING_CPU_AFFINITY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case '?':
|
case '?':
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
@ -2476,6 +2498,10 @@ static int inner_child(
|
|||||||
return log_error_errno(r, "Failed to adjust OOM score: %m");
|
return log_error_errno(r, "Failed to adjust OOM score: %m");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (arg_cpuset)
|
||||||
|
if (sched_setaffinity(0, CPU_ALLOC_SIZE(arg_cpuset_ncpus), arg_cpuset) < 0)
|
||||||
|
return log_error_errno(errno, "Failed to set CPU affinity: %m");
|
||||||
|
|
||||||
r = drop_capabilities();
|
r = drop_capabilities();
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "drop_capabilities() failed: %m");
|
return log_error_errno(r, "drop_capabilities() failed: %m");
|
||||||
@ -3397,6 +3423,19 @@ static int load_settings(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((arg_settings_mask & SETTING_CPU_AFFINITY) == 0 &&
|
||||||
|
settings->cpuset) {
|
||||||
|
|
||||||
|
if (!arg_settings_trusted)
|
||||||
|
log_warning("Ignoring CPUAffinity= setting, file '%s' is not trusted.", p);
|
||||||
|
else {
|
||||||
|
if (arg_cpuset)
|
||||||
|
CPU_FREE(arg_cpuset);
|
||||||
|
arg_cpuset = TAKE_PTR(settings->cpuset);
|
||||||
|
arg_cpuset_ncpus = settings->cpuset_ncpus;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4375,6 +4414,7 @@ finish:
|
|||||||
expose_port_free_all(arg_expose_ports);
|
expose_port_free_all(arg_expose_ports);
|
||||||
free(arg_root_hash);
|
free(arg_root_hash);
|
||||||
rlimit_free_all(arg_rlimit);
|
rlimit_free_all(arg_rlimit);
|
||||||
|
arg_cpuset = cpu_set_mfree(arg_cpuset);
|
||||||
|
|
||||||
return r < 0 ? EXIT_FAILURE : ret;
|
return r < 0 ? EXIT_FAILURE : ret;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user