]> git.ipfire.org Git - thirdparty/util-linux.git/blame - schedutils/chrt.c
flock: add error message to translations
[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
89 exit(rc);
48d7b13a
KZ
90}
91
a9a3e5f2 92static void show_rt_info(pid_t pid, int isnew)
48d7b13a
KZ
93{
94 struct sched_param sp;
95 int policy;
96
97 /* don't display "pid 0" as that is confusing */
98 if (!pid)
99 pid = getpid();
100
101 policy = sched_getscheduler(pid);
bd9d9f05
KZ
102 if (policy == -1)
103 err(EXIT_FAILURE, _("failed to get pid %d's policy"), pid);
48d7b13a 104
a9a3e5f2
BS
105 if (isnew)
106 printf(_("pid %d's new scheduling policy: "), pid);
107 else
108 printf(_("pid %d's current scheduling policy: "), pid);
109
48d7b13a
KZ
110 switch (policy) {
111 case SCHED_OTHER:
112 printf("SCHED_OTHER\n");
113 break;
114 case SCHED_FIFO:
115 printf("SCHED_FIFO\n");
116 break;
4951f9b3 117#ifdef SCHED_RESET_ON_FORK
110d680a 118 case SCHED_FIFO | SCHED_RESET_ON_FORK:
0fefbedc
AK
119 printf("SCHED_FIFO|SCHED_RESET_ON_FORK\n");
120 break;
4951f9b3 121#endif
b64279da 122#ifdef SCHED_IDLE
c779d6e9
MS
123 case SCHED_IDLE:
124 printf("SCHED_IDLE\n");
6c00cbbe 125 break;
b64279da 126#endif
48d7b13a
KZ
127 case SCHED_RR:
128 printf("SCHED_RR\n");
129 break;
4951f9b3 130#ifdef SCHED_RESET_ON_FORK
110d680a 131 case SCHED_RR | SCHED_RESET_ON_FORK:
0fefbedc
AK
132 printf("SCHED_RR|SCHED_RESET_ON_FORK\n");
133 break;
4951f9b3 134#endif
b64279da 135#ifdef SCHED_BATCH
df3773fb
KZ
136 case SCHED_BATCH:
137 printf("SCHED_BATCH\n");
138 break;
b64279da 139#endif
48d7b13a 140 default:
8a44fb01 141 warnx(_("unknown scheduling policy"));
48d7b13a
KZ
142 }
143
bd9d9f05
KZ
144 if (sched_getparam(pid, &sp))
145 err(EXIT_FAILURE, _("failed to get pid %d's attributes"), pid);
48d7b13a 146
a9a3e5f2
BS
147 if (isnew)
148 printf(_("pid %d's new scheduling priority: %d\n"),
149 pid, sp.sched_priority);
150 else
151 printf(_("pid %d's current scheduling priority: %d\n"),
152 pid, sp.sched_priority);
48d7b13a
KZ
153}
154
155static void show_min_max(void)
156{
90b7d261 157 unsigned long i;
110d680a
SK
158 int policies[] = {
159 SCHED_OTHER,
160 SCHED_FIFO,
161 SCHED_RR,
b64279da 162#ifdef SCHED_BATCH
110d680a 163 SCHED_BATCH,
b64279da
AJ
164#endif
165#ifdef SCHED_IDLE
110d680a 166 SCHED_IDLE,
b64279da 167#endif
110d680a
SK
168 };
169 const char *names[] = {
170 "OTHER",
171 "FIFO",
172 "RR",
b64279da 173#ifdef SCHED_BATCH
110d680a 174 "BATCH",
b64279da
AJ
175#endif
176#ifdef SCHED_IDLE
110d680a 177 "IDLE",
b64279da 178#endif
110d680a 179 };
bd9d9f05
KZ
180
181 for (i = 0; i < ARRAY_SIZE(policies); i++) {
182 int max = sched_get_priority_max(policies[i]);
183 int min = sched_get_priority_min(policies[i]);
184
185 if (max >= 0 && min >= 0)
186 printf(_("SCHED_%s min/max priority\t: %d/%d\n"),
187 names[i], min, max);
188 else
189 printf(_("SCHED_%s not supported?\n"), names[i]);
190 }
48d7b13a
KZ
191}
192
110d680a 193int main(int argc, char **argv)
48d7b13a 194{
503cbbe1
KZ
195 int i, policy = SCHED_RR, priority = 0, verbose = 0, policy_flag = 0,
196 all_tasks = 0;
48d7b13a 197 struct sched_param sp;
697d58e8 198 pid_t pid = -1;
48d7b13a 199
6c7d5ae9 200 static const struct option longopts[] = {
78904e76 201 { "all-tasks", 0, NULL, 'a' },
df3773fb 202 { "batch", 0, NULL, 'b' },
48d7b13a 203 { "fifo", 0, NULL, 'f' },
c779d6e9 204 { "idle", 0, NULL, 'i' },
48d7b13a
KZ
205 { "pid", 0, NULL, 'p' },
206 { "help", 0, NULL, 'h' },
207 { "max", 0, NULL, 'm' },
208 { "other", 0, NULL, 'o' },
209 { "rr", 0, NULL, 'r' },
cdfb1e88 210 { "reset-on-fork", 0, NULL, 'R' },
48d7b13a
KZ
211 { "verbose", 0, NULL, 'v' },
212 { "version", 0, NULL, 'V' },
213 { NULL, 0, NULL, 0 }
214 };
215
bd9d9f05
KZ
216 setlocale(LC_ALL, "");
217 bindtextdomain(PACKAGE, LOCALEDIR);
218 textdomain(PACKAGE);
ed8ec2a6 219 atexit(close_stdout);
bd9d9f05 220
78904e76 221 while((i = getopt_long(argc, argv, "+abfiphmoRrvV", longopts, NULL)) != -1)
48d7b13a 222 {
bd9d9f05 223 int ret = EXIT_FAILURE;
48d7b13a
KZ
224
225 switch (i) {
78904e76
DB
226 case 'a':
227 all_tasks = 1;
228 break;
df3773fb 229 case 'b':
b64279da 230#ifdef SCHED_BATCH
df3773fb 231 policy = SCHED_BATCH;
b64279da 232#endif
df3773fb 233 break;
48d7b13a
KZ
234 case 'f':
235 policy = SCHED_FIFO;
236 break;
cdfb1e88 237 case 'R':
c150589f 238#ifdef SCHED_RESET_ON_FORK
cdfb1e88 239 policy_flag |= SCHED_RESET_ON_FORK;
4951f9b3 240#endif
c150589f 241 break;
c779d6e9 242 case 'i':
b64279da 243#ifdef SCHED_IDLE
c779d6e9 244 policy = SCHED_IDLE;
b64279da 245#endif
c779d6e9 246 break;
48d7b13a
KZ
247 case 'm':
248 show_min_max();
110d680a 249 return EXIT_SUCCESS;
48d7b13a
KZ
250 case 'o':
251 policy = SCHED_OTHER;
252 break;
253 case 'p':
254 errno = 0;
630ed89d 255 pid = strtos32_or_err(argv[argc - 1], _("invalid PID argument"));
48d7b13a
KZ
256 break;
257 case 'r':
258 policy = SCHED_RR;
259 break;
260 case 'v':
261 verbose = 1;
262 break;
263 case 'V':
8c219bf4
BS
264 printf(_("%s from %s\n"), program_invocation_short_name,
265 PACKAGE_STRING);
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}