aboutsummaryrefslogtreecommitdiff
path: root/src/rc
diff options
context:
space:
mode:
Diffstat (limited to 'src/rc')
-rw-r--r--src/rc/start-stop-daemon.c54
1 files changed, 54 insertions, 0 deletions
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