Upload Tizen:Base source
[framework/base/util-linux-ng.git] / disk-utils / elvtune.c
1 /*
2  *  elvtune.c - I/O elevator tuner
3  *
4  *  Copyright (C) 2000 Andrea Arcangeli <andrea@suse.de> SuSE
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
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  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  *  This file may be redistributed under the terms of the GNU General
20  *  Public License, version 2.
21  */
22
23 #include <fcntl.h>
24 #include <errno.h>
25 #include <stdio.h>
26 #include <getopt.h>
27 #include <unistd.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <sys/ioctl.h>
31 #include <sys/utsname.h>
32 #include "nls.h"
33 #include "blkdev.h"
34 #include "linux_version.h"
35
36 /* this has to match with the kernel structure */
37 /* current version for ac19 and 2.2.16 */
38 typedef struct blkelv_ioctl_arg_s {
39         int queue_ID;
40         int read_latency;
41         int write_latency;
42         int max_bomb_segments;
43 } blkelv_ioctl_arg_t;
44
45 static void
46 usage(void) {
47         fprintf(stderr, "elvtune (%s)\n", PACKAGE_STRING);
48         fprintf(stderr, _("usage:\n"));
49         fprintf(stderr, "\telvtune [-r r_lat] [-w w_lat] [-b b_lat]"
50                         " /dev/blkdev1 [/dev/blkdev2...]\n");
51         fprintf(stderr, "\telvtune -h\n");
52         fprintf(stderr, "\telvtune -v\n");
53         fprintf(stderr, _("\tNOTE: elvtune only works with 2.4 kernels\n"));
54         /* (ioctls exist in 2.2.16 - 2.5.57) */
55 }
56
57 static void
58 version(void) {
59         fprintf(stderr, "elvtune (%s)\n", PACKAGE_STRING);
60 }
61
62 int
63 main(int argc, char * argv[]) {
64         int read_value = 0xbeefbeef, write_value = 0xbeefbeef, bomb_value = 0xbeefbeef;
65         int read_set, write_set, bomb_set, set;
66         char * devname;
67         int fd;
68         blkelv_ioctl_arg_t elevator;
69
70         read_set = write_set = bomb_set = set = 0;
71
72         setlocale(LC_MESSAGES, "");
73         bindtextdomain(PACKAGE, LOCALEDIR);
74         textdomain(PACKAGE);
75
76         for (;;) {
77                 int opt;
78
79                 opt = getopt(argc, argv, "r:w:b:hv");
80                 if (opt == -1)
81                         break;
82                 switch (opt) {
83                 case 'r':
84                         read_value = atoi(optarg);
85                         read_set = set = 1;
86                         break;
87                 case 'w':
88                         write_value = atoi(optarg);
89                         write_set = set = 1;
90                         break;
91                 case 'b':
92                         bomb_value = atoi(optarg);
93                         bomb_set = set = 1;
94                         break;
95
96                 case 'h':
97                         usage(), exit(0);
98                 case 'v':
99                         version(), exit(0);
100
101                 case '?':
102                 default:
103                 case ':':
104                         fprintf(stderr, _("parse error\n"));
105                         exit(1);
106                 }
107         }
108
109         if (optind >= argc)
110                 fprintf(stderr, _("missing blockdevice, use -h for help\n")), exit(1);
111
112         while (optind < argc) {
113                 devname = argv[optind++];
114
115                 fd = open(devname, O_RDONLY|O_NONBLOCK);
116                 if (fd < 0) {
117                         perror("open");
118                         break;
119                 }
120
121                 /* mmj: If we get EINVAL it's not a 2.4 kernel, so warn about
122                    that and exit. It should return ENOTTY however, so check for
123                    that as well in case it gets corrected in the future */
124
125                 if (ioctl(fd, BLKELVGET, &elevator) < 0) {
126                         int errsv = errno;
127                         perror("ioctl get");
128                         if ((errsv == EINVAL || errsv == ENOTTY) &&
129                             get_linux_version() >= KERNEL_VERSION(2,5,58)) {
130                                 fprintf(stderr,
131                                         _("\nelvtune is only useful on older "
132                                         "kernels;\nfor 2.6 use IO scheduler "
133                                         "sysfs tunables instead..\n"));
134                         }
135                         break;
136                 }
137
138                 if (set) {
139                         if (read_set)
140                                 elevator.read_latency = read_value;
141                         if (write_set)
142                                 elevator.write_latency = write_value;
143                         if (bomb_set)
144                                 elevator.max_bomb_segments = bomb_value;
145
146                         if (ioctl(fd, BLKELVSET, &elevator) < 0) {
147                                 perror("ioctl set");
148                                 break;
149                         }
150                         if (ioctl(fd, BLKELVGET, &elevator) < 0) {
151                                 perror("ioctl reget");
152                                 break;
153                         }
154                 }
155
156                 printf("\n%s elevator ID\t\t%d\n", devname, elevator.queue_ID);
157                 printf("\tread_latency:\t\t%d\n", elevator.read_latency);
158                 printf("\twrite_latency:\t\t%d\n", elevator.write_latency);
159                 printf("\tmax_bomb_segments:\t%d\n\n", elevator.max_bomb_segments);
160
161                 if (close(fd) < 0) {
162                         perror("close");
163                         break;
164                 }
165         }
166
167         return 0;
168 }