The following commit has been merged in the master branch: commit a5908b7ddb65d84650f0dab407097bdbca6a2cc2 Author: Guillem Jover <guil...@debian.org> Date: Wed Jan 14 11:46:24 2009 +0200
s-s-d: Support setting the process scheduler policy and priority Add new option -P, --procsched <policy[:priority]>. Closes: #175740 diff --git a/ChangeLog b/ChangeLog index 8383951..ad1ddf5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,22 @@ 2009-01-14 Guillem Jover <guil...@debian.org> + * man/start-stop-daemon.8: Document new option --procsched. + * utils/start-stop-daemon.c [_POSIX_PRIORITY_SCHEDULING]: Include + <sched.h>. + [!_POSIX_PRIORITY_SCHEDULING]: Define SCHED_OTHER, SCHED_FIFO and + SCHED_RR with dummy values. + (struct res_schedule): New type. + (proc_sched): New variable. + (do_help): Document --procsched. + (parse_proc_schedule, set_proc_schedule): New functions. + (parse_options): Add 'procsched' to longopts. Add 'P:' to getopt_long + call. Handle 'P' as getopt_long return value. Call parse_proc_schedule + if proc_schedule_str is not NULL. + (main): Print proc_sched values if --test is used. Call + set_proc_schedule if proc_sched is not NULL. + +2009-01-14 Guillem Jover <guil...@debian.org> + * utils/start-stop-daemon.c (xstrdup): New function. (parse_options): Use xstrdup instead of strdup. diff --git a/debian/changelog b/debian/changelog index 1340300..3904d57 100644 --- a/debian/changelog +++ b/debian/changelog @@ -50,6 +50,8 @@ dpkg (1.15.0) UNRELEASED; urgency=low permissions. Closes: #502496 * Make start-stop-daemon behave the same way whether --chuid gets a user name or a uid. Closes: #368000 + * Add new option --procsched to start-stop-daemon to be able to set the + process scheduling policy and priority. Closes: #175740 [ Raphael Hertzog ] * Enhance dpkg-shlibdeps's error message when a library can't be found to diff --git a/man/start-stop-daemon.8 b/man/start-stop-daemon.8 index 7e8bbe2..26996b9 100644 --- a/man/start-stop-daemon.8 +++ b/man/start-stop-daemon.8 @@ -219,6 +219,12 @@ code for them to do this themselves. .BR \-N ", " \-\-nicelevel " \fIint\fP" This alters the priority of the process before starting it. .TP +.BR \-P ", " \-\-procsched " \fIpolicy\fP\fB:\fP\fIpriority\fP" +This alters the process scheduler policy and priority of the process before +starting it. The priority can be optionally specified by appending a \fB:\fP +followed by the value. The default \fIpriority\fP is 0. The currently +supported policy values are \fBother\fP, \fBfifo\fP and \fBrr\fP. +.TP .BR \-k ", " \-\-umask " \fImask\fP" This sets the umask of the process before starting it. .TP diff --git a/utils/start-stop-daemon.c b/utils/start-stop-daemon.c index a12a0fe..8171dc3 100644 --- a/utils/start-stop-daemon.c +++ b/utils/start-stop-daemon.c @@ -91,6 +91,14 @@ #include <assert.h> #include <ctype.h> +#ifdef _POSIX_PRIORITY_SCHEDULING +#include <sched.h> +#else +#define SCHED_OTHER -1 +#define SCHED_FIFO -1 +#define SCHED_RR -1 +#endif + #ifdef HAVE_SYS_CDEFS_H #include <sys/cdefs.h> #endif @@ -142,6 +150,13 @@ struct pid_list { static struct pid_list *found = NULL; static struct pid_list *killed = NULL; +/* Resource scheduling policy. */ +struct res_schedule { + const char *policy_name; + int policy; + int priority; +}; + struct schedule_item { enum { sched_timeout, @@ -152,6 +167,8 @@ struct schedule_item { int value; /* Seconds, signal no., or index into array */ }; +static struct res_schedule *proc_sched = NULL; + static int schedule_length; static struct schedule_item *schedule = NULL; @@ -319,6 +336,9 @@ do_help(void) " -r|--chroot <directory> chroot to <directory> before starting\n" " -d|--chdir <directory> change to <directory> (default is /)\n" " -N|--nicelevel <incr> add incr to the process's nice level\n" +" -P|--procsched <policy[:prio]>\n" +" use <policy> with <prio> for the kernel\n" +" process scheduler (default prio is 0)\n" " -k|--umask <mask> change the umask to <mask> before starting\n" " -b|--background force the process to detach\n" " -m|--make-pidfile create the pidfile before starting\n" @@ -334,6 +354,9 @@ do_help(void) " forever repeat remainder forever\n" "or <schedule> may be just <timeout>, meaning <signal>/<timeout>/KILL/<timeout>\n" "\n" +"The process scheduler <policy> can be one of:\n" +" other, fifo or rr\n" +"\n" "Exit status: 0 = done 1 = nothing done (=> 0 if --oknodo)\n" " 3 = trouble 2 = with --retry, processes wouldn't die\n"); } @@ -431,6 +454,58 @@ parse_umask(const char *string, int *value_r) } static void +parse_proc_schedule(const char *string) +{ + char *policy_str, *prio_str; + int prio = 0, prio_min, prio_max; + + policy_str = xstrdup(string); + policy_str = strtok(policy_str, ":"); + prio_str = strtok(NULL, ":"); + + if (prio_str && parse_integer(prio_str, &prio) != 0) + fatal("invalid process scheduler priority"); + + proc_sched = xmalloc(sizeof(*proc_sched)); + proc_sched->policy_name = policy_str; + + if (strcmp(policy_str, "other") == 0) { + proc_sched->policy = SCHED_OTHER; + proc_sched->priority = 0; + } else if (strcmp(policy_str, "fifo") == 0) { + proc_sched->policy = SCHED_FIFO; + proc_sched->priority = prio; + } else if (strcmp(policy_str, "rr") == 0) { + proc_sched->policy = SCHED_RR; + proc_sched->priority = prio; + } else + badusage("invalid process scheduler policy"); + +#ifdef _POSIX_PRIORITY_SCHEDULING + prio_min = sched_get_priority_min(proc_sched->policy); + prio_max = sched_get_priority_max(proc_sched->policy); + + if (proc_sched->priority < prio_min) + badusage("process scheduler priority less than min"); + if (proc_sched->priority > prio_max) + badusage("process scheduler priority greater than max"); +#endif +} + +static void +set_proc_schedule(struct res_schedule *sched) +{ +#ifdef _POSIX_PRIORITY_SCHEDULING + struct sched_param param; + + param.sched_priority = sched->priority; + + if (sched_setscheduler(getpid(), sched->policy, ¶m) == -1) + fatal("Unable to set process scheduler"); +#endif +} + +static void parse_schedule_item(const char *string, struct schedule_item *item) { const char *after_hyph; @@ -531,6 +606,7 @@ parse_options(int argc, char * const *argv) { "exec", 1, NULL, 'x'}, { "chuid", 1, NULL, 'c'}, { "nicelevel", 1, NULL, 'N'}, + { "procsched", 1, NULL, 'P'}, { "umask", 1, NULL, 'k'}, { "background", 0, NULL, 'b'}, { "make-pidfile", 0, NULL, 'm'}, @@ -541,11 +617,12 @@ parse_options(int argc, char * const *argv) const char *umask_str = NULL; const char *signal_str = NULL; const char *schedule_str = NULL; + const char *proc_schedule_str = NULL; int c; for (;;) { c = getopt_long(argc, argv, - "HKSVa:n:op:qr:s:tu:vx:c:N:k:bmR:g:d:", + "HKSVa:n:op:qr:s:tu:vx:c:N:P:k:bmR:g:d:", longopts, NULL); if (c == -1) break; @@ -608,6 +685,9 @@ parse_options(int argc, char * const *argv) case 'N': /* --nice */ nicelevel = atoi(optarg); break; + case 'P': /* --procsched */ + proc_schedule_str = optarg; + break; case 'k': /* --umask <mask> */ umask_str = optarg; break; @@ -638,6 +718,9 @@ parse_options(int argc, char * const *argv) parse_schedule(schedule_str); } + if (proc_schedule_str != NULL) + parse_proc_schedule(proc_schedule_str); + if (umask_str != NULL) { if (parse_umask(umask_str, &umask_value) != 0) badusage("umask value must be a positive number"); @@ -1324,6 +1407,9 @@ main(int argc, char **argv) printf(" in directory %s", changeroot); if (nicelevel) printf(", and add %i to the priority", nicelevel); + if (proc_sched) + printf(", with scheduling policy %s with priority %i", + proc_sched->policy_name, proc_sched->priority); printf(".\n"); } if (testmode) @@ -1345,6 +1431,8 @@ main(int argc, char **argv) fatal("Unable to alter nice level by %i: %s", nicelevel, strerror(errno)); } + if (proc_sched) + set_proc_schedule(proc_sched); if (umask_value >= 0) umask(umask_value); if (mpidfile && pidfile != NULL) { -- dpkg's main repository -- To UNSUBSCRIBE, email to debian-dpkg-cvs-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org