diff options
Diffstat (limited to 'toys')
-rw-r--r-- | toys/other/ionice.c | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/toys/other/ionice.c b/toys/other/ionice.c new file mode 100644 index 00000000..82f8fde6 --- /dev/null +++ b/toys/other/ionice.c @@ -0,0 +1,95 @@ +/* ionice.c - set or get process I/O scheduling class and priority + * + * Copyright 2015 Rob Landley <rob@landley.net> + * + * It would be really nice if there was a standard, but no. There is + * Documentation/block/ioprio.txt in the linux source. + +USE_IONICE(NEWTOY(ionice, "^tc#<0>3n#<0>7=5p#", TOYFLAG_USR|TOYFLAG_BIN)) +USE_IORENICE(NEWTOY(iorenice, "?<1>3", TOYFLAG_USR|TOYFLAG_BIN)) + +config IONICE + bool "ionice" + default y + help + usage: ionice [-t] [-c CLASS] [-n LEVEL] [COMMAND...|-p PID] + + Change the I/O scheduling priority of a process. With no arguments + (or just -p), display process' existing I/O class/priority. + + -c CLASS = 1-3: 1(realtime), 2(best-effort, default), 3(when-idle) + -n LEVEL = 0-7: (0 is highest priority, default = 5) + -p Affect existing PID instead of spawning new child + -t Ignore failure to set I/O priority + + System default iopriority is generally -c 2 -n 4. + +config IORENICE + bool "iorenice" + default y + help + usage: iorenice PID [CLASS] [PRIORITY] + + Display or change I/O priority of existing process. CLASS can be + "rt" for realtime, "be" for best effort, "idle" for only when idle, or + "none" to leave it alone. PRIORITY can be 0-7 (0 is highest, default 4). +*/ + +#define FOR_ionice +#include "toys.h" +#include <sys/syscall.h> + +GLOBALS( + long pid; + long level; + long class; +) + +static int ioprio_get(void) +{ + return syscall(__NR_ioprio_get, 1, (int)TT.pid); +} + +static int ioprio_set(void) +{ + return syscall(__NR_ioprio_set, 1, (int)TT.pid, (int)TT.class, (int)TT.level); +} + +void ionice_main(void) +{ + if (!TT.pid && !toys.optc) error_exit("Need -p or COMMAND"); + if (toys.optflags == FLAG_p) { + int p = ioprio_get(); + xprintf("%s: prio %d\n", + (char *[]){"unknown", "Realtime", "Best-effort", "Idle"}[(p>>13)&3], + p&7); + } else { + if (-1 == ioprio_set() && !(toys.optflags&FLAG_t)) perror_exit("set"); + if (TT.pid) xexec(toys.optargs); + } +} + +void iorenice_main(void) +{ + char *classes[] = {"none", "rt", "be", "idle"}; + + TT.pid = atolx(*toys.optargs); + if (toys.optc == 1) { + int p = ioprio_get(); + + if (p == -1) perror_exit("read priority"); + TT.class = (p>>13)&3; + p &= 7; + xprintf("Pid %d, class %s (%d), prio %d\n", + TT.pid, classes[TT.class], TT.class, p); + return; + } + + for (TT.class = 0; TT.class<4; TT.class++) + if (!strcmp(toys.optargs[toys.optc-1], classes[TT.class])) break; + if (toys.optc == 3 || TT.class == 4) TT.level = atolx(toys.optargs[1]); + else TT.level = 4; + TT.class &= 3; + + if (-1 == ioprio_set()) perror_exit("set"); +} |