2 * elvtune.c - I/O elevator tuner
4 * Copyright (C) 2000 Andrea Arcangeli <andrea@suse.de> SuSE
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.
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.
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.
30 #include <sys/ioctl.h>
31 #include <sys/utsname.h>
34 #include "linux_version.h"
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 {
42 int max_bomb_segments;
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) */
59 fprintf(stderr, "elvtune (%s)\n", PACKAGE_STRING);
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;
68 blkelv_ioctl_arg_t elevator;
70 read_set = write_set = bomb_set = set = 0;
72 setlocale(LC_MESSAGES, "");
73 bindtextdomain(PACKAGE, LOCALEDIR);
79 opt = getopt(argc, argv, "r:w:b:hv");
84 read_value = atoi(optarg);
88 write_value = atoi(optarg);
92 bomb_value = atoi(optarg);
104 fprintf(stderr, _("parse error\n"));
110 fprintf(stderr, _("missing blockdevice, use -h for help\n")), exit(1);
112 while (optind < argc) {
113 devname = argv[optind++];
115 fd = open(devname, O_RDONLY|O_NONBLOCK);
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 */
125 if (ioctl(fd, BLKELVGET, &elevator) < 0) {
128 if ((errsv == EINVAL || errsv == ENOTTY) &&
129 get_linux_version() >= KERNEL_VERSION(2,5,58)) {
131 _("\nelvtune is only useful on older "
132 "kernels;\nfor 2.6 use IO scheduler "
133 "sysfs tunables instead..\n"));
140 elevator.read_latency = read_value;
142 elevator.write_latency = write_value;
144 elevator.max_bomb_segments = bomb_value;
146 if (ioctl(fd, BLKELVSET, &elevator) < 0) {
150 if (ioctl(fd, BLKELVGET, &elevator) < 0) {
151 perror("ioctl reget");
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);