aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsad-goldfish <98661640+sad-goldfish@users.noreply.github.com>2022-03-05 20:48:17 +0000
committerGitHub <noreply@github.com>2022-03-05 15:48:17 -0500
commit270e5c6828577e50830fd3b5662f2b3ec4fb6772 (patch)
tree1cb6960c146c9829b403fbb27fdc4a442859d3cd
parentd7963104564fd8277dd39303b1b3f9c90db0bf20 (diff)
Add Posix Scheduling Support to start-stop-daemon (#497)
-rw-r--r--man/start-stop-daemon.87
-rw-r--r--src/rc/start-stop-daemon.c54
2 files changed, 61 insertions, 0 deletions
diff --git a/man/start-stop-daemon.8 b/man/start-stop-daemon.8
index 257cad70..6c96b7f7 100644
--- a/man/start-stop-daemon.8
+++ b/man/start-stop-daemon.8
@@ -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 .
diff --git a/src/rc/start-stop-daemon.c b/src/rc/start-stop-daemon.c
index c0f2b80e..db97f3b3 100644
--- a/src/rc/start-stop-daemon.c
+++ b/src/rc/start-stop-daemon.c
@@ -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