]> git.ipfire.org Git - thirdparty/util-linux.git/blame - schedutils/chrt.c
Merge branch 'close_stream' of git://github.com/kerolasa/lelux-utiliteetit
[thirdparty/util-linux.git] / schedutils / chrt.c
CommitLineData
48d7b13a
KZ
1/*
2 * chrt.c - chrt
3 * Command-line utility for manipulating a task's real-time attributes
4 *
5 * Robert Love <rml@tech9.net>
6 * 27-Apr-2002: initial version
78904e76 7 * 04-May-2011: make thread aware - Davidlohr Bueso <dave@gnu.org>
48d7b13a
KZ
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License, v2, as
11 * published by the Free Software Foundation
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
7cebf0bb
SK
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
48d7b13a
KZ
21 *
22 * Copyright (C) 2004 Robert Love
23 */
24
48d7b13a
KZ
25#include <stdio.h>
26#include <stdlib.h>
27#include <sched.h>
28#include <unistd.h>
29#include <getopt.h>
30#include <errno.h>
bd9d9f05 31
b6534e4f 32#include "c.h"
bd9d9f05 33#include "nls.h"
ed8ec2a6 34#include "closestream.h"
8abcf290 35#include "strutils.h"
78904e76 36#include "procutils.h"
24295096 37
09dd84ca
KZ
38/* the SCHED_BATCH is supported since Linux 2.6.16
39 * -- temporary workaround for people with old glibc headers
40 */
b64279da 41#if defined (__linux__) && !defined(SCHED_BATCH)
09dd84ca
KZ
42# define SCHED_BATCH 3
43#endif
44
c779d6e9
MS
45/* the SCHED_IDLE is supported since Linux 2.6.23
46 * commit id 0e6aca43e08a62a48d6770e9a159dbec167bf4c6
47 * -- temporary workaround for people with old glibc headers
48 */
b64279da 49#if defined (__linux__) && !defined(SCHED_IDLE)
c779d6e9
MS
50# define SCHED_IDLE 5
51#endif
52
0fefbedc
AK
53#if defined(__linux__) && !defined(SCHED_RESET_ON_FORK)
54#define SCHED_RESET_ON_FORK 0x40000000
55#endif
56
57
98da1298 58static void __attribute__((__noreturn__)) show_usage(int rc)
48d7b13a 59{
aaf6349f
BS
60 FILE *out = rc == EXIT_SUCCESS ? stdout : stderr;
61
62 fprintf(out, _(
63 "\nchrt - manipulate real-time attributes of a process\n"
bd9d9f05
KZ
64 "\nSet policy:\n"
65 " chrt [options] <policy> <priority> {<pid> | <command> [<arg> ...]}\n"
66 "\nGet policy:\n"
aaf6349f
BS
67 " chrt [options] {<pid> | <command> [<arg> ...]}\n"));
68
69 fprintf(out, _(
bd9d9f05
KZ
70 "\nScheduling policies:\n"
71 " -b | --batch set policy to SCHED_BATCH\n"
72 " -f | --fifo set policy to SCHED_FIFO\n"
73 " -i | --idle set policy to SCHED_IDLE\n"
74 " -o | --other set policy to SCHED_OTHER\n"
aaf6349f
BS
75 " -r | --rr set policy to SCHED_RR (default)\n"));
76
4951f9b3 77#ifdef SCHED_RESET_ON_FORK
aaf6349f 78 fprintf(out, _(
cdfb1e88 79 "\nScheduling flags:\n"
aaf6349f 80 " -R | --reset-on-fork set SCHED_RESET_ON_FORK for FIFO or RR\n"));
4951f9b3 81#endif
aaf6349f 82 fprintf(out, _(
bd9d9f05 83 "\nOptions:\n"
1b9b57ac 84 " -a | --all-tasks operate on all the tasks (threads) for a given pid\n"
bd9d9f05 85 " -h | --help display this help\n"
bd9d9f05 86 " -m | --max show min and max valid priorities\n"
aaf6349f 87 " -p | --pid operate on existing given pid\n"
bd9d9f05
KZ
88 " -v | --verbose display status information\n"
89 " -V | --version output version information\n\n"));
90
91 exit(rc);
48d7b13a
KZ
92}
93
a9a3e5f2 94static void show_rt_info(pid_t pid, int isnew)
48d7b13a
KZ
95{
96 struct sched_param sp;
97 int policy;
98
99 /* don't display "pid 0" as that is confusing */
100 if (!pid)
101 pid = getpid();
102
103 policy = sched_getscheduler(pid);
bd9d9f05
KZ
104 if (policy == -1)
105 err(EXIT_FAILURE, _("failed to get pid %d's policy"), pid);
48d7b13a 106
a9a3e5f2
BS
107 if (isnew)
108 printf(_("pid %d's new scheduling policy: "), pid);
109 else
110 printf(_("pid %d's current scheduling policy: "), pid);
111
48d7b13a
KZ
112 switch (policy) {
113 case SCHED_OTHER:
114 printf("SCHED_OTHER\n");
115 break;
116 case SCHED_FIFO:
117 printf("SCHED_FIFO\n");
118 break;
4951f9b3 119#ifdef SCHED_RESET_ON_FORK
110d680a 120 case SCHED_FIFO | SCHED_RESET_ON_FORK:
0fefbedc
AK
121 printf("SCHED_FIFO|SCHED_RESET_ON_FORK\n");
122 break;
4951f9b3 123#endif
b64279da 124#ifdef SCHED_IDLE
c779d6e9
MS
125 case SCHED_IDLE:
126 printf("SCHED_IDLE\n");
6c00cbbe 127 break;
b64279da 128#endif
48d7b13a
KZ
129 case SCHED_RR:
130 printf("SCHED_RR\n");
131 break;
4951f9b3 132#ifdef SCHED_RESET_ON_FORK
110d680a 133 case SCHED_RR | SCHED_RESET_ON_FORK:
0fefbedc
AK
134 printf("SCHED_RR|SCHED_RESET_ON_FORK\n");
135 break;
4951f9b3 136#endif
b64279da 137#ifdef SCHED_BATCH
df3773fb
KZ
138 case SCHED_BATCH:
139 printf("SCHED_BATCH\n");
140 break;
b64279da 141#endif
48d7b13a 142 default:
8a44fb01 143 warnx(_("unknown scheduling policy"));
48d7b13a
KZ
144 }
145
bd9d9f05
KZ
146 if (sched_getparam(pid, &sp))
147 err(EXIT_FAILURE, _("failed to get pid %d's attributes"), pid);
48d7b13a 148
a9a3e5f2
BS
149 if (isnew)
150 printf(_("pid %d's new scheduling priority: %d\n"),
151 pid, sp.sched_priority);
152 else
153 printf(_("pid %d's current scheduling priority: %d\n"),
154 pid, sp.sched_priority);
48d7b13a
KZ
155}
156
157static void show_min_max(void)
158{
90b7d261 159 unsigned long i;
110d680a
SK
160 int policies[] = {
161 SCHED_OTHER,
162 SCHED_FIFO,
163 SCHED_RR,
b64279da 164#ifdef SCHED_BATCH
110d680a 165 SCHED_BATCH,
b64279da
AJ
166#endif
167#ifdef SCHED_IDLE
110d680a 168 SCHED_IDLE,
b64279da 169#endif
110d680a
SK
170 };
171 const char *names[] = {
172 "OTHER",
173 "FIFO",
174 "RR",
b64279da 175#ifdef SCHED_BATCH
110d680a 176 "BATCH",
b64279da
AJ
177#endif
178#ifdef SCHED_IDLE
110d680a 179 "IDLE",
b64279da 180#endif
110d680a 181 };
bd9d9f05
KZ
182
183 for (i = 0; i < ARRAY_SIZE(policies); i++) {
184 int max = sched_get_priority_max(policies[i]);
185 int min = sched_get_priority_min(policies[i]);
186
187 if (max >= 0 && min >= 0)
188 printf(_("SCHED_%s min/max priority\t: %d/%d\n"),
189 names[i], min, max);
190 else
191 printf(_("SCHED_%s not supported?\n"), names[i]);
192 }
48d7b13a
KZ
193}
194
110d680a 195int main(int argc, char **argv)
48d7b13a 196{
503cbbe1
KZ
197 int i, policy = SCHED_RR, priority = 0, verbose = 0, policy_flag = 0,
198 all_tasks = 0;
48d7b13a 199 struct sched_param sp;
697d58e8 200 pid_t pid = -1;
48d7b13a 201
6c7d5ae9 202 static const struct option longopts[] = {
78904e76 203 { "all-tasks", 0, NULL, 'a' },
df3773fb 204 { "batch", 0, NULL, 'b' },
48d7b13a 205 { "fifo", 0, NULL, 'f' },
c779d6e9 206 { "idle", 0, NULL, 'i' },
48d7b13a
KZ
207 { "pid", 0, NULL, 'p' },
208 { "help", 0, NULL, 'h' },
209 { "max", 0, NULL, 'm' },
210 { "other", 0, NULL, 'o' },
211 { "rr", 0, NULL, 'r' },
cdfb1e88 212 { "reset-on-fork", 0, NULL, 'R' },
48d7b13a
KZ
213 { "verbose", 0, NULL, 'v' },
214 { "version", 0, NULL, 'V' },
215 { NULL, 0, NULL, 0 }
216 };
217
bd9d9f05
KZ
218 setlocale(LC_ALL, "");
219 bindtextdomain(PACKAGE, LOCALEDIR);
220 textdomain(PACKAGE);
ed8ec2a6 221 atexit(close_stdout);
bd9d9f05 222
78904e76 223 while((i = getopt_long(argc, argv, "+abfiphmoRrvV", longopts, NULL)) != -1)
48d7b13a 224 {
bd9d9f05 225 int ret = EXIT_FAILURE;
48d7b13a
KZ
226
227 switch (i) {
78904e76
DB
228 case 'a':
229 all_tasks = 1;
230 break;
df3773fb 231 case 'b':
b64279da 232#ifdef SCHED_BATCH
df3773fb 233 policy = SCHED_BATCH;
b64279da 234#endif
df3773fb 235 break;
48d7b13a
KZ
236 case 'f':
237 policy = SCHED_FIFO;
238 break;
cdfb1e88 239 case 'R':
c150589f 240#ifdef SCHED_RESET_ON_FORK
cdfb1e88 241 policy_flag |= SCHED_RESET_ON_FORK;
4951f9b3 242#endif
c150589f 243 break;
c779d6e9 244 case 'i':
b64279da 245#ifdef SCHED_IDLE
c779d6e9 246 policy = SCHED_IDLE;
b64279da 247#endif
c779d6e9 248 break;
48d7b13a
KZ
249 case 'm':
250 show_min_max();
110d680a 251 return EXIT_SUCCESS;
48d7b13a
KZ
252 case 'o':
253 policy = SCHED_OTHER;
254 break;
255 case 'p':
256 errno = 0;
8abcf290 257 pid = strtol_or_err(argv[argc - 1], _("failed to parse pid"));
48d7b13a
KZ
258 break;
259 case 'r':
260 policy = SCHED_RR;
261 break;
262 case 'v':
263 verbose = 1;
264 break;
265 case 'V':
110d680a
SK
266 printf("%s from %s\n", program_invocation_short_name,
267 PACKAGE_STRING);
268 return EXIT_SUCCESS;
48d7b13a 269 case 'h':
bd9d9f05 270 ret = EXIT_SUCCESS;
337b8ead 271 /* fallthrough */
48d7b13a 272 default:
bd9d9f05 273 show_usage(ret);
48d7b13a 274 }
48d7b13a
KZ
275 }
276
110d680a
SK
277 if (((pid > -1) && argc - optind < 1) ||
278 ((pid == -1) && argc - optind < 2))
bd9d9f05 279 show_usage(EXIT_FAILURE);
48d7b13a 280
697d58e8 281 if ((pid > -1) && (verbose || argc - optind == 1)) {
503cbbe1
KZ
282 if (all_tasks) {
283 pid_t tid;
284 struct proc_tasks *ts = proc_open_tasks(pid);
285
286 if (!ts)
8a44fb01 287 err(EXIT_FAILURE, _("cannot obtain the list of tasks"));
503cbbe1
KZ
288 while (!proc_next_tid(ts, &tid))
289 show_rt_info(tid, FALSE);
290 proc_close_tasks(ts);
291 } else
292 show_rt_info(pid, FALSE);
293
48d7b13a 294 if (argc - optind == 1)
bd9d9f05 295 return EXIT_SUCCESS;
48d7b13a
KZ
296 }
297
298 errno = 0;
8abcf290 299 priority = strtol_or_err(argv[optind], _("failed to parse priority"));
48d7b13a 300
4951f9b3 301#ifdef SCHED_RESET_ON_FORK
cdfb1e88
KZ
302 /* sanity check */
303 if ((policy_flag & SCHED_RESET_ON_FORK) &&
304 !(policy == SCHED_FIFO || policy == SCHED_RR))
305 errx(EXIT_FAILURE, _("SCHED_RESET_ON_FORK flag is suppoted for "
110d680a 306 "SCHED_FIFO and SCHED_RR policies only"));
4951f9b3 307#endif
cdfb1e88
KZ
308
309 policy |= policy_flag;
310
697d58e8
MK
311 if (pid == -1)
312 pid = 0;
48d7b13a 313 sp.sched_priority = priority;
78904e76
DB
314
315 if (all_tasks) {
316 pid_t tid;
317 struct proc_tasks *ts = proc_open_tasks(pid);
318
319 if (!ts)
8a44fb01 320 err(EXIT_FAILURE, _("cannot obtain the list of tasks"));
78904e76
DB
321 while (!proc_next_tid(ts, &tid))
322 if (sched_setscheduler(tid, policy, &sp) == -1)
323 err(EXIT_FAILURE, _("failed to set tid %d's policy"), tid);
78904e76 324 proc_close_tasks(ts);
110d680a
SK
325 } else if (sched_setscheduler(pid, policy, &sp) == -1)
326 err(EXIT_FAILURE, _("failed to set pid %d's policy"), pid);
48d7b13a
KZ
327
328 if (verbose)
a9a3e5f2 329 show_rt_info(pid, TRUE);
48d7b13a
KZ
330
331 if (!pid) {
332 argv += optind + 1;
333 execvp(argv[0], argv);
334 perror("execvp");
bd9d9f05 335 err(EXIT_FAILURE, _("failed to execute %s"), argv[0]);
48d7b13a
KZ
336 }
337
bd9d9f05 338 return EXIT_SUCCESS;
48d7b13a 339}