aboutsummaryrefslogtreecommitdiff
path: root/toys/other/ionice.c
diff options
context:
space:
mode:
Diffstat (limited to 'toys/other/ionice.c')
-rw-r--r--toys/other/ionice.c95
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");
+}