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