]> git.ipfire.org Git - thirdparty/util-linux.git/blob - schedutils/ionice.c
ionice: add -t option
[thirdparty/util-linux.git] / schedutils / ionice.c
1 /*
2 * ionice: set or get process io scheduling class and priority
3 *
4 * Copyright (C) 2005 Jens Axboe <axboe@suse.de> SUSE Labs
5 *
6 * Released under the terms of the GNU General Public License version 2
7 *
8 */
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <errno.h>
12 #include <getopt.h>
13 #include <unistd.h>
14 #include <sys/ptrace.h>
15 #include <sys/syscall.h>
16 #include <asm/unistd.h>
17
18 static inline int ioprio_set(int which, int who, int ioprio)
19 {
20 return syscall(SYS_ioprio_set, which, who, ioprio);
21 }
22
23 static inline int ioprio_get(int which, int who)
24 {
25 return syscall(SYS_ioprio_get, which, who);
26 }
27
28 enum {
29 IOPRIO_CLASS_NONE,
30 IOPRIO_CLASS_RT,
31 IOPRIO_CLASS_BE,
32 IOPRIO_CLASS_IDLE,
33 };
34
35 enum {
36 IOPRIO_WHO_PROCESS = 1,
37 IOPRIO_WHO_PGRP,
38 IOPRIO_WHO_USER,
39 };
40
41 #define IOPRIO_CLASS_SHIFT 13
42
43 const char *to_prio[] = { "none", "realtime", "best-effort", "idle", };
44
45 static void usage(void)
46 {
47 printf("Usage: ionice [OPTIONS] [COMMAND [ARG]...]\n");
48 printf("Sets or gets process io scheduling class and priority.\n");
49 printf("\n\t-n\tClass data (typically 0-7, lower being higher prio)\n");
50 printf("\t-c\tScheduling class\n");
51 printf("\t\t\t1: realtime, 2: best-effort, 3: idle\n");
52 printf("\t-p\tProcess pid\n");
53 printf("\t-t\tIgnore failures to set priority, run command unconditionally\n");
54 printf("\t-h\tThis help page\n");
55 printf("\nJens Axboe <axboe@suse.de> (C) 2005\n");
56 }
57
58 int main(int argc, char *argv[])
59 {
60 int ioprio = 4, set = 0, tolerant = 0, ioprio_class = IOPRIO_CLASS_BE;
61 int c, pid = 0;
62
63 while ((c = getopt(argc, argv, "+n:c:p:th")) != EOF) {
64 switch (c) {
65 case 'n':
66 ioprio = strtol(optarg, NULL, 10);
67 set |= 1;
68 break;
69 case 'c':
70 ioprio_class = strtol(optarg, NULL, 10);
71 set |= 2;
72 break;
73 case 'p':
74 pid = strtol(optarg, NULL, 10);
75 break;
76 case 't':
77 tolerant = 1;
78 break;
79 case 'h':
80 default:
81 usage();
82 exit(EXIT_SUCCESS);
83 }
84 }
85
86 switch (ioprio_class) {
87 case IOPRIO_CLASS_NONE:
88 ioprio_class = IOPRIO_CLASS_BE;
89 break;
90 case IOPRIO_CLASS_RT:
91 case IOPRIO_CLASS_BE:
92 break;
93 case IOPRIO_CLASS_IDLE:
94 if (set & 1)
95 printf("Ignoring given class data for idle class\n");
96 ioprio = 7;
97 break;
98 default:
99 printf("bad prio class %d\n", ioprio_class);
100 exit(EXIT_FAILURE);
101 }
102
103 if (!set) {
104 if (!pid && argv[optind])
105 pid = strtol(argv[optind], NULL, 10);
106
107 ioprio = ioprio_get(IOPRIO_WHO_PROCESS, pid);
108
109 if (ioprio == -1) {
110 perror("ioprio_get");
111 exit(EXIT_FAILURE);
112 } else {
113 ioprio_class = ioprio >> IOPRIO_CLASS_SHIFT;
114 if (ioprio_class != IOPRIO_CLASS_IDLE) {
115 ioprio = ioprio & 0xff;
116 printf("%s: prio %d\n", to_prio[ioprio_class], ioprio);
117 } else
118 printf("%s\n", to_prio[ioprio_class]);
119 }
120 } else {
121 if (ioprio_set(IOPRIO_WHO_PROCESS, pid, ioprio | ioprio_class << IOPRIO_CLASS_SHIFT) == -1) {
122 if (!tolerant) {
123 perror("ioprio_set");
124 exit(EXIT_FAILURE);
125 }
126 }
127
128 if (argv[optind]) {
129 execvp(argv[optind], &argv[optind]);
130 /* execvp should never return */
131 perror("execvp");
132 exit(EXIT_FAILURE);
133 }
134 }
135
136 exit(EXIT_SUCCESS);
137 }