Hi, I have re-written the patch again now. It now accepts both IO scheduler class and IO scheduler data with a single flag, as you said you would prefer earlier (in the format "-I <class>:<data>"). Also, on non-Linux platforms or Linux systems that don't support ioprio_set, passing the '-I' flag will have no effect, as the new code won't be compiled in (it will just silently ignore it).
There is error-checking on the scheduler class string. To convert the scheduler data string in to an integer, I used strtol(), as that allows a certain level of error checking in the string to be converted, so it detects if you pass non-integer characters as the scheduler data (as opposed to just converting it to zero, as atoi() does, which is valid anyway). Let me know what you think. Regards Chris
=== modified file 'utils/start-stop-daemon.c'
--- utils/start-stop-daemon.c 2009-01-13 17:28:50 +0000
+++ utils/start-stop-daemon.c 2009-01-13 22:01:36 +0000
@@ -103,6 +103,26 @@
#include <error.h>
#endif
+#include <sys/syscall.h>
+#if defined(SYS_ioprio_set) && defined(linux)
+# define SupportIOPrioSet
+#endif
+
+#ifdef SupportIOPrioSet
+enum {
+ IOPRIO_WHO_PROCESS = 1,
+ IOPRIO_WHO_PGRP,
+ IOPRIO_WHO_USER,
+};
+
+enum {
+ IOPRIO_CLASS_NONE,
+ IOPRIO_CLASS_RT,
+ IOPRIO_CLASS_BE,
+ IOPRIO_CLASS_IDLE,
+};
+#endif
+
static int testmode = 0;
static int quietmode = 0;
static int exitnodo = 1;
@@ -127,6 +147,18 @@
static const char *progname = "";
static int nicelevel = 0;
static int umask_value = -1;
+#ifdef SupportIOPrioSet
+static int ioprio_mask = 0;
+static char *ioprio_class_in = NULL;
+static char *ioprio_data_in = NULL;
+static int ioprio_class = IOPRIO_CLASS_BE;
+static long int ioprio_data = 4;
+static long int ioprio_data_temp = 0;
+static char *temp = NULL;
+
+#define IOPRIO_CLASS_SHIFT 13
+#define IOPRIO_PRIO_VALUE(class, data) (((class) << IOPRIO_CLASS_SHIFT) | data)
+#endif
static struct stat exec_stat;
#if defined(OSHURD)
@@ -169,6 +201,9 @@
static int pid_is_exec(pid_t pid, const struct stat *esb);
#endif
+#ifdef SupportIOPrioSet
+static inline int ioprio_set(int which, int who, int ioprio);
+#endif
static void fatal(const char *format, ...)
NONRETURNING PRINTFFORMAT(1, 2);
@@ -308,6 +343,9 @@
" -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"
+#ifdef SupportIOPrioSet
+" -I|--ioprio <class>:<data> set the process's IO scheduler class and class data\n"
+#endif
" -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"
@@ -520,6 +558,7 @@
{ "exec", 1, NULL, 'x'},
{ "chuid", 1, NULL, 'c'},
{ "nicelevel", 1, NULL, 'N'},
+ { "ioprio", 1, NULL, 'I'},
{ "umask", 1, NULL, 'k'},
{ "background", 0, NULL, 'b'},
{ "make-pidfile", 0, NULL, 'm'},
@@ -533,9 +572,9 @@
int c;
for (;;) {
- c = getopt_long(argc, argv,
- "HKSVa:n:op:qr:s:tu:vx:c:N:k:bmR:g:d:",
- longopts, NULL);
+ c = getopt_long(argc, argv,
+ "HKSVa:n:op:qr:s:tu:vx:c:N:I:k:bmR:g:d:",
+ longopts, NULL);
if (c == -1)
break;
switch (c) {
@@ -597,6 +636,13 @@
case 'N': /* --nice */
nicelevel = atoi(optarg);
break;
+ case 'I': /* --ioprio */
+#ifdef SupportIOPrioSet
+ ioprio_class_in = strdup(optarg);
+ ioprio_class_in = strtok(ioprio_class_in, ":");
+ ioprio_data_in = strtok(NULL, ":");
+#endif
+ break;
case 'k': /* --umask <mask> */
umask_str = optarg;
break;
@@ -1221,6 +1267,14 @@
}
}
+#ifdef SupportIOPrioSet
+static inline int
+ioprio_set (int which, int who, int ioprio)
+{
+ return syscall(SYS_ioprio_set, which, who, ioprio);
+}
+#endif
+
int
main(int argc, char **argv)
{
@@ -1334,6 +1388,40 @@
fatal("Unable to alter nice level by %i: %s",
nicelevel, strerror(errno));
}
+#ifdef SupportIOPrioSet
+ if (ioprio_class_in != NULL) {
+ if (strcmp(ioprio_class_in, "real-time") == 0) {
+ ioprio_class = IOPRIO_CLASS_RT;
+ } else if (strcmp(ioprio_class_in, "best-effort") == 0) {
+ ioprio_class = IOPRIO_CLASS_BE;
+ } else if (strcmp(ioprio_class_in, "idle") == 0) {
+ ioprio_class = IOPRIO_CLASS_IDLE;
+ } else {
+ fatal("Unrecognized IO scheduler class %s", ioprio_class_in);
+ }
+ switch (ioprio_class) {
+ case (IOPRIO_CLASS_IDLE):
+ ioprio_data = 7;
+ break;
+ default:
+ if (ioprio_data_in != NULL) {
+ ioprio_data_temp = strtol(ioprio_data_in, &temp, 10);
+ if (ioprio_data_in != temp) {
+ ioprio_data = ioprio_data_temp;
+ } else {
+ fatal("Unrecognized IO scheduler class data %s", ioprio_data_in);
+ }
+ }
+ }
+ ioprio_mask = IOPRIO_PRIO_VALUE(ioprio_class, ioprio_data);
+ if (quietmode < 0)
+ printf("IO priority mask %i", ioprio_mask);
+ errno = 0;
+ if ((ioprio_set(IOPRIO_WHO_PROCESS, getpid(), ioprio_mask) == -1) && (errno != 0))
+ fatal("Unable to alter IO priority to mask %i: %s",
+ ioprio_mask, strerror(errno));
+ }
+#endif
if (umask_value >= 0)
umask(umask_value);
if (mpidfile && pidfile != NULL) {
signature.asc
Description: This is a digitally signed message part

