Skip to content

Commit

Permalink
Add Posix Scheduling Support to start-stop-daemon (#497)
Browse files Browse the repository at this point in the history
  • Loading branch information
sad-goldfish authored Mar 5, 2022
1 parent d796310 commit 270e5c6
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 0 deletions.
7 changes: 7 additions & 0 deletions man/start-stop-daemon.8
Original file line number Diff line number Diff line change
Expand Up @@ -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 .
Expand Down
54 changes: 54 additions & 0 deletions src/rc/start-stop-daemon.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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"
Expand All @@ -80,6 +87,8 @@ enum {
LONGOPT_CAPABILITIES,
LONGOPT_OOM_SCORE_ADJ,
LONGOPT_NO_NEW_PRIVS,
LONGOPT_SCHEDULER,
LONGOPT_SCHEDULER_PRIO,
LONGOPT_SECBITS,
};

Expand Down Expand Up @@ -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[] = {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
}

Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 270e5c6

Please sign in to comment.