start-stop-daemon can now set process IO scheduling.

This commit is contained in:
Roy Marples 2009-12-14 08:47:48 +00:00
parent 9476a2e721
commit dc3ccd8101
2 changed files with 39 additions and 3 deletions

View File

@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE. .\" SUCH DAMAGE.
.\" .\"
.Dd October 14, 2009 .Dd December 14, 2009
.Dt START-STOP-DAEMON 8 SMM .Dt START-STOP-DAEMON 8 SMM
.Os OpenRC .Os OpenRC
.Sh NAME .Sh NAME
@ -136,6 +136,10 @@ option. Only useful when used with daemons that run in the foreground and
forced into the background with the forced into the background with the
.Fl -b , -background .Fl -b , -background
option. option.
.It Fl I , -ionice Ar class Ns Op : Ns Ar data
Modifies the IO scheduling priority of the daemon.
Class can be 0 for none, 1 for real time, 2 for best effort and 3 for idle.
Data can be from 0 to 7 inclusive.
.It Fl N , -nice Ar level .It Fl N , -nice Ar level
Modifies the scheduling priority of the daemon. Modifies the scheduling priority of the daemon.
.It Fl 1 , -stdout Ar logfile .It Fl 1 , -stdout Ar logfile

View File

@ -47,6 +47,10 @@
#include <sys/time.h> #include <sys/time.h>
#include <sys/wait.h> #include <sys/wait.h>
#ifdef __linux__
#include <sys/syscall.h> /* For io priority */
#endif
#include <ctype.h> #include <ctype.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
@ -104,6 +108,13 @@ static char *changeuser, *ch_root, *ch_dir;
extern char **environ; extern char **environ;
#ifdef __linux__
static inline int ioprio_set(int which, int who, int ioprio)
{
return syscall(SYS_ioprio_set, which, who, ioprio);
}
#endif
static void static void
free_schedulelist(void) free_schedulelist(void)
{ {
@ -589,8 +600,9 @@ expand_home(const char *home, const char *path)
} }
#include "_usage.h" #include "_usage.h"
#define getoptstring "KN:PR:Sbc:d:e:g:ik:mn:op:s:tu:r:w:x:1:2:" getoptstring_COMMON #define getoptstring "I:KN:PR:Sbc:d:e:g:ik:mn:op:s:tu:r:w:x:1:2:" getoptstring_COMMON
static const struct option longopts[] = { static const struct option longopts[] = {
{ "ionice", 1, NULL, 'I'},
{ "stop", 0, NULL, 'K'}, { "stop", 0, NULL, 'K'},
{ "nicelevel", 1, NULL, 'N'}, { "nicelevel", 1, NULL, 'N'},
{ "retry", 1, NULL, 'R'}, { "retry", 1, NULL, 'R'},
@ -619,6 +631,7 @@ static const struct option longopts[] = {
longopts_COMMON longopts_COMMON
}; };
static const char * const longopts_help[] = { static const char * const longopts_help[] = {
"Set an ionice class:data when starting",
"Stop daemon", "Stop daemon",
"Set a nicelevel when starting", "Set a nicelevel when starting",
"Retry schedule to use when stopping", "Retry schedule to use when stopping",
@ -675,7 +688,7 @@ start_stop_daemon(int argc, char **argv)
char *pidfile = NULL; char *pidfile = NULL;
char *retry = NULL; char *retry = NULL;
int sig = -1; int sig = -1;
int nicelevel = 0; int nicelevel = 0, ionicec = -1, ioniced = 0;
bool background = false; bool background = false;
bool makepidfile = false; bool makepidfile = false;
bool interpreted = false; bool interpreted = false;
@ -738,6 +751,17 @@ start_stop_daemon(int argc, char **argv)
while ((opt = getopt_long(argc, argv, getoptstring, longopts, while ((opt = getopt_long(argc, argv, getoptstring, longopts,
(int *) 0)) != -1) (int *) 0)) != -1)
switch (opt) { switch (opt) {
case 'I': /* --ionice */
if (sscanf(optarg, "%d:%d", &ionicec, &ioniced) == 0)
eerrorx("%s: invalid ionice `%s'",
applet, optarg);
if (ionicec == 0)
ioniced = 0;
else if (ionicec == 3)
ioniced = 7;
ionicec <<= 13; /* class shift */
break;
case 'K': /* --stop */ case 'K': /* --stop */
stop = true; stop = true;
break; break;
@ -1121,6 +1145,14 @@ start_stop_daemon(int argc, char **argv)
strerror(errno)); strerror(errno));
} }
/* Only linux suports setting an IO priority */
#ifdef __linux__
if (ionicec != -1 &&
ioprio_set(1, mypid, ionicec | ioniced) == -1)
eerrorx("%s: ioprio_set %d %d: %s", applet,
ionicec, ioniced, strerror(errno));
#endif
if (ch_root && chroot(ch_root) < 0) if (ch_root && chroot(ch_root) < 0)
eerrorx("%s: chroot `%s': %s", eerrorx("%s: chroot `%s': %s",
applet, ch_root, strerror(errno)); applet, ch_root, strerror(errno));