diff options
author | Matt Whitlock <gentoo@mattwhitlock.name> | 2021-07-31 17:41:57 -0400 |
---|---|---|
committer | William Hubbs <w.d.hubbs@gmail.com> | 2021-12-22 10:01:14 -0600 |
commit | fd1e4a384af44a8687b3a5369283f80f1cf29d84 (patch) | |
tree | 51890d0f27d3585553102c3783f369e62be74328 /src/rc/supervise-daemon.c | |
parent | dd5a6fa60f619f0db854d51efe8731946d3bfbf5 (diff) |
add option for OOM score adjustment
This commit adds a new --oom-score-adj option to start-stop-daemon and
supervise-daemon, as well as an equivalent SSD_OOM_SCORE_ADJ environment
variable. If either of these are specified (with the command-line
option taking precedence), then the specified adjustment value is
written to /proc/self/oom_score_adj after forking but prior to exec'ing
the daemon (at the time when nice and ionice are applied).
Additionally, per a suggestion by Mike Frysinger, the suggested values
for the SSD_NICELEVEL, SSD_IONICELEVEL, and SSD_OOM_SCORE_ADJ variables
in the example config file are now given as zeros, which are the
kernel's default values of these process knobs for the init process at
boot. Note that uncommenting any of these zero-valued suggestions will
cause SSD/SD to set the corresponding process knob affirmatively to
zero, whereas leaving the variable unset (and the equivalent command-
line option unspecified) means SSD/SD will not change the corresponding
process knob from its inherited value.
See: https://github.com/OpenRC/openrc/pull/435#discussion_r688310672
This fixes #435.
Diffstat (limited to 'src/rc/supervise-daemon.c')
-rw-r--r-- | src/rc/supervise-daemon.c | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/src/rc/supervise-daemon.c b/src/rc/supervise-daemon.c index 49b09c04..ddadb677 100644 --- a/src/rc/supervise-daemon.c +++ b/src/rc/supervise-daemon.c @@ -82,6 +82,7 @@ const struct option longopts[] = { { "umask", 1, NULL, 'k'}, { "respawn-max", 1, NULL, 'm'}, { "nicelevel", 1, NULL, 'N'}, + { "oom-score-adj",1, NULL,0x80}, { "pidfile", 1, NULL, 'p'}, { "respawn-period", 1, NULL, 'P'}, { "retry", 1, NULL, 'R'}, @@ -106,6 +107,7 @@ const char * const longopts_help[] = { "Set the umask for the daemon", "set maximum number of respawn attempts", "Set a nicelevel when starting", + "Set OOM score adjustment when starting", "Match pid found in this file", "Set respawn time period", "Retry schedule to use when stopping", @@ -124,9 +126,10 @@ static int healthcheckdelay = 0; static int healthchecktimer = 0; static volatile sig_atomic_t do_healthcheck = 0; static volatile sig_atomic_t exiting = 0; -static int nicelevel = 0; +static int nicelevel = INT_MIN; static int ionicec = -1; static int ioniced = 0; +static int oom_score_adj = INT_MIN; static char *changeuser, *ch_root, *ch_dir; static uid_t uid = 0; static gid_t gid = 0; @@ -332,6 +335,7 @@ static void child_process(char *exec, char **argv) time_t start_time; char start_count_string[20]; char start_time_string[20]; + FILE *fp; #ifdef HAVE_PAM pam_handle_t *pamh = NULL; @@ -351,7 +355,7 @@ static void child_process(char *exec, char **argv) rc_service_value_set(svcname, "child_pid", start_count_string); } - if (nicelevel) { + if (nicelevel != INT_MIN) { if (setpriority(PRIO_PROCESS, getpid(), nicelevel) == -1) eerrorx("%s: setpriority %d: %s", applet, nicelevel, strerror(errno)); @@ -361,6 +365,15 @@ static void child_process(char *exec, char **argv) eerrorx("%s: ioprio_set %d %d: %s", applet, ionicec, ioniced, strerror(errno)); + if (oom_score_adj != INT_MIN) { + fp = fopen("/proc/self/oom_score_adj", "w"); + if (!fp) + eerrorx("%s: oom_score_adj %d: %s", applet, + oom_score_adj, strerror(errno)); + fprintf(fp, "%d\n", oom_score_adj); + fclose(fp); + } + if (ch_root && chroot(ch_root) < 0) eerrorx("%s: chroot `%s': %s", applet, ch_root, strerror(errno)); @@ -424,7 +437,8 @@ static void child_process(char *exec, char **argv) strncmp(env->value, "RC_SERVICE=", 11) != 0 && strncmp(env->value, "RC_SVCNAME=", 11) != 0) || strncmp(env->value, "SSD_NICELEVEL=", 14) == 0 || - strncmp(env->value, "SSD_IONICELEVEL=", 16) == 0) + strncmp(env->value, "SSD_IONICELEVEL=", 16) == 0 || + strncmp(env->value, "SSD_OOM_SCORE_ADJ=", 18) == 0) { p = strchr(env->value, '='); *p = '\0'; @@ -745,6 +759,10 @@ int main(int argc, char **argv) ioniced = 7; ionicec <<= 13; /* class shift */ } + if ((tmp = getenv("SSD_OOM_SCORE_ADJ"))) + if (sscanf(tmp, "%d", &oom_score_adj) != 1) + eerror("%s: invalid oom_score_adj `%s' (SSD_OOM_SCORE_ADJ)", + applet, tmp); /* Get our user name and initial dir */ p = getenv("USER"); @@ -806,6 +824,12 @@ int main(int argc, char **argv) applet, optarg); break; + case 0x80: /* --oom-score-adj */ + if (sscanf(optarg, "%d", &oom_score_adj) != 1) + eerrorx("%s: invalid oom-score-adj `%s'", + applet, optarg); + break; + case 'P': /* --respawn-period time */ n = sscanf(optarg, "%d", &respawn_period); if (n != 1 || respawn_period < 1) |