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, &param) == -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

Reply via email to