| /* 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>3=2n#<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) |
| { |
| int prio = ((int)TT.class << 13) | (int)TT.level; |
| |
| return syscall(__NR_ioprio_set, 1, (int)TT.pid, prio); |
| } |
| |
| 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 %ld, class %s (%ld), 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"); |
| } |