Add Posix Scheduling Support to start-stop-daemon (#497)

This commit is contained in:
sad-goldfish 2022-03-05 20:48:17 +00:00 committed by GitHub
parent d796310456
commit 270e5c6828
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 61 additions and 0 deletions

View File

@ -130,6 +130,13 @@ Data can be from 0 to 7 inclusive.
Modifies the scheduling priority of the daemon.
.It Fl -oom-score-adj Ar adj
Modifies the OOM score adjustment of the daemon.
.It Fl -scheduler Ar policy
Sets the scheduling policy of the daemon. Possible values are other, fifo and rr
on POSIX systems and, additionally, batch and idle on Linux. If
.Ar policy
is an integer, it is passed directly to sched_setscheduler(2).
.It Fl -scheduler-priority Ar priority
Sets the priority parameter of the scheduling policy of the daemon. See sched(7) for details.
.It Fl 1 , -stdout Ar logfile
Redirect the standard output of the process to logfile when started with
.Fl background .

View File

@ -21,6 +21,11 @@
#define ONE_MS 1000000
#ifdef __linux__
/* For extra SCHED_* defines. */
# define _GNU_SOURCE
#endif
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/resource.h>
@ -60,6 +65,8 @@ static struct pam_conv conv = { NULL, NULL};
#include <sys/capability.h>
#endif
#include <sched.h>
#include "einfo.h"
#include "queue.h"
#include "rc.h"
@ -80,6 +87,8 @@ enum {
LONGOPT_CAPABILITIES,
LONGOPT_OOM_SCORE_ADJ,
LONGOPT_NO_NEW_PRIVS,
LONGOPT_SCHEDULER,
LONGOPT_SCHEDULER_PRIO,
LONGOPT_SECBITS,
};
@ -120,6 +129,8 @@ const struct option longopts[] = {
{ "stdout-logger",1, NULL, '3'},
{ "stderr-logger",1, NULL, '4'},
{ "progress", 0, NULL, 'P'},
{ "scheduler", 1, NULL, LONGOPT_SCHEDULER},
{ "scheduler-priority", 1, NULL, LONGOPT_SCHEDULER_PRIO},
longopts_COMMON
};
const char * const longopts_help[] = {
@ -155,6 +166,8 @@ const char * const longopts_help[] = {
"Redirect stdout to process",
"Redirect stderr to process",
"Print dots each second while waiting",
"Set process scheduler",
"Set process scheduler priority",
longopts_help_COMMON
};
const char *usagestring = NULL;
@ -332,6 +345,8 @@ int main(int argc, char **argv)
mode_t numask = 022;
char **margv;
unsigned int start_wait = 0;
const char *scheduler = NULL;
int sched_prio = -1;
#ifdef HAVE_CAP
cap_iab_t cap_iab = NULL;
unsigned secbits = 0;
@ -594,6 +609,14 @@ int main(int argc, char **argv)
stderr_process = optarg;
break;
case LONGOPT_SCHEDULER: /* --scheduler "Process scheduler policy" */
scheduler = optarg;
break;
case LONGOPT_SCHEDULER_PRIO: /* --scheduler-priority "Process scheduler priority" */
sscanf(optarg, "%d", &sched_prio);
break;
case_RC_COMMON_GETOPT
}
@ -1064,6 +1087,37 @@ int main(int argc, char **argv)
for (i = getdtablesize() - 1; i >= 3; --i)
close(i);
if (scheduler != NULL) {
int scheduler_index;
struct sched_param sched = {.sched_priority = sched_prio};
if (strcmp(scheduler, "fifo") == 0)
scheduler_index = SCHED_FIFO;
else if (strcmp(scheduler, "rr") == 0)
scheduler_index = SCHED_RR;
else if (strcmp(scheduler, "other") == 0)
scheduler_index = SCHED_OTHER;
#ifdef SCHED_BATCH
else if (strcmp(scheduler, "batch") == 0)
scheduler_index = SCHED_BATCH;
#endif
#ifdef SCHED_IDLE
else if (strcmp(scheduler, "idle") == 0)
scheduler_index = SCHED_IDLE;
#endif
else if (sscanf(scheduler, "%d", &scheduler_index) != 1)
eerrorx("Unknown scheduler: %s", scheduler);
if (sched_prio == -1)
sched.sched_priority = sched_get_priority_min(scheduler_index);
if (sched_setscheduler(mypid, scheduler_index, &sched))
eerrorx("Failed to set scheduler: %s", strerror(errno));
} else if (sched_prio != -1) {
const struct sched_param sched = {.sched_priority = sched_prio};
if (sched_setparam(mypid, &sched))
eerrorx("Failed to set scheduler parameters: %s", strerror(errno));
}
setsid();
execvp(exec, argv);
#ifdef HAVE_PAM