]>
Commit | Line | Data |
---|---|---|
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 | ||
acde3a05 | 51 | /* flag by sched_getscheduler() */ |
0fefbedc | 52 | #if defined(__linux__) && !defined(SCHED_RESET_ON_FORK) |
acde3a05 KZ |
53 | # define SCHED_RESET_ON_FORK 0x40000000 |
54 | #endif | |
55 | ||
56 | /* flag by sched_getattr() */ | |
57 | #if defined(__linux__) && !defined(SCHED_FLAG_RESET_ON_FORK) | |
58 | # define SCHED_FLAG_RESET_ON_FORK 0x01 | |
0fefbedc AK |
59 | #endif |
60 | ||
1a7e6395 | 61 | |
15167589 KZ |
62 | #if defined (__linux__) && !defined(HAVE_SCHED_SETATTR) |
63 | # include <sys/syscall.h> | |
64 | #endif | |
65 | ||
66 | #if defined (__linux__) && !defined(HAVE_SCHED_SETATTR) && defined(SYS_sched_setattr) | |
67 | # define HAVE_SCHED_SETATTR | |
68 | ||
69 | struct sched_attr { | |
70 | uint32_t size; | |
71 | uint32_t sched_policy; | |
72 | uint64_t sched_flags; | |
73 | ||
74 | /* SCHED_NORMAL, SCHED_BATCH */ | |
75 | int32_t sched_nice; | |
76 | ||
77 | /* SCHED_FIFO, SCHED_RR */ | |
78 | uint32_t sched_priority; | |
79 | ||
80 | /* SCHED_DEADLINE (nsec) */ | |
81 | uint64_t sched_runtime; | |
82 | uint64_t sched_deadline; | |
83 | uint64_t sched_period; | |
84 | }; | |
85 | ||
86 | static int sched_setattr(pid_t pid, const struct sched_attr *attr, unsigned int flags) | |
87 | { | |
88 | return syscall(SYS_sched_setattr, pid, attr, flags); | |
89 | } | |
90 | ||
91 | static int sched_getattr(pid_t pid, struct sched_attr *attr, unsigned int size, unsigned int flags) | |
92 | { | |
93 | return syscall(SYS_sched_getattr, pid, attr, size, flags); | |
94 | } | |
1a7e6395 KZ |
95 | #endif |
96 | ||
97 | /* the SCHED_DEADLINE is supported since Linux 3.14 | |
98 | * commit id aab03e05e8f7e26f51dee792beddcb5cca9215a5 | |
99 | * -- sched_setattr() is required for this policy! | |
100 | */ | |
101 | #if defined (__linux__) && !defined(SCHED_DEADLINE) && defined(HAVE_SCHED_SETATTR) | |
102 | # define SCHED_DEADLINE 6 | |
103 | #endif | |
15167589 | 104 | |
7a4ea566 KZ |
105 | /* control struct */ |
106 | struct chrt_ctl { | |
107 | pid_t pid; | |
108 | int policy; /* SCHED_* */ | |
109 | int priority; | |
110 | ||
1a7e6395 KZ |
111 | uint64_t runtime; /* --sched-* options */ |
112 | uint64_t deadline; | |
113 | uint64_t period; | |
114 | ||
7a4ea566 KZ |
115 | unsigned int all_tasks : 1, /* all threads of the PID */ |
116 | reset_on_fork : 1, /* SCHED_RESET_ON_FORK */ | |
a30cf650 | 117 | altered : 1, /* sched_set**() used */ |
7a4ea566 KZ |
118 | verbose : 1; /* verbose output */ |
119 | }; | |
0fefbedc | 120 | |
98da1298 | 121 | static void __attribute__((__noreturn__)) show_usage(int rc) |
48d7b13a | 122 | { |
aaf6349f BS |
123 | FILE *out = rc == EXIT_SUCCESS ? stdout : stderr; |
124 | ||
451dbcfa | 125 | fputs(_("Show or change the real-time scheduling attributes of a process.\n"), out); |
9acbe2aa BS |
126 | fputs(USAGE_SEPARATOR, out); |
127 | fputs(_("Set policy:\n" | |
128 | " chrt [options] <priority> <command> [<arg>...]\n" | |
a6fec537 | 129 | " chrt [options] --pid <priority> <pid>\n"), out); |
9acbe2aa BS |
130 | fputs(USAGE_SEPARATOR, out); |
131 | fputs(_("Get policy:\n" | |
132 | " chrt [options] -p <pid>\n"), out); | |
aaf6349f | 133 | |
9acbe2aa BS |
134 | fputs(USAGE_SEPARATOR, out); |
135 | fputs(_("Policy options:\n"), out); | |
136 | fputs(_(" -b, --batch set policy to SCHED_BATCH\n"), out); | |
1a7e6395 | 137 | fputs(_(" -d, --deadline set policy to SCHED_DEADLINE\n"), out); |
9acbe2aa BS |
138 | fputs(_(" -f, --fifo set policy to SCHED_FIFO\n"), out); |
139 | fputs(_(" -i, --idle set policy to SCHED_IDLE\n"), out); | |
140 | fputs(_(" -o, --other set policy to SCHED_OTHER\n"), out); | |
141 | fputs(_(" -r, --rr set policy to SCHED_RR (default)\n"), out); | |
aaf6349f | 142 | |
9acbe2aa | 143 | fputs(USAGE_SEPARATOR, out); |
1a7e6395 KZ |
144 | fputs(_("Scheduling options:\n"), out); |
145 | fputs(_(" -R, --reset-on-fork set SCHED_RESET_ON_FORK for FIFO or RR\n"), out); | |
146 | fputs(_(" -T, --sched-runtime <ns> runtime parameter for DEADLINE\n"), out); | |
147 | fputs(_(" -P, --sched-period <ns> period parameter for DEADLINE\n"), out); | |
148 | fputs(_(" -D, --sched-deadline <ns> deadline parameter for DEADLINE\n"), out); | |
149 | ||
9acbe2aa BS |
150 | fputs(USAGE_SEPARATOR, out); |
151 | fputs(_("Other options:\n"), out); | |
152 | fputs(_(" -a, --all-tasks operate on all the tasks (threads) for a given pid\n"), out); | |
153 | fputs(_(" -m, --max show min and max valid priorities\n"), out); | |
154 | fputs(_(" -p, --pid operate on existing given pid\n"), out); | |
155 | fputs(_(" -v, --verbose display status information\n"), out); | |
156 | ||
157 | fputs(USAGE_SEPARATOR, out); | |
158 | fputs(USAGE_HELP, out); | |
159 | fputs(USAGE_VERSION, out); | |
bd9d9f05 | 160 | |
a587cc55 | 161 | fprintf(out, USAGE_MAN_TAIL("chrt(1)")); |
bd9d9f05 | 162 | exit(rc); |
48d7b13a KZ |
163 | } |
164 | ||
acde3a05 | 165 | static const char *get_policy_name(int policy) |
48d7b13a | 166 | { |
48d7b13a KZ |
167 | switch (policy) { |
168 | case SCHED_OTHER: | |
acde3a05 | 169 | return "SCHED_OTHER"; |
48d7b13a | 170 | case SCHED_FIFO: |
a03eac52 | 171 | #ifdef SCHED_RESET_ON_FORK |
110d680a | 172 | case SCHED_FIFO | SCHED_RESET_ON_FORK: |
a03eac52 | 173 | #endif |
acde3a05 | 174 | return "SCHED_FIFO"; |
b64279da | 175 | #ifdef SCHED_IDLE |
c779d6e9 | 176 | case SCHED_IDLE: |
acde3a05 | 177 | return "SCHED_IDLE"; |
b64279da | 178 | #endif |
48d7b13a | 179 | case SCHED_RR: |
a03eac52 | 180 | #ifdef SCHED_RESET_ON_FORK |
59e4a382 | 181 | case SCHED_RR | SCHED_RESET_ON_FORK: |
a03eac52 | 182 | #endif |
acde3a05 | 183 | return "SCHED_RR"; |
b64279da | 184 | #ifdef SCHED_BATCH |
df3773fb | 185 | case SCHED_BATCH: |
acde3a05 | 186 | return "SCHED_BATCH"; |
1a7e6395 KZ |
187 | #endif |
188 | #ifdef SCHED_DEADLINE | |
189 | case SCHED_DEADLINE: | |
acde3a05 | 190 | return "SCHED_DEADLINE"; |
b64279da | 191 | #endif |
48d7b13a | 192 | default: |
acde3a05 | 193 | break; |
48d7b13a KZ |
194 | } |
195 | ||
acde3a05 KZ |
196 | return _("unknown"); |
197 | } | |
198 | ||
199 | static void show_sched_pid_info(struct chrt_ctl *ctl, pid_t pid) | |
200 | { | |
201 | int policy, reset_on_fork = 0, prio = 0; | |
202 | #ifdef SCHED_DEADLINE | |
203 | uint64_t deadline = 0, runtime = 0, period = 0; | |
204 | #endif | |
205 | ||
206 | /* don't display "pid 0" as that is confusing */ | |
207 | if (!pid) | |
208 | pid = getpid(); | |
209 | ||
210 | #ifdef HAVE_SCHED_SETATTR | |
211 | { | |
212 | struct sched_attr sa; | |
213 | ||
214 | if (sched_getattr(pid, &sa, sizeof(sa), 0) != 0) | |
215 | err(EXIT_FAILURE, _("failed to get pid %d's policy"), pid); | |
216 | ||
217 | policy = sa.sched_policy; | |
218 | prio = sa.sched_priority; | |
219 | reset_on_fork = sa.sched_flags & SCHED_FLAG_RESET_ON_FORK; | |
220 | deadline = sa.sched_deadline; | |
221 | runtime = sa.sched_runtime; | |
222 | period = sa.sched_period; | |
223 | } | |
224 | #else /* !HAVE_SCHED_SETATTR */ | |
225 | { | |
226 | struct sched_param sp; | |
227 | ||
228 | policy = sched_getscheduler(pid); | |
229 | if (policy == -1) | |
230 | err(EXIT_FAILURE, _("failed to get pid %d's policy"), pid); | |
231 | ||
232 | if (sched_getparam(pid, &sp) != 0) | |
233 | err(EXIT_FAILURE, _("failed to get pid %d's attributes"), pid); | |
234 | else | |
235 | prio = sp.sched_priority; | |
236 | # ifdef SCHED_RESET_ON_FORK | |
237 | if (policy == (SCHED_FIFO|SCHED_RESET_ON_FORK) || policy == (SCHED_BATCH|SCHED_RESET_ON_FORK)) | |
238 | reset_on_fork = 1; | |
239 | # endif | |
240 | } | |
241 | #endif /* !HAVE_SCHED_SETATTR */ | |
48d7b13a | 242 | |
a30cf650 | 243 | if (ctl->altered) |
acde3a05 | 244 | printf(_("pid %d's new scheduling policy: %s"), pid, get_policy_name(policy)); |
a9a3e5f2 | 245 | else |
acde3a05 KZ |
246 | printf(_("pid %d's current scheduling policy: %s"), pid, get_policy_name(policy)); |
247 | ||
248 | if (reset_on_fork) | |
249 | printf("|SCHED_RESET_ON_FORK"); | |
250 | putchar('\n'); | |
251 | ||
252 | if (ctl->altered) | |
253 | printf(_("pid %d's new scheduling priority: %d\n"), pid, prio); | |
254 | else | |
255 | printf(_("pid %d's current scheduling priority: %d\n"), pid, prio); | |
256 | ||
257 | #ifdef SCHED_DEADLINE | |
258 | if (policy == SCHED_DEADLINE) { | |
259 | if (ctl->altered) | |
260 | printf(_("pid %d's new runtime/deadline/period parameters: %ju/%ju/%ju\n"), | |
261 | pid, runtime, deadline, period); | |
262 | else | |
263 | printf(_("pid %d's current runtime/deadline/period parameters: %ju/%ju/%ju\n"), | |
264 | pid, runtime, deadline, period); | |
265 | } | |
266 | #endif | |
48d7b13a KZ |
267 | } |
268 | ||
a30cf650 KZ |
269 | |
270 | static void show_sched_info(struct chrt_ctl *ctl) | |
271 | { | |
272 | if (ctl->all_tasks) { | |
273 | pid_t tid; | |
274 | struct proc_tasks *ts = proc_open_tasks(ctl->pid); | |
275 | ||
276 | if (!ts) | |
277 | err(EXIT_FAILURE, _("cannot obtain the list of tasks")); | |
278 | ||
279 | while (!proc_next_tid(ts, &tid)) | |
280 | show_sched_pid_info(ctl, tid); | |
281 | ||
282 | proc_close_tasks(ts); | |
283 | } else | |
284 | show_sched_pid_info(ctl, ctl->pid); | |
285 | } | |
286 | ||
48d7b13a KZ |
287 | static void show_min_max(void) |
288 | { | |
90b7d261 | 289 | unsigned long i; |
110d680a SK |
290 | int policies[] = { |
291 | SCHED_OTHER, | |
292 | SCHED_FIFO, | |
293 | SCHED_RR, | |
b64279da | 294 | #ifdef SCHED_BATCH |
110d680a | 295 | SCHED_BATCH, |
b64279da AJ |
296 | #endif |
297 | #ifdef SCHED_IDLE | |
110d680a | 298 | SCHED_IDLE, |
1a7e6395 KZ |
299 | #endif |
300 | #ifdef SCHED_DEADLINE | |
301 | SCHED_DEADLINE, | |
b64279da | 302 | #endif |
110d680a | 303 | }; |
bd9d9f05 KZ |
304 | |
305 | for (i = 0; i < ARRAY_SIZE(policies); i++) { | |
acde3a05 KZ |
306 | int plc = policies[i]; |
307 | int max = sched_get_priority_max(plc); | |
308 | int min = sched_get_priority_min(plc); | |
bd9d9f05 KZ |
309 | |
310 | if (max >= 0 && min >= 0) | |
311 | printf(_("SCHED_%s min/max priority\t: %d/%d\n"), | |
acde3a05 | 312 | get_policy_name(plc), min, max); |
bd9d9f05 | 313 | else |
acde3a05 | 314 | printf(_("SCHED_%s not supported?\n"), get_policy_name(plc)); |
bd9d9f05 | 315 | } |
48d7b13a KZ |
316 | } |
317 | ||
15167589 KZ |
318 | #ifndef HAVE_SCHED_SETATTR |
319 | static int set_sched_one(struct chrt_ctl *ctl, pid_t pid) | |
4820a737 KZ |
320 | { |
321 | struct sched_param sp = { .sched_priority = ctl->priority }; | |
15167589 | 322 | int policy = ctl->policy; |
4820a737 | 323 | |
15167589 KZ |
324 | # ifdef SCHED_RESET_ON_FORK |
325 | if (ctl->reset_on_fork) | |
326 | policy |= SCHED_RESET_ON_FORK; | |
327 | # endif | |
328 | return sched_setscheduler(pid, policy, &sp); | |
329 | } | |
330 | ||
331 | #else /* !HAVE_SCHED_SETATTR */ | |
332 | static int set_sched_one(struct chrt_ctl *ctl, pid_t pid) | |
333 | { | |
1a7e6395 | 334 | /* use main() to check if the setting makes sense */ |
15167589 | 335 | struct sched_attr sa = { |
acde3a05 | 336 | .size = sizeof(struct sched_attr), |
15167589 | 337 | .sched_policy = ctl->policy, |
1a7e6395 | 338 | .sched_priority = ctl->priority, |
acde3a05 KZ |
339 | .sched_runtime = ctl->runtime, |
340 | .sched_period = ctl->period, | |
1a7e6395 | 341 | .sched_deadline = ctl->deadline |
15167589 KZ |
342 | }; |
343 | # ifdef SCHED_RESET_ON_FORK | |
344 | if (ctl->reset_on_fork) | |
345 | sa.sched_flags |= SCHED_RESET_ON_FORK; | |
346 | # endif | |
347 | return sched_setattr(pid, &sa, 0); | |
348 | } | |
349 | #endif /* HAVE_SCHED_SETATTR */ | |
350 | ||
351 | static void set_sched(struct chrt_ctl *ctl) | |
352 | { | |
4820a737 KZ |
353 | if (ctl->all_tasks) { |
354 | pid_t tid; | |
355 | struct proc_tasks *ts = proc_open_tasks(ctl->pid); | |
356 | ||
357 | if (!ts) | |
358 | err(EXIT_FAILURE, _("cannot obtain the list of tasks")); | |
359 | ||
360 | while (!proc_next_tid(ts, &tid)) | |
15167589 | 361 | if (set_sched_one(ctl, tid) == -1) |
4820a737 KZ |
362 | err(EXIT_FAILURE, _("failed to set tid %d's policy"), tid); |
363 | ||
364 | proc_close_tasks(ts); | |
365 | ||
15167589 | 366 | } else if (set_sched_one(ctl, ctl->pid) == -1) |
4820a737 KZ |
367 | err(EXIT_FAILURE, _("failed to set pid %d's policy"), ctl->pid); |
368 | ||
369 | ctl->altered = 1; | |
370 | } | |
371 | ||
110d680a | 372 | int main(int argc, char **argv) |
48d7b13a | 373 | { |
7a4ea566 | 374 | struct chrt_ctl _ctl = { .pid = -1 }, *ctl = &_ctl; |
4820a737 | 375 | int c; |
48d7b13a | 376 | |
6c7d5ae9 | 377 | static const struct option longopts[] = { |
1a7e6395 KZ |
378 | { "all-tasks", no_argument, NULL, 'a' }, |
379 | { "batch", no_argument, NULL, 'b' }, | |
380 | { "deadline", no_argument, NULL, 'd' }, | |
381 | { "fifo", no_argument, NULL, 'f' }, | |
382 | { "idle", no_argument, NULL, 'i' }, | |
383 | { "pid", no_argument, NULL, 'p' }, | |
384 | { "help", no_argument, NULL, 'h' }, | |
385 | { "max", no_argument, NULL, 'm' }, | |
386 | { "other", no_argument, NULL, 'o' }, | |
387 | { "rr", no_argument, NULL, 'r' }, | |
388 | { "sched-runtime", required_argument, NULL, 'T' }, | |
389 | { "sched-period", required_argument, NULL, 'P' }, | |
390 | { "sched-deadline", required_argument, NULL, 'D' }, | |
391 | { "reset-on-fork", no_argument, NULL, 'R' }, | |
392 | { "verbose", no_argument, NULL, 'v' }, | |
393 | { "version", no_argument, NULL, 'V' }, | |
394 | { NULL, no_argument, NULL, 0 } | |
48d7b13a KZ |
395 | }; |
396 | ||
bd9d9f05 KZ |
397 | setlocale(LC_ALL, ""); |
398 | bindtextdomain(PACKAGE, LOCALEDIR); | |
399 | textdomain(PACKAGE); | |
ed8ec2a6 | 400 | atexit(close_stdout); |
bd9d9f05 | 401 | |
b3a50671 | 402 | while((c = getopt_long(argc, argv, "+abdD:fiphmoP:T:rRvV", longopts, NULL)) != -1) |
48d7b13a | 403 | { |
bd9d9f05 | 404 | int ret = EXIT_FAILURE; |
48d7b13a | 405 | |
4820a737 | 406 | switch (c) { |
78904e76 | 407 | case 'a': |
7a4ea566 | 408 | ctl->all_tasks = 1; |
78904e76 | 409 | break; |
df3773fb | 410 | case 'b': |
b64279da | 411 | #ifdef SCHED_BATCH |
7a4ea566 | 412 | ctl->policy = SCHED_BATCH; |
1a7e6395 KZ |
413 | #endif |
414 | break; | |
415 | ||
416 | case 'd': | |
417 | #ifdef SCHED_DEADLINE | |
418 | ctl->policy = SCHED_DEADLINE; | |
b64279da | 419 | #endif |
df3773fb | 420 | break; |
48d7b13a | 421 | case 'f': |
7a4ea566 | 422 | ctl->policy = SCHED_FIFO; |
48d7b13a | 423 | break; |
cdfb1e88 | 424 | case 'R': |
7a4ea566 | 425 | ctl->reset_on_fork = 1; |
c150589f | 426 | break; |
c779d6e9 | 427 | case 'i': |
b64279da | 428 | #ifdef SCHED_IDLE |
7a4ea566 | 429 | ctl->policy = SCHED_IDLE; |
b64279da | 430 | #endif |
c779d6e9 | 431 | break; |
48d7b13a KZ |
432 | case 'm': |
433 | show_min_max(); | |
110d680a | 434 | return EXIT_SUCCESS; |
48d7b13a | 435 | case 'o': |
7a4ea566 | 436 | ctl->policy = SCHED_OTHER; |
48d7b13a KZ |
437 | break; |
438 | case 'p': | |
439 | errno = 0; | |
7a4ea566 | 440 | ctl->pid = strtos32_or_err(argv[argc - 1], _("invalid PID argument")); |
48d7b13a KZ |
441 | break; |
442 | case 'r': | |
7a4ea566 | 443 | ctl->policy = SCHED_RR; |
48d7b13a KZ |
444 | break; |
445 | case 'v': | |
7a4ea566 | 446 | ctl->verbose = 1; |
48d7b13a | 447 | break; |
1a7e6395 KZ |
448 | case 'T': |
449 | ctl->runtime = strtou64_or_err(optarg, _("invalid runtime argument")); | |
450 | break; | |
451 | case 'P': | |
452 | ctl->period = strtou64_or_err(optarg, _("invalid period argument")); | |
453 | break; | |
454 | case 'D': | |
455 | ctl->deadline = strtou64_or_err(optarg, _("invalid deadline argument")); | |
456 | break; | |
48d7b13a | 457 | case 'V': |
f6277500 | 458 | printf(UTIL_LINUX_VERSION); |
110d680a | 459 | return EXIT_SUCCESS; |
48d7b13a | 460 | case 'h': |
bd9d9f05 | 461 | ret = EXIT_SUCCESS; |
337b8ead | 462 | /* fallthrough */ |
48d7b13a | 463 | default: |
bd9d9f05 | 464 | show_usage(ret); |
48d7b13a | 465 | } |
48d7b13a KZ |
466 | } |
467 | ||
7a4ea566 KZ |
468 | if (((ctl->pid > -1) && argc - optind < 1) || |
469 | ((ctl->pid == -1) && argc - optind < 2)) | |
bd9d9f05 | 470 | show_usage(EXIT_FAILURE); |
48d7b13a | 471 | |
7a4ea566 | 472 | if ((ctl->pid > -1) && (ctl->verbose || argc - optind == 1)) { |
a30cf650 | 473 | show_sched_info(ctl); |
48d7b13a | 474 | if (argc - optind == 1) |
bd9d9f05 | 475 | return EXIT_SUCCESS; |
48d7b13a KZ |
476 | } |
477 | ||
478 | errno = 0; | |
7a4ea566 | 479 | ctl->priority = strtos32_or_err(argv[optind], _("invalid priority argument")); |
48d7b13a | 480 | |
4951f9b3 | 481 | #ifdef SCHED_RESET_ON_FORK |
1a7e6395 KZ |
482 | if (ctl->reset_on_fork && ctl->policy != SCHED_FIFO && ctl->policy != SCHED_RR) |
483 | errx(EXIT_FAILURE, _("--reset-on-fork option is supported for " | |
484 | "SCHED_FIFO and SCHED_RR policies only")); | |
485 | #endif | |
486 | #ifdef SCHED_DEADLINE | |
487 | if ((ctl->runtime || ctl->deadline || ctl->period) && ctl->policy != SCHED_DEADLINE) | |
488 | errx(EXIT_FAILURE, _("--sched-{runtime,deadline,period} options " | |
489 | "are supported for SCHED_DEADLINE only")); | |
490 | if (ctl->policy == SCHED_DEADLINE) { | |
491 | /* The basic rule is runtime <= deadline <= period, so we can | |
492 | * make deadline and runtime optional on command line. Note we | |
493 | * don't check any values or set any defaults, it's kernel | |
494 | * responsibility. | |
495 | */ | |
496 | if (ctl->deadline == 0) | |
497 | ctl->deadline = ctl->period; | |
498 | if (ctl->runtime == 0) | |
499 | ctl->runtime = ctl->deadline; | |
500 | } | |
501 | #else | |
502 | if (ctl->runtime || ctl->deadline || ctl->period) | |
503 | errx(EXIT_FAILURE, _("SCHED_DEADLINE is unsupported")); | |
4951f9b3 | 504 | #endif |
7a4ea566 KZ |
505 | if (ctl->pid == -1) |
506 | ctl->pid = 0; | |
2e31d1c3 SK |
507 | if (ctl->priority < sched_get_priority_min(ctl->policy) || |
508 | sched_get_priority_max(ctl->policy) < ctl->priority) | |
509 | errx(EXIT_FAILURE, | |
510 | _("unsupported priority value for the policy: %d: see --max for valid range"), | |
511 | ctl->priority); | |
4820a737 | 512 | set_sched(ctl); |
a30cf650 | 513 | |
7a4ea566 | 514 | if (ctl->verbose) |
a30cf650 | 515 | show_sched_info(ctl); |
48d7b13a | 516 | |
7a4ea566 | 517 | if (!ctl->pid) { |
48d7b13a KZ |
518 | argv += optind + 1; |
519 | execvp(argv[0], argv); | |
bd9d9f05 | 520 | err(EXIT_FAILURE, _("failed to execute %s"), argv[0]); |
48d7b13a KZ |
521 | } |
522 | ||
bd9d9f05 | 523 | return EXIT_SUCCESS; |
48d7b13a | 524 | } |