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.
This commit is contained in:
parent
dd5a6fa60f
commit
fd1e4a384a
@ -116,10 +116,12 @@
|
|||||||
|
|
||||||
# Some daemons are started and stopped via start-stop-daemon.
|
# Some daemons are started and stopped via start-stop-daemon.
|
||||||
# We can set some things on a per service basis, like the nicelevel.
|
# 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
|
# Or the ionice level. The format is class[:data] , just like the
|
||||||
# --ionice start-stop-daemon parameter.
|
# --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
|
# Pass ulimit parameters
|
||||||
# If you are using bash in POSIX mode for your shell, note that the
|
# If you are using bash in POSIX mode for your shell, note that the
|
||||||
|
@ -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.
|
Data can be from 0 to 7 inclusive.
|
||||||
.It Fl N , -nicelevel Ar level
|
.It Fl N , -nicelevel Ar level
|
||||||
Modifies the scheduling priority of the daemon.
|
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
|
.It Fl 1 , -stdout Ar logfile
|
||||||
Redirect the standard output of the process to logfile when started with
|
Redirect the standard output of the process to logfile when started with
|
||||||
.Fl background .
|
.Fl background .
|
||||||
@ -187,6 +189,10 @@ option takes precedence.
|
|||||||
can also set the scheduling priority of the daemon, but the command line
|
can also set the scheduling priority of the daemon, but the command line
|
||||||
option takes precedence.
|
option takes precedence.
|
||||||
.Pp
|
.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
|
.Va SSD_STARTWAIT
|
||||||
As the
|
As the
|
||||||
.Fl w , -wait option above.
|
.Fl w , -wait option above.
|
||||||
|
@ -37,6 +37,8 @@ servicename
|
|||||||
.Ar count
|
.Ar count
|
||||||
.Fl N , -nicelevel
|
.Fl N , -nicelevel
|
||||||
.Ar level
|
.Ar level
|
||||||
|
.Fl -oom-score-adj
|
||||||
|
.Ar adj
|
||||||
.Fl p , -pidfile
|
.Fl p , -pidfile
|
||||||
.Ar supervisorpidfile
|
.Ar supervisorpidfile
|
||||||
.Fl P , -respawn-period
|
.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.
|
file of the process that is being supervised.
|
||||||
.It Fl N , -nicelevel Ar level
|
.It Fl N , -nicelevel Ar level
|
||||||
Modifies the scheduling priority of the daemon.
|
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
|
.It Fl P , -respawn-period Ar seconds
|
||||||
Sets the length of a respawn period. See the
|
Sets the length of a respawn period. See the
|
||||||
description of --respawn-max for more information.
|
description of --respawn-max for more information.
|
||||||
@ -163,6 +167,10 @@ option takes precedence.
|
|||||||
.Va SSD_NICELEVEL
|
.Va SSD_NICELEVEL
|
||||||
can also set the scheduling priority of the daemon, but the command line
|
can also set the scheduling priority of the daemon, but the command line
|
||||||
option takes precedence.
|
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
|
.Sh NOTE
|
||||||
.Nm
|
.Nm
|
||||||
uses
|
uses
|
||||||
|
@ -72,6 +72,7 @@ const struct option longopts[] = {
|
|||||||
{ "ionice", 1, NULL, 'I'},
|
{ "ionice", 1, NULL, 'I'},
|
||||||
{ "stop", 0, NULL, 'K'},
|
{ "stop", 0, NULL, 'K'},
|
||||||
{ "nicelevel", 1, NULL, 'N'},
|
{ "nicelevel", 1, NULL, 'N'},
|
||||||
|
{ "oom-score-adj",1, NULL,0x80},
|
||||||
{ "retry", 1, NULL, 'R'},
|
{ "retry", 1, NULL, 'R'},
|
||||||
{ "start", 0, NULL, 'S'},
|
{ "start", 0, NULL, 'S'},
|
||||||
{ "startas", 1, NULL, 'a'},
|
{ "startas", 1, NULL, 'a'},
|
||||||
@ -103,6 +104,7 @@ const char * const longopts_help[] = {
|
|||||||
"Set an ionice class:data when starting",
|
"Set an ionice class:data when starting",
|
||||||
"Stop daemon",
|
"Stop daemon",
|
||||||
"Set a nicelevel when starting",
|
"Set a nicelevel when starting",
|
||||||
|
"Set OOM score adjustment when starting",
|
||||||
"Retry schedule to use when stopping",
|
"Retry schedule to use when stopping",
|
||||||
"Start daemon",
|
"Start daemon",
|
||||||
"deprecated, use --exec or --name",
|
"deprecated, use --exec or --name",
|
||||||
@ -270,7 +272,8 @@ int main(int argc, char **argv)
|
|||||||
char *pidfile = NULL;
|
char *pidfile = NULL;
|
||||||
char *retry = NULL;
|
char *retry = NULL;
|
||||||
int sig = -1;
|
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 background = false;
|
||||||
bool makepidfile = false;
|
bool makepidfile = false;
|
||||||
bool interpreted = false;
|
bool interpreted = false;
|
||||||
@ -327,6 +330,10 @@ int main(int argc, char **argv)
|
|||||||
ioniced = 7;
|
ioniced = 7;
|
||||||
ionicec <<= 13; /* class shift */
|
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 */
|
/* Get our user name and initial dir */
|
||||||
p = getenv("USER");
|
p = getenv("USER");
|
||||||
@ -367,6 +374,12 @@ int main(int argc, char **argv)
|
|||||||
applet, optarg);
|
applet, optarg);
|
||||||
break;
|
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 */
|
case 'P': /* --progress */
|
||||||
progress = true;
|
progress = true;
|
||||||
break;
|
break;
|
||||||
@ -778,7 +791,7 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
devnull_fd = open("/dev/null", O_RDWR);
|
devnull_fd = open("/dev/null", O_RDWR);
|
||||||
|
|
||||||
if (nicelevel) {
|
if (nicelevel != INT_MIN) {
|
||||||
if (setpriority(PRIO_PROCESS, mypid, nicelevel) == -1)
|
if (setpriority(PRIO_PROCESS, mypid, nicelevel) == -1)
|
||||||
eerrorx("%s: setpriority %d: %s",
|
eerrorx("%s: setpriority %d: %s",
|
||||||
applet, nicelevel,
|
applet, nicelevel,
|
||||||
@ -790,6 +803,15 @@ int main(int argc, char **argv)
|
|||||||
eerrorx("%s: ioprio_set %d %d: %s", applet,
|
eerrorx("%s: ioprio_set %d %d: %s", applet,
|
||||||
ionicec, ioniced, strerror(errno));
|
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)
|
if (ch_root && chroot(ch_root) < 0)
|
||||||
eerrorx("%s: chroot `%s': %s",
|
eerrorx("%s: chroot `%s': %s",
|
||||||
applet, ch_root, strerror(errno));
|
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_SERVICE=", 11) != 0 &&
|
||||||
strncmp(env->value, "RC_SVCNAME=", 11) != 0) ||
|
strncmp(env->value, "RC_SVCNAME=", 11) != 0) ||
|
||||||
strncmp(env->value, "SSD_NICELEVEL=", 14) == 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 = strchr(env->value, '=');
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
|
@ -82,6 +82,7 @@ const struct option longopts[] = {
|
|||||||
{ "umask", 1, NULL, 'k'},
|
{ "umask", 1, NULL, 'k'},
|
||||||
{ "respawn-max", 1, NULL, 'm'},
|
{ "respawn-max", 1, NULL, 'm'},
|
||||||
{ "nicelevel", 1, NULL, 'N'},
|
{ "nicelevel", 1, NULL, 'N'},
|
||||||
|
{ "oom-score-adj",1, NULL,0x80},
|
||||||
{ "pidfile", 1, NULL, 'p'},
|
{ "pidfile", 1, NULL, 'p'},
|
||||||
{ "respawn-period", 1, NULL, 'P'},
|
{ "respawn-period", 1, NULL, 'P'},
|
||||||
{ "retry", 1, NULL, 'R'},
|
{ "retry", 1, NULL, 'R'},
|
||||||
@ -106,6 +107,7 @@ const char * const longopts_help[] = {
|
|||||||
"Set the umask for the daemon",
|
"Set the umask for the daemon",
|
||||||
"set maximum number of respawn attempts",
|
"set maximum number of respawn attempts",
|
||||||
"Set a nicelevel when starting",
|
"Set a nicelevel when starting",
|
||||||
|
"Set OOM score adjustment when starting",
|
||||||
"Match pid found in this file",
|
"Match pid found in this file",
|
||||||
"Set respawn time period",
|
"Set respawn time period",
|
||||||
"Retry schedule to use when stopping",
|
"Retry schedule to use when stopping",
|
||||||
@ -124,9 +126,10 @@ static int healthcheckdelay = 0;
|
|||||||
static int healthchecktimer = 0;
|
static int healthchecktimer = 0;
|
||||||
static volatile sig_atomic_t do_healthcheck = 0;
|
static volatile sig_atomic_t do_healthcheck = 0;
|
||||||
static volatile sig_atomic_t exiting = 0;
|
static volatile sig_atomic_t exiting = 0;
|
||||||
static int nicelevel = 0;
|
static int nicelevel = INT_MIN;
|
||||||
static int ionicec = -1;
|
static int ionicec = -1;
|
||||||
static int ioniced = 0;
|
static int ioniced = 0;
|
||||||
|
static int oom_score_adj = INT_MIN;
|
||||||
static char *changeuser, *ch_root, *ch_dir;
|
static char *changeuser, *ch_root, *ch_dir;
|
||||||
static uid_t uid = 0;
|
static uid_t uid = 0;
|
||||||
static gid_t gid = 0;
|
static gid_t gid = 0;
|
||||||
@ -332,6 +335,7 @@ static void child_process(char *exec, char **argv)
|
|||||||
time_t start_time;
|
time_t start_time;
|
||||||
char start_count_string[20];
|
char start_count_string[20];
|
||||||
char start_time_string[20];
|
char start_time_string[20];
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
#ifdef HAVE_PAM
|
#ifdef HAVE_PAM
|
||||||
pam_handle_t *pamh = NULL;
|
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);
|
rc_service_value_set(svcname, "child_pid", start_count_string);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nicelevel) {
|
if (nicelevel != INT_MIN) {
|
||||||
if (setpriority(PRIO_PROCESS, getpid(), nicelevel) == -1)
|
if (setpriority(PRIO_PROCESS, getpid(), nicelevel) == -1)
|
||||||
eerrorx("%s: setpriority %d: %s", applet, nicelevel,
|
eerrorx("%s: setpriority %d: %s", applet, nicelevel,
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
@ -361,6 +365,15 @@ static void child_process(char *exec, char **argv)
|
|||||||
eerrorx("%s: ioprio_set %d %d: %s", applet, ionicec, ioniced,
|
eerrorx("%s: ioprio_set %d %d: %s", applet, ionicec, ioniced,
|
||||||
strerror(errno));
|
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)
|
if (ch_root && chroot(ch_root) < 0)
|
||||||
eerrorx("%s: chroot `%s': %s", applet, ch_root, strerror(errno));
|
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_SERVICE=", 11) != 0 &&
|
||||||
strncmp(env->value, "RC_SVCNAME=", 11) != 0) ||
|
strncmp(env->value, "RC_SVCNAME=", 11) != 0) ||
|
||||||
strncmp(env->value, "SSD_NICELEVEL=", 14) == 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 = strchr(env->value, '=');
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
@ -745,6 +759,10 @@ int main(int argc, char **argv)
|
|||||||
ioniced = 7;
|
ioniced = 7;
|
||||||
ionicec <<= 13; /* class shift */
|
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 */
|
/* Get our user name and initial dir */
|
||||||
p = getenv("USER");
|
p = getenv("USER");
|
||||||
@ -806,6 +824,12 @@ int main(int argc, char **argv)
|
|||||||
applet, optarg);
|
applet, optarg);
|
||||||
break;
|
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 */
|
case 'P': /* --respawn-period time */
|
||||||
n = sscanf(optarg, "%d", &respawn_period);
|
n = sscanf(optarg, "%d", &respawn_period);
|
||||||
if (n != 1 || respawn_period < 1)
|
if (n != 1 || respawn_period < 1)
|
||||||
|
Loading…
Reference in New Issue
Block a user