Upload Tizen:Base source
[framework/base/util-linux-ng.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/ptrace.h>
15 #include <sys/syscall.h>
16 #include <asm/unistd.h>
17 #include <err.h>
18
19 #include "nls.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         "  ionoce [ 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 static long getnum(const char *str)
95 {
96         long num;
97         char *end = NULL;
98
99         if (str == NULL || *str == '\0')
100                 goto err;
101         errno = 0;
102         num = strtol(str, &end, 10);
103
104         if (errno || (end && *end))
105                 goto err;
106
107         return num;
108 err:
109         if (errno)
110                 err(EXIT_SUCCESS, _("cannot parse number '%s'"), str);
111         else
112                 errx(EXIT_SUCCESS, _("cannot parse number '%s'"), str);
113         return 0;
114 }
115
116 int main(int argc, char *argv[])
117 {
118         int ioprio = 4, set = 0, ioclass = IOPRIO_CLASS_BE, c;
119         pid_t pid = 0;
120
121         setlocale(LC_ALL, "");
122         bindtextdomain(PACKAGE, LOCALEDIR);
123         textdomain(PACKAGE);
124
125         while ((c = getopt(argc, argv, "+n:c:p:th")) != EOF) {
126                 switch (c) {
127                 case 'n':
128                         ioprio = getnum(optarg);
129                         set |= 1;
130                         break;
131                 case 'c':
132                         ioclass = getnum(optarg);
133                         set |= 2;
134                         break;
135                 case 'p':
136                         pid = getnum(optarg);
137                         break;
138                 case 't':
139                         tolerant = 1;
140                         break;
141                 case 'h':
142                         usage(EXIT_SUCCESS);
143                 default:
144                         usage(EXIT_FAILURE);
145                 }
146         }
147
148         switch (ioclass) {
149                 case IOPRIO_CLASS_NONE:
150                         if (set & 1)
151                                 warnx(_("ignoring given class data for none class"));
152                         ioprio = 0;
153                         break;
154                 case IOPRIO_CLASS_RT:
155                 case IOPRIO_CLASS_BE:
156                         break;
157                 case IOPRIO_CLASS_IDLE:
158                         if (set & 1)
159                                 warnx(_("ignoring given class data for idle class"));
160                         ioprio = 7;
161                         break;
162                 default:
163                         errx(EXIT_FAILURE, _("bad prio class %d"), ioclass);
164         }
165
166         if (!set) {
167                 ioprio_print(pid);
168
169                 for(; argv[optind]; ++optind) {
170                         pid = getnum(argv[optind]);
171                         ioprio_print(pid);
172                 }
173         } else {
174                 if (pid) {
175                         ioprio_setpid(pid, ioprio, ioclass);
176
177                         for(; argv[optind]; ++optind)
178                         {
179                                 pid = getnum(argv[optind]);
180                                 ioprio_setpid(pid, ioprio, ioclass);
181                         }
182                 }
183                 else if (argv[optind]) {
184                         ioprio_setpid(0, ioprio, ioclass);
185                         execvp(argv[optind], &argv[optind]);
186                         /* execvp should never return */
187                         err(EXIT_FAILURE, _("execvp failed"));
188                 }
189         }
190
191         exit(EXIT_SUCCESS);
192 }