]> git.ipfire.org Git - thirdparty/util-linux.git/blame - schedutils/ionice.c
flock: initialize timevals [-Werror=maybe-uninitialized]
[thirdparty/util-linux.git] / schedutils / ionice.c
CommitLineData
48d7b13a
KZ
1/*
2 * ionice: set or get process io scheduling class and priority
3 *
357e7c3b 4 * Copyright (C) 2005 Jens Axboe <jens@axboe.dk>
48d7b13a
KZ
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>
319563bf 14#ifdef HAVE_SYS_SYSCALL_H
48d7b13a 15#include <sys/syscall.h>
319563bf 16#endif
fe040397 17#include <ctype.h>
5bd11d0d
KZ
18
19#include "nls.h"
8abcf290 20#include "strutils.h"
eb76ca98 21#include "c.h"
ed8ec2a6 22#include "closestream.h"
24295096 23
ef0fe2e8
SM
24static int tolerant;
25
48d7b13a
KZ
26static inline int ioprio_set(int which, int who, int ioprio)
27{
4dfadf9c 28 return syscall(SYS_ioprio_set, which, who, ioprio);
48d7b13a
KZ
29}
30
31static inline int ioprio_get(int which, int who)
32{
4dfadf9c 33 return syscall(SYS_ioprio_get, which, who);
48d7b13a
KZ
34}
35
36enum {
37 IOPRIO_CLASS_NONE,
38 IOPRIO_CLASS_RT,
39 IOPRIO_CLASS_BE,
40 IOPRIO_CLASS_IDLE,
41};
42
43enum {
44 IOPRIO_WHO_PROCESS = 1,
45 IOPRIO_WHO_PGRP,
46 IOPRIO_WHO_USER,
47};
48
560cdabb
KZ
49#define IOPRIO_CLASS_SHIFT (13)
50#define IOPRIO_PRIO_MASK ((1UL << IOPRIO_CLASS_SHIFT) - 1)
51
52#define IOPRIO_PRIO_CLASS(mask) ((mask) >> IOPRIO_CLASS_SHIFT)
53#define IOPRIO_PRIO_DATA(mask) ((mask) & IOPRIO_PRIO_MASK)
54#define IOPRIO_PRIO_VALUE(class, data) (((class) << IOPRIO_CLASS_SHIFT) | data)
55
2ba641e5 56static const char *to_prio[] = {
560cdabb
KZ
57 [IOPRIO_CLASS_NONE] = "none",
58 [IOPRIO_CLASS_RT] = "realtime",
59 [IOPRIO_CLASS_BE] = "best-effort",
60 [IOPRIO_CLASS_IDLE] = "idle"
61};
48d7b13a 62
fe040397
KZ
63static int parse_ioclass(const char *str)
64{
cee12fc6 65 size_t i;
fe040397
KZ
66
67 for (i = 0; i < ARRAY_SIZE(to_prio); i++)
68 if (!strcasecmp(str, to_prio[i]))
69 return i;
70 return -1;
71}
72
bd2ff3d2 73static void ioprio_print(int pid, int who)
ef0fe2e8 74{
bd2ff3d2 75 int ioprio = ioprio_get(who, pid);
ef0fe2e8
SM
76
77 if (ioprio == -1)
78 err(EXIT_FAILURE, _("ioprio_get failed"));
79 else {
560cdabb 80 int ioclass = IOPRIO_PRIO_CLASS(ioprio);
cbc1dc96
KZ
81 const char *name = _("unknown");
82
b422f5fe 83 if (ioclass >= 0 && (size_t) ioclass < ARRAY_SIZE(to_prio))
cbc1dc96 84 name = to_prio[ioclass];
560cdabb
KZ
85
86 if (ioclass != IOPRIO_CLASS_IDLE)
65f25186 87 printf(_("%s: prio %lu\n"), name,
8c219bf4 88 IOPRIO_PRIO_DATA(ioprio));
560cdabb 89 else
cbc1dc96 90 printf("%s\n", name);
ef0fe2e8
SM
91 }
92}
93
bd2ff3d2 94static void ioprio_setid(int which, int ioclass, int data, int who)
ef0fe2e8 95{
bd2ff3d2 96 int rc = ioprio_set(who, which,
560cdabb 97 IOPRIO_PRIO_VALUE(ioclass, data));
ef0fe2e8
SM
98
99 if (rc == -1 && !tolerant)
100 err(EXIT_FAILURE, _("ioprio_set failed"));
101}
102
6e1eda6f 103static void __attribute__((__noreturn__)) usage(void)
48d7b13a 104{
6e1eda6f 105 FILE *out = stdout;
2d745ee6
BS
106 fputs(USAGE_HEADER, out);
107 fprintf(out, _(" %1$s [options] -p <pid>...\n"
108 " %1$s [options] -P <pgid>...\n"
109 " %1$s [options] -u <uid>...\n"
110 " %1$s [options] <command>\n"), program_invocation_short_name);
111
451dbcfa
BS
112 fputs(USAGE_SEPARATOR, out);
113 fputs(_("Show or change the I/O-scheduling class and priority of a process.\n"), out);
114
2d745ee6
BS
115 fputs(USAGE_OPTIONS, out);
116 fputs(_(" -c, --class <class> name or number of scheduling class,\n"
117 " 0: none, 1: realtime, 2: best-effort, 3: idle\n"), out);
118 fputs(_(" -n, --classdata <num> priority (0..7) in the specified scheduling class,\n"
119 " only for the realtime and best-effort classes\n"), out);
120 fputs(_(" -p, --pid <pid>... act on these already running processes\n"), out);
121 fputs(_(" -P, --pgid <pgrp>... act on already running processes in these groups\n"), out);
122 fputs(_(" -t, --ignore ignore failures\n"), out);
123 fputs(_(" -u, --uid <uid>... act on already running processes owned by these users\n"), out);
124
125 fputs(USAGE_SEPARATOR, out);
bad4c729 126 fprintf(out, USAGE_HELP_OPTIONS(24));
2d745ee6 127
bad4c729 128 fprintf(out, USAGE_MAN_TAIL("ionice(1)"));
976b7580 129
6e1eda6f 130 exit(EXIT_SUCCESS);
48d7b13a
KZ
131}
132
a5e9b75f 133int main(int argc, char **argv)
48d7b13a 134{
560cdabb 135 int data = 4, set = 0, ioclass = IOPRIO_CLASS_BE, c;
bd2ff3d2
MY
136 int which = 0, who = 0;
137 const char *invalid_msg = NULL;
48d7b13a 138
976b7580
SK
139 static const struct option longopts[] = {
140 { "classdata", required_argument, NULL, 'n' },
141 { "class", required_argument, NULL, 'c' },
142 { "help", no_argument, NULL, 'h' },
143 { "ignore", no_argument, NULL, 't' },
144 { "pid", required_argument, NULL, 'p' },
bd2ff3d2
MY
145 { "pgid", required_argument, NULL, 'P' },
146 { "uid", required_argument, NULL, 'u' },
976b7580
SK
147 { "version", no_argument, NULL, 'V' },
148 { NULL, 0, NULL, 0 }
149 };
150
5bd11d0d
KZ
151 setlocale(LC_ALL, "");
152 bindtextdomain(PACKAGE, LOCALEDIR);
153 textdomain(PACKAGE);
2c308875 154 close_stdout_atexit();
5bd11d0d 155
bd2ff3d2 156 while ((c = getopt_long(argc, argv, "+n:c:p:P:u:tVh", longopts, NULL)) != EOF)
48d7b13a
KZ
157 switch (c) {
158 case 'n':
630ed89d 159 data = strtos32_or_err(optarg, _("invalid class data argument"));
8dbfe5a1 160 set |= 1;
48d7b13a
KZ
161 break;
162 case 'c':
fe040397 163 if (isdigit(*optarg))
630ed89d
KZ
164 ioclass = strtos32_or_err(optarg,
165 _("invalid class argument"));
fe040397
KZ
166 else {
167 ioclass = parse_ioclass(optarg);
168 if (ioclass < 0)
169 errx(EXIT_FAILURE,
170 _("unknown scheduling class: '%s'"),
171 optarg);
172 }
8dbfe5a1 173 set |= 2;
48d7b13a
KZ
174 break;
175 case 'p':
bd2ff3d2
MY
176 if (who)
177 errx(EXIT_FAILURE,
2d745ee6 178 _("can handle only one of pid, pgid or uid at once"));
bd2ff3d2
MY
179 invalid_msg = _("invalid PID argument");
180 which = strtos32_or_err(optarg, invalid_msg);
181 who = IOPRIO_WHO_PROCESS;
182 break;
183 case 'P':
184 if (who)
185 errx(EXIT_FAILURE,
2d745ee6 186 _("can handle only one of pid, pgid or uid at once"));
bd2ff3d2
MY
187 invalid_msg = _("invalid PGID argument");
188 which = strtos32_or_err(optarg, invalid_msg);
189 who = IOPRIO_WHO_PGRP;
190 break;
191 case 'u':
192 if (who)
193 errx(EXIT_FAILURE,
2d745ee6 194 _("can handle only one of pid, pgid or uid at once"));
b6973e5d 195 invalid_msg = _("invalid UID argument");
bd2ff3d2
MY
196 which = strtos32_or_err(optarg, invalid_msg);
197 who = IOPRIO_WHO_USER;
48d7b13a 198 break;
4d125dfc
LK
199 case 't':
200 tolerant = 1;
201 break;
2c308875 202
976b7580 203 case 'V':
2c308875 204 print_version(EXIT_SUCCESS);
48d7b13a 205 case 'h':
6e1eda6f 206 usage();
48d7b13a 207 default:
677ec86c 208 errtryhelp(EXIT_FAILURE);
48d7b13a 209 }
48d7b13a 210
ef0fe2e8 211 switch (ioclass) {
48d7b13a 212 case IOPRIO_CLASS_NONE:
cbc1dc96 213 if ((set & 1) && !tolerant)
5dc9371c 214 warnx(_("ignoring given class data for none class"));
560cdabb 215 data = 0;
48d7b13a
KZ
216 break;
217 case IOPRIO_CLASS_RT:
218 case IOPRIO_CLASS_BE:
219 break;
220 case IOPRIO_CLASS_IDLE:
cbc1dc96 221 if ((set & 1) && !tolerant)
5bd11d0d 222 warnx(_("ignoring given class data for idle class"));
560cdabb 223 data = 7;
48d7b13a
KZ
224 break;
225 default:
cbc1dc96
KZ
226 if (!tolerant)
227 warnx(_("unknown prio class %d"), ioclass);
228 break;
48d7b13a
KZ
229 }
230
bd2ff3d2 231 if (!set && !which && optind == argc)
fcc2b2da
KZ
232 /*
233 * ionice without options, print the current ioprio
234 */
bd2ff3d2
MY
235 ioprio_print(0, IOPRIO_WHO_PROCESS);
236 else if (!set && who) {
fcc2b2da 237 /*
bd2ff3d2 238 * ionice -p|-P|-u ID [ID ...]
fcc2b2da 239 */
bd2ff3d2 240 ioprio_print(which, who);
48d7b13a 241
ef0fe2e8 242 for(; argv[optind]; ++optind) {
bd2ff3d2
MY
243 which = strtos32_or_err(argv[optind], invalid_msg);
244 ioprio_print(which, who);
48d7b13a 245 }
bd2ff3d2 246 } else if (set && who) {
fcc2b2da 247 /*
bd2ff3d2 248 * ionice -c CLASS -p|-P|-u ID [ID ...]
fcc2b2da 249 */
bd2ff3d2 250 ioprio_setid(which, ioclass, data, who);
ef0fe2e8 251
fcc2b2da 252 for(; argv[optind]; ++optind) {
bd2ff3d2
MY
253 which = strtos32_or_err(argv[optind], invalid_msg);
254 ioprio_setid(which, ioclass, data, who);
2b258413 255 }
fcc2b2da
KZ
256 } else if (argv[optind]) {
257 /*
258 * ionice [-c CLASS] COMMAND
259 */
bd2ff3d2 260 ioprio_setid(0, ioclass, data, IOPRIO_WHO_PROCESS);
fcc2b2da 261 execvp(argv[optind], &argv[optind]);
61b62222 262 errexec(argv[optind]);
6e1eda6f
RM
263 } else {
264 warnx(_("bad usage"));
265 errtryhelp(EXIT_FAILURE);
266 }
48d7b13a 267
a5e9b75f 268 return EXIT_SUCCESS;
48d7b13a 269}