]> git.ipfire.org Git - thirdparty/util-linux.git/blob - schedutils/ionice.c
schedutils: remove unneeded header files
[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 <jens@axboe.dk>
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/syscall.h>
15 #include <err.h>
16
17 #include "nls.h"
18
19 #include "strutils.h"
20
21 static int tolerant;
22
23 static inline int ioprio_set(int which, int who, int ioprio)
24 {
25 return syscall(SYS_ioprio_set, which, who, ioprio);
26 }
27
28 static inline int ioprio_get(int which, int who)
29 {
30 return syscall(SYS_ioprio_get, which, who);
31 }
32
33 enum {
34 IOPRIO_CLASS_NONE,
35 IOPRIO_CLASS_RT,
36 IOPRIO_CLASS_BE,
37 IOPRIO_CLASS_IDLE,
38 };
39
40 enum {
41 IOPRIO_WHO_PROCESS = 1,
42 IOPRIO_WHO_PGRP,
43 IOPRIO_WHO_USER,
44 };
45
46 #define IOPRIO_CLASS_SHIFT 13
47
48 const char *to_prio[] = { "none", "realtime", "best-effort", "idle", };
49
50 static void ioprio_print(int pid)
51 {
52 int ioprio, ioclass;
53
54 ioprio = ioprio_get(IOPRIO_WHO_PROCESS, pid);
55
56 if (ioprio == -1)
57 err(EXIT_FAILURE, _("ioprio_get failed"));
58 else {
59 ioclass = ioprio >> IOPRIO_CLASS_SHIFT;
60 if (ioclass != IOPRIO_CLASS_IDLE) {
61 ioprio = ioprio & 0xff;
62 printf("%s: prio %d\n", to_prio[ioclass], ioprio);
63 } else
64 printf("%s\n", to_prio[ioclass]);
65 }
66 }
67
68
69 static void ioprio_setpid(pid_t pid, int ioprio, int ioclass)
70 {
71 int rc = ioprio_set(IOPRIO_WHO_PROCESS, pid,
72 ioprio | ioclass << IOPRIO_CLASS_SHIFT);
73
74 if (rc == -1 && !tolerant)
75 err(EXIT_FAILURE, _("ioprio_set failed"));
76 }
77
78 static void usage(int rc)
79 {
80 fprintf(stdout, _(
81 "\nionice - sets or gets process io scheduling class and priority.\n"
82 "\nUsage:\n"
83 " ionice [ options ] -p <pid> [<pid> ...]\n"
84 " ionice [ options ] <command> [<arg> ...]\n"
85 "\nOptions:\n"
86 " -n <classdata> class data (0-7, lower being higher prio)\n"
87 " -c <class> scheduling class\n"
88 " 0: none, 1: realtime, 2: best-effort, 3: idle\n"
89 " -t ignore failures\n"
90 " -h this help\n\n"));
91 exit(rc);
92 }
93
94 int main(int argc, char *argv[])
95 {
96 int ioprio = 4, set = 0, ioclass = IOPRIO_CLASS_BE, c;
97 pid_t pid = 0;
98
99 setlocale(LC_ALL, "");
100 bindtextdomain(PACKAGE, LOCALEDIR);
101 textdomain(PACKAGE);
102
103 while ((c = getopt(argc, argv, "+n:c:p:th")) != EOF) {
104 switch (c) {
105 case 'n':
106 ioprio = strtol_or_err(optarg, _("failed to parse class data"));
107 set |= 1;
108 break;
109 case 'c':
110 ioclass = strtol_or_err(optarg, _("failed to parse class"));
111 set |= 2;
112 break;
113 case 'p':
114 pid = strtol_or_err(optarg, _("failed to parse pid"));
115 break;
116 case 't':
117 tolerant = 1;
118 break;
119 case 'h':
120 usage(EXIT_SUCCESS);
121 default:
122 usage(EXIT_FAILURE);
123 }
124 }
125
126 switch (ioclass) {
127 case IOPRIO_CLASS_NONE:
128 if (set & 1)
129 warnx(_("ignoring given class data for none class"));
130 ioprio = 0;
131 break;
132 case IOPRIO_CLASS_RT:
133 case IOPRIO_CLASS_BE:
134 break;
135 case IOPRIO_CLASS_IDLE:
136 if (set & 1)
137 warnx(_("ignoring given class data for idle class"));
138 ioprio = 7;
139 break;
140 default:
141 errx(EXIT_FAILURE, _("bad prio class %d"), ioclass);
142 }
143
144 if (!set) {
145 ioprio_print(pid);
146
147 for(; argv[optind]; ++optind) {
148 pid = strtol_or_err(argv[optind], _("failed to parse pid"));
149 ioprio_print(pid);
150 }
151 } else {
152 if (pid) {
153 ioprio_setpid(pid, ioprio, ioclass);
154
155 for(; argv[optind]; ++optind)
156 {
157 pid = strtol_or_err(argv[optind], _("failed to parse pid"));
158 ioprio_setpid(pid, ioprio, ioclass);
159 }
160 }
161 else if (argv[optind]) {
162 ioprio_setpid(0, ioprio, ioclass);
163 execvp(argv[optind], &argv[optind]);
164 /* execvp should never return */
165 err(EXIT_FAILURE, _("executing %s failed"), argv[optind]);
166 }
167 }
168
169 exit(EXIT_SUCCESS);
170 }