1 /* ionice.c - set or get process I/O scheduling class and priority 2 * 3 * Copyright 2015 Rob Landley <rob@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