From: Lennart Poettering Date: Mon, 7 May 2018 19:17:09 +0000 (+0200) Subject: nspawn: add a new --oom-score-adjust= command line switch X-Git-Tag: v239~243^2~5 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=81f345dfed63b660ee7b31e0f3737995cf78470f;p=thirdparty%2Fsystemd.git nspawn: add a new --oom-score-adjust= command line switch This is primarily useful in order to provide comprehensive OCI runtime compatibility with nspawn, but might have uses outside of it. --- diff --git a/man/systemd-nspawn.xml b/man/systemd-nspawn.xml index 7f2b755eabe..22bb3b705b2 100644 --- a/man/systemd-nspawn.xml +++ b/man/systemd-nspawn.xml @@ -786,6 +786,16 @@ --rlimit=RLIMIT_NOFILE=8192:16384. + + + + Changes the OOM ("Out Of Memory") score adjustment value for the container payload. This controls + /proc/self/oom_score_adj which influences the preference with which this container is + terminated when memory becomes scarce. For details see proc5. Takes an + integer in the range -1000…1000. + + diff --git a/man/systemd.nspawn.xml b/man/systemd.nspawn.xml index 436f8cd0e99..748a633a337 100644 --- a/man/systemd.nspawn.xml +++ b/man/systemd.nspawn.xml @@ -313,6 +313,15 @@ details. + + OOMScoreAdjust= + + Configures the OOM score adjustment value. This is equivalent to the + command line switch, and takes the same argument. See + systemd-nspawn1 for + details. + + Hostname= diff --git a/src/nspawn/nspawn-gperf.gperf b/src/nspawn/nspawn-gperf.gperf index a3759674ef9..de00dbc243f 100644 --- a/src/nspawn/nspawn-gperf.gperf +++ b/src/nspawn/nspawn-gperf.gperf @@ -51,6 +51,7 @@ Exec.LimitRTPRIO, config_parse_rlimit, RLIMIT_RTPRIO, of Exec.LimitRTTIME, config_parse_rlimit, RLIMIT_RTTIME, offsetof(Settings, rlimit) Exec.Hostname, config_parse_hostname, 0, offsetof(Settings, hostname) Exec.NoNewPrivileges, config_parse_tristate, 0, offsetof(Settings, no_new_privileges) +Exec.OOMScoreAdjust, config_parse_oom_score_adjust, 0, 0 Files.ReadOnly, config_parse_tristate, 0, offsetof(Settings, read_only) Files.Volatile, config_parse_volatile_mode, 0, offsetof(Settings, volatile_mode) Files.Bind, config_parse_bind, 0, 0 diff --git a/src/nspawn/nspawn-settings.c b/src/nspawn/nspawn-settings.c index 11a2f41b961..c91ac73e2e7 100644 --- a/src/nspawn/nspawn-settings.c +++ b/src/nspawn/nspawn-settings.c @@ -634,3 +634,42 @@ int config_parse_hostname( return 0; } + +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) { + + Settings *settings = data; + int oa, r; + + assert(rvalue); + assert(settings); + + if (isempty(rvalue)) { + settings->oom_score_adjust_set = false; + return 0; + } + + r = parse_oom_score_adjust(rvalue, &oa); + if (r == -ERANGE) { + log_syntax(unit, LOG_ERR, filename, line, r, "OOM score adjust value out of range, ignoring: %s", rvalue); + return 0; + } + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse the OOM score adjust value, ignoring: %s", rvalue); + return 0; + } + + settings->oom_score_adjust = oa; + settings->oom_score_adjust_set = true; + + return 0; +} diff --git a/src/nspawn/nspawn-settings.h b/src/nspawn/nspawn-settings.h index 130331ee18f..7cf5be625b5 100644 --- a/src/nspawn/nspawn-settings.h +++ b/src/nspawn/nspawn-settings.h @@ -51,9 +51,10 @@ typedef enum SettingsMask { SETTING_SYSCALL_FILTER = UINT64_C(1) << 16, SETTING_HOSTNAME = UINT64_C(1) << 17, SETTING_NO_NEW_PRIVILEGES = UINT64_C(1) << 18, - SETTING_RLIMIT_FIRST = UINT64_C(1) << 19, /* we define one bit per resource limit here */ - SETTING_RLIMIT_LAST = UINT64_C(1) << (19 + _RLIMIT_MAX - 1), - _SETTINGS_MASK_ALL = (UINT64_C(1) << (19 + _RLIMIT_MAX)) - 1 + SETTING_OOM_SCORE_ADJUST = UINT64_C(1) << 19, + SETTING_RLIMIT_FIRST = UINT64_C(1) << 20, /* we define one bit per resource limit here */ + SETTING_RLIMIT_LAST = UINT64_C(1) << (20 + _RLIMIT_MAX - 1), + _SETTINGS_MASK_ALL = (UINT64_C(1) << (20 + _RLIMIT_MAX)) - 1 } SettingsMask; typedef struct Settings { @@ -78,6 +79,8 @@ typedef struct Settings { struct rlimit *rlimit[_RLIMIT_MAX]; char *hostname; int no_new_privileges; + int oom_score_adjust; + bool oom_score_adjust_set; /* [Image] */ int read_only; @@ -123,3 +126,4 @@ int config_parse_pid2(const char *unit, const char *filename, unsigned line, con int config_parse_private_users(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_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); diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index a7b35abd6bb..21d63987ec9 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -204,6 +204,8 @@ static char **arg_syscall_whitelist = NULL; static char **arg_syscall_blacklist = NULL; static struct rlimit *arg_rlimit[_RLIMIT_MAX] = {}; static bool arg_no_new_privileges = false; +static int arg_oom_score_adjust = 0; +static bool arg_oom_score_adjust_set = false; static void help(void) { printf("%s [OPTIONS...] [PATH] [ARGUMENTS...]\n\n" @@ -270,6 +272,8 @@ static void help(void) { " --system-call-filter=LIST|~LIST\n" " Permit/prohibit specific system calls\n" " --rlimit=NAME=LIMIT Set a resource limit for the payload\n" + " --oom-score-adjust=VALUE\n" + " Adjust the OOM score value for the payload\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" " host, try-guest, try-host\n" @@ -448,6 +452,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_RLIMIT, ARG_HOSTNAME, ARG_NO_NEW_PRIVILEGES, + ARG_OOM_SCORE_ADJUST, }; static const struct option options[] = { @@ -504,6 +509,7 @@ static int parse_argv(int argc, char *argv[]) { { "root-hash", required_argument, NULL, ARG_ROOT_HASH }, { "system-call-filter", required_argument, NULL, ARG_SYSTEM_CALL_FILTER }, { "rlimit", required_argument, NULL, ARG_RLIMIT }, + { "oom-score-adjust", required_argument, NULL, ARG_OOM_SCORE_ADJUST }, {} }; @@ -1167,6 +1173,15 @@ static int parse_argv(int argc, char *argv[]) { break; } + case ARG_OOM_SCORE_ADJUST: + r = parse_oom_score_adjust(optarg, &arg_oom_score_adjust); + if (r < 0) + return log_error_errno(r, "Failed to parse --oom-score-adjust= parameter: %s", optarg); + + arg_oom_score_adjust_set = true; + arg_settings_mask |= SETTING_OOM_SCORE_ADJUST; + break; + case '?': return -EINVAL; @@ -2451,6 +2466,12 @@ static int inner_child( rtnl_socket = safe_close(rtnl_socket); } + if (arg_oom_score_adjust_set) { + r = set_oom_score_adjust(arg_oom_score_adjust); + if (r < 0) + return log_error_errno(r, "Failed to adjust OOM score: %m"); + } + r = drop_capabilities(); if (r < 0) return log_error_errno(r, "drop_capabilities() failed: %m"); @@ -3361,6 +3382,17 @@ static int load_settings(void) { settings->no_new_privileges >= 0) arg_no_new_privileges = settings->no_new_privileges; + if ((arg_settings_mask & SETTING_OOM_SCORE_ADJUST) == 0 && + settings->oom_score_adjust_set) { + + if (!arg_settings_trusted) + log_warning("Ignoring OOMScoreAdjust= setting, file '%s' is not trusted.", p); + else { + arg_oom_score_adjust = settings->oom_score_adjust; + arg_oom_score_adjust_set = true; + } + } + return 0; }