10f66f451Sopenharmony_ci/* ionice.c - set or get process I/O scheduling class and priority
20f66f451Sopenharmony_ci *
30f66f451Sopenharmony_ci * Copyright 2015 Rob Landley <rob@landley.net>
40f66f451Sopenharmony_ci *
50f66f451Sopenharmony_ci * It would be really nice if there was a standard, but no. There is
60f66f451Sopenharmony_ci * Documentation/block/ioprio.txt in the linux source.
70f66f451Sopenharmony_ci
80f66f451Sopenharmony_ciUSE_IONICE(NEWTOY(ionice, "^tc#<0>3=2n#<0>7=5p#", TOYFLAG_USR|TOYFLAG_BIN))
90f66f451Sopenharmony_ciUSE_IORENICE(NEWTOY(iorenice, "?<1>3", TOYFLAG_USR|TOYFLAG_BIN))
100f66f451Sopenharmony_ci
110f66f451Sopenharmony_ciconfig IONICE
120f66f451Sopenharmony_ci  bool "ionice"
130f66f451Sopenharmony_ci  default y
140f66f451Sopenharmony_ci  help
150f66f451Sopenharmony_ci    usage: ionice [-t] [-c CLASS] [-n LEVEL] [COMMAND...|-p PID]
160f66f451Sopenharmony_ci
170f66f451Sopenharmony_ci    Change the I/O scheduling priority of a process. With no arguments
180f66f451Sopenharmony_ci    (or just -p), display process' existing I/O class/priority.
190f66f451Sopenharmony_ci
200f66f451Sopenharmony_ci    -c	CLASS = 1-3: 1(realtime), 2(best-effort, default), 3(when-idle)
210f66f451Sopenharmony_ci    -n	LEVEL = 0-7: (0 is highest priority, default = 5)
220f66f451Sopenharmony_ci    -p	Affect existing PID instead of spawning new child
230f66f451Sopenharmony_ci    -t	Ignore failure to set I/O priority
240f66f451Sopenharmony_ci
250f66f451Sopenharmony_ci    System default iopriority is generally -c 2 -n 4.
260f66f451Sopenharmony_ci
270f66f451Sopenharmony_ciconfig IORENICE
280f66f451Sopenharmony_ci  bool "iorenice"
290f66f451Sopenharmony_ci  default y
300f66f451Sopenharmony_ci  help
310f66f451Sopenharmony_ci    usage: iorenice PID [CLASS] [PRIORITY]
320f66f451Sopenharmony_ci
330f66f451Sopenharmony_ci    Display or change I/O priority of existing process. CLASS can be
340f66f451Sopenharmony_ci    "rt" for realtime, "be" for best effort, "idle" for only when idle, or
350f66f451Sopenharmony_ci    "none" to leave it alone. PRIORITY can be 0-7 (0 is highest, default 4).
360f66f451Sopenharmony_ci*/
370f66f451Sopenharmony_ci
380f66f451Sopenharmony_ci#define FOR_ionice
390f66f451Sopenharmony_ci#include "toys.h"
400f66f451Sopenharmony_ci#include <sys/syscall.h>
410f66f451Sopenharmony_ci
420f66f451Sopenharmony_ciGLOBALS(
430f66f451Sopenharmony_ci  long p, n, c;
440f66f451Sopenharmony_ci)
450f66f451Sopenharmony_ci
460f66f451Sopenharmony_cistatic int ioprio_get(void)
470f66f451Sopenharmony_ci{
480f66f451Sopenharmony_ci  return syscall(__NR_ioprio_get, 1, (int)TT.p);
490f66f451Sopenharmony_ci}
500f66f451Sopenharmony_ci
510f66f451Sopenharmony_cistatic int ioprio_set(void)
520f66f451Sopenharmony_ci{
530f66f451Sopenharmony_ci  int prio = ((int)TT.c << 13) | (int)TT.n;
540f66f451Sopenharmony_ci
550f66f451Sopenharmony_ci  return syscall(__NR_ioprio_set, 1, (int)TT.p, prio);
560f66f451Sopenharmony_ci}
570f66f451Sopenharmony_ci
580f66f451Sopenharmony_civoid ionice_main(void)
590f66f451Sopenharmony_ci{
600f66f451Sopenharmony_ci  if (!TT.p && !toys.optc) error_exit("Need -p or COMMAND");
610f66f451Sopenharmony_ci  if (toys.optflags == FLAG_p) {
620f66f451Sopenharmony_ci    int p = ioprio_get();
630f66f451Sopenharmony_ci    xprintf("%s: prio %d\n",
640f66f451Sopenharmony_ci      (char *[]){"unknown", "Realtime", "Best-effort", "Idle"}[(p>>13)&3],
650f66f451Sopenharmony_ci      p&7);
660f66f451Sopenharmony_ci  } else {
670f66f451Sopenharmony_ci    if (-1 == ioprio_set() && !(toys.optflags&FLAG_t)) perror_exit("set");
680f66f451Sopenharmony_ci    if (!TT.p) xexec(toys.optargs);
690f66f451Sopenharmony_ci  }
700f66f451Sopenharmony_ci}
710f66f451Sopenharmony_ci
720f66f451Sopenharmony_civoid iorenice_main(void)
730f66f451Sopenharmony_ci{
740f66f451Sopenharmony_ci  char *classes[] = {"none", "rt", "be", "idle"};
750f66f451Sopenharmony_ci
760f66f451Sopenharmony_ci  TT.p = atolx(*toys.optargs);
770f66f451Sopenharmony_ci  if (toys.optc == 1) {
780f66f451Sopenharmony_ci    int p = ioprio_get();
790f66f451Sopenharmony_ci
800f66f451Sopenharmony_ci    if (p == -1) perror_exit("read priority");
810f66f451Sopenharmony_ci    TT.c = (p>>13)&3;
820f66f451Sopenharmony_ci    p &= 7;
830f66f451Sopenharmony_ci    xprintf("Pid %ld, class %s (%ld), prio %d\n", TT.p, classes[TT.c], TT.c, p);
840f66f451Sopenharmony_ci    return;
850f66f451Sopenharmony_ci  }
860f66f451Sopenharmony_ci
870f66f451Sopenharmony_ci  for (TT.c = 0; TT.c<4; TT.c++)
880f66f451Sopenharmony_ci    if (!strcmp(toys.optargs[toys.optc-1], classes[TT.c])) break;
890f66f451Sopenharmony_ci  if (toys.optc == 3 || TT.c == 4) TT.n = atolx(toys.optargs[1]);
900f66f451Sopenharmony_ci  else TT.n = 4;
910f66f451Sopenharmony_ci  TT.c &= 3;
920f66f451Sopenharmony_ci
930f66f451Sopenharmony_ci  if (-1 == ioprio_set()) perror_exit("set");
940f66f451Sopenharmony_ci}
95