1 /* ionice.c - set or get process I/O scheduling class and priority
2 *
3 * Copyright 2015 Rob Landley <[email protected]>
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
GLOBALS(long p,n,c;)41 GLOBALS(
42 long p, n, c;
43 )
44
45 static int xioprio_get(void)
46 {
47 int p = syscall(__NR_ioprio_get, 1, (int)TT.p);
48
49 if (p==-1) perror_exit("read priority");
50
51 return p;
52 }
53
xioprio_set(void)54 static void xioprio_set(void)
55 {
56 if (-1 == syscall(__NR_ioprio_set, 1, (int)TT.p, (int)((TT.c<<13)|TT.n)))
57 if (!FLAG(t)) perror_exit("set priority");
58 }
59
ionice_main(void)60 void ionice_main(void)
61 {
62 if (!TT.p && !toys.optc) error_exit("Need -p or COMMAND");
63 if (toys.optflags == FLAG_p) {
64 int p = xioprio_get();
65
66 xprintf("%s: prio %d\n",
67 (char *[]){"unknown", "Realtime", "Best-effort", "Idle"}[(p>>13)&3], p&7);
68 } else {
69 xioprio_set();
70 if (!TT.p) xexec(toys.optargs);
71 }
72 }
73
iorenice_main(void)74 void iorenice_main(void)
75 {
76 char *classes[] = {"none", "rt", "be", "idle"};
77
78 TT.p = atolx(*toys.optargs);
79 if (toys.optc == 1) {
80 int p = xioprio_get();
81
82 xprintf("Pid %ld, class %s (%d), prio %d\n", TT.p, classes[(p>>13)&3],
83 (p>>13)&3, p&7);
84 return;
85 }
86
87 for (TT.c = 0; TT.c<4; TT.c++)
88 if (!strcmp(toys.optargs[toys.optc-1], classes[TT.c])) break;
89 if (toys.optc == 3 || TT.c == 4) TT.n = atolx(toys.optargs[1]);
90 else TT.n = 4;
91 TT.c &= 3;
92
93 xioprio_set();
94 }
95