Home | History | Annotate | Download | only in other
      1 /* ionice.c - set or get process I/O scheduling class and priority
      2  *
      3  * Copyright 2015 Rob Landley <rob (at) landley.net>
      4  *
      5  * It would be really nice if there was a standard, but no. There is
      6  * Documentation/block/ioprio.txt in the linux source.
      7 
      8 USE_IONICE(NEWTOY(ionice, "^tc#<0>3=2n#<0>7=5p#", TOYFLAG_USR|TOYFLAG_BIN))
      9 USE_IORENICE(NEWTOY(iorenice, "?<1>3", TOYFLAG_USR|TOYFLAG_BIN))
     10 
     11 config IONICE
     12   bool "ionice"
     13   default y
     14   help
     15     usage: ionice [-t] [-c CLASS] [-n LEVEL] [COMMAND...|-p PID]
     16 
     17     Change the I/O scheduling priority of a process. With no arguments
     18     (or just -p), display process' existing I/O class/priority.
     19 
     20     -c	CLASS = 1-3: 1(realtime), 2(best-effort, default), 3(when-idle)
     21     -n	LEVEL = 0-7: (0 is highest priority, default = 5)
     22     -p	Affect existing PID instead of spawning new child
     23     -t	Ignore failure to set I/O priority
     24 
     25     System default iopriority is generally -c 2 -n 4.
     26 
     27 config IORENICE
     28   bool "iorenice"
     29   default y
     30   help
     31     usage: iorenice PID [CLASS] [PRIORITY]
     32 
     33     Display or change I/O priority of existing process. CLASS can be
     34     "rt" for realtime, "be" for best effort, "idle" for only when idle, or
     35     "none" to leave it alone. PRIORITY can be 0-7 (0 is highest, default 4).
     36 */
     37 
     38 #define FOR_ionice
     39 #include "toys.h"
     40 #include <sys/syscall.h>
     41 
     42 GLOBALS(
     43   long pid;
     44   long level;
     45   long class;
     46 )
     47 
     48 static int ioprio_get(void)
     49 {
     50   return syscall(__NR_ioprio_get, 1, (int)TT.pid);
     51 }
     52 
     53 static int ioprio_set(void)
     54 {
     55   int prio = ((int)TT.class << 13) | (int)TT.level;
     56 
     57   return syscall(__NR_ioprio_set, 1, (int)TT.pid, prio);
     58 }
     59 
     60 void ionice_main(void)
     61 {
     62   if (!TT.pid && !toys.optc) error_exit("Need -p or COMMAND");
     63   if (toys.optflags == FLAG_p) {
     64     int p = ioprio_get();
     65     xprintf("%s: prio %d\n",
     66       (char *[]){"unknown", "Realtime", "Best-effort", "Idle"}[(p>>13)&3],
     67       p&7);
     68   } else {
     69     if (-1 == ioprio_set() && !(toys.optflags&FLAG_t)) perror_exit("set");
     70     if (!TT.pid) xexec(toys.optargs);
     71   }
     72 }
     73 
     74 void iorenice_main(void)
     75 {
     76   char *classes[] = {"none", "rt", "be", "idle"};
     77 
     78   TT.pid = atolx(*toys.optargs);
     79   if (toys.optc == 1) {
     80     int p = ioprio_get();
     81 
     82     if (p == -1) perror_exit("read priority");
     83     TT.class = (p>>13)&3;
     84     p &= 7;
     85     xprintf("Pid %ld, class %s (%ld), prio %d\n",
     86             TT.pid, classes[TT.class], TT.class, p);
     87     return;
     88   }
     89 
     90   for (TT.class = 0; TT.class<4; TT.class++)
     91     if (!strcmp(toys.optargs[toys.optc-1], classes[TT.class])) break;
     92   if (toys.optc == 3 || TT.class == 4) TT.level = atolx(toys.optargs[1]);
     93   else TT.level = 4;
     94   TT.class &= 3;
     95 
     96   if (-1 == ioprio_set()) perror_exit("set");
     97 }
     98