diff --git a/etc/rc.conf b/etc/rc.conf index 11e8449a..e93eed59 100644 --- a/etc/rc.conf +++ b/etc/rc.conf @@ -116,10 +116,12 @@ # Some daemons are started and stopped via start-stop-daemon. # We can set some things on a per service basis, like the nicelevel. -#SSD_NICELEVEL="-19" +#SSD_NICELEVEL="0" # Or the ionice level. The format is class[:data] , just like the # --ionice start-stop-daemon parameter. -#SSD_IONICELEVEL="2:2" +#SSD_IONICELEVEL="0:0" +# Or the OOM score adjustment. +#SSD_OOM_SCORE_ADJ="0" # Pass ulimit parameters # If you are using bash in POSIX mode for your shell, note that the diff --git a/man/start-stop-daemon.8 b/man/start-stop-daemon.8 index d5eb5123..e5aa4684 100644 --- a/man/start-stop-daemon.8 +++ b/man/start-stop-daemon.8 @@ -128,6 +128,8 @@ Class can be 0 for none, 1 for real time, 2 for best effort and 3 for idle. Data can be from 0 to 7 inclusive. .It Fl N , -nicelevel Ar level Modifies the scheduling priority of the daemon. +.It Fl -oom-score-adj Ar adj +Modifies the OOM score adjustment of the daemon. .It Fl 1 , -stdout Ar logfile Redirect the standard output of the process to logfile when started with .Fl background . @@ -187,6 +189,10 @@ option takes precedence. can also set the scheduling priority of the daemon, but the command line option takes precedence. .Pp +.Va SSD_OOM_SCORE_ADJ +can also set the OOM score adjustment of the daemon, but the command line +option takes precedence. +.Pp .Va SSD_STARTWAIT As the .Fl w , -wait option above. diff --git a/man/supervise-daemon.8 b/man/supervise-daemon.8 index ffd64f97..69e2ff3f 100644 --- a/man/supervise-daemon.8 +++ b/man/supervise-daemon.8 @@ -37,6 +37,8 @@ servicename .Ar count .Fl N , -nicelevel .Ar level +.Fl -oom-score-adj +.Ar adj .Fl p , -pidfile .Ar supervisorpidfile .Fl P , -respawn-period @@ -129,6 +131,8 @@ Sets a path for the supervisor's pid file. Note that this is not the pid file of the process that is being supervised. .It Fl N , -nicelevel Ar level Modifies the scheduling priority of the daemon. +.It Fl -oom-score-adj Ar adj +Modifies the OOM score adjustment of the daemon. .It Fl P , -respawn-period Ar seconds Sets the length of a respawn period. See the description of --respawn-max for more information. @@ -163,6 +167,10 @@ option takes precedence. .Va SSD_NICELEVEL can also set the scheduling priority of the daemon, but the command line option takes precedence. +.Pp +.Va SSD_OOM_SCORE_ADJ +can also set the OOM score adjustment of the daemon, but the command line +option takes precedence. .Sh NOTE .Nm uses diff --git a/src/rc/start-stop-daemon.c b/src/rc/start-stop-daemon.c index e6febe82..62e579d1 100644 --- a/src/rc/start-stop-daemon.c +++ b/src/rc/start-stop-daemon.c @@ -72,6 +72,7 @@ const struct option longopts[] = { { "ionice", 1, NULL, 'I'}, { "stop", 0, NULL, 'K'}, { "nicelevel", 1, NULL, 'N'}, + { "oom-score-adj",1, NULL,0x80}, { "retry", 1, NULL, 'R'}, { "start", 0, NULL, 'S'}, { "startas", 1, NULL, 'a'}, @@ -103,6 +104,7 @@ const char * const longopts_help[] = { "Set an ionice class:data when starting", "Stop daemon", "Set a nicelevel when starting", + "Set OOM score adjustment when starting", "Retry schedule to use when stopping", "Start daemon", "deprecated, use --exec or --name", @@ -270,7 +272,8 @@ int main(int argc, char **argv) char *pidfile = NULL; char *retry = NULL; int sig = -1; - int nicelevel = 0, ionicec = -1, ioniced = 0; + int nicelevel = INT_MIN, ionicec = -1, ioniced = 0; + int oom_score_adj = INT_MIN; bool background = false; bool makepidfile = false; bool interpreted = false; @@ -327,6 +330,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"); @@ -367,6 +374,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': /* --progress */ progress = true; break; @@ -778,7 +791,7 @@ int main(int argc, char **argv) devnull_fd = open("/dev/null", O_RDWR); - if (nicelevel) { + if (nicelevel != INT_MIN) { if (setpriority(PRIO_PROCESS, mypid, nicelevel) == -1) eerrorx("%s: setpriority %d: %s", applet, nicelevel, @@ -790,6 +803,15 @@ int main(int argc, 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)); @@ -867,7 +889,8 @@ int main(int argc, 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'; 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)