diff options
author | Igor Pashev <pashev.igor@gmail.com> | 2012-11-02 20:15:39 +0400 |
---|---|---|
committer | Igor Pashev <pashev.igor@gmail.com> | 2012-11-02 20:15:39 +0400 |
commit | b13154de3eca5ba28fbb4854d916cd0be5febeed (patch) | |
tree | 30f2e9e89ab71a2df837076ac68c3ba770230294 /disk-utils/elvtune.c | |
download | util-linux-upstream.tar.gz |
Imported Upstream version 2.22upstream/2.22upstream
Diffstat (limited to 'disk-utils/elvtune.c')
-rw-r--r-- | disk-utils/elvtune.c | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/disk-utils/elvtune.c b/disk-utils/elvtune.c new file mode 100644 index 0000000..9f7fbf3 --- /dev/null +++ b/disk-utils/elvtune.c @@ -0,0 +1,174 @@ +/* + * elvtune.c - I/O elevator tuner + * + * Copyright (C) 2000 Andrea Arcangeli <andrea@suse.de> SuSE + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* + * This command is deprecated. The utility is in maintenance mode, + * meaning we keep them in source tree for backward compatibility + * only. Do not waste time making this command better, unless the + * fix is about security or other very critical issue. + * + * See Documentation/deprecated.txt for more information. + */ + +#include <fcntl.h> +#include <errno.h> +#include <stdio.h> +#include <getopt.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include <sys/ioctl.h> +#include <sys/utsname.h> +#include "nls.h" +#include "blkdev.h" +#include "closestream.h" +#include "linux_version.h" + +/* this has to match with the kernel structure */ +/* current version for ac19 and 2.2.16 */ +typedef struct blkelv_ioctl_arg_s { + int queue_ID; + int read_latency; + int write_latency; + int max_bomb_segments; +} blkelv_ioctl_arg_t; + +static void +usage(void) { + fprintf(stderr, "elvtune (%s)\n", PACKAGE_STRING); + fprintf(stderr, _("usage:\n")); + fprintf(stderr, "\telvtune [-r r_lat] [-w w_lat] [-b b_lat]" + " /dev/blkdev1 [/dev/blkdev2...]\n"); + fprintf(stderr, "\telvtune -h\n"); + fprintf(stderr, "\telvtune -v\n"); + fprintf(stderr, _("\tNOTE: elvtune only works with 2.4 kernels\n")); + /* (ioctls exist in 2.2.16 - 2.5.57) */ +} + +static void +version(void) { + fprintf(stderr, "elvtune (%s)\n", PACKAGE_STRING); +} + +int +main(int argc, char * argv[]) { + int read_value = 0xbeefbeef, write_value = 0xbeefbeef, bomb_value = 0xbeefbeef; + int read_set, write_set, bomb_set, set; + char * devname; + int fd; + blkelv_ioctl_arg_t elevator; + + read_set = write_set = bomb_set = set = 0; + + setlocale(LC_MESSAGES, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + atexit(close_stdout); + + for (;;) { + int opt; + + opt = getopt(argc, argv, "r:w:b:hv"); + if (opt == -1) + break; + switch (opt) { + case 'r': + read_value = atoi(optarg); + read_set = set = 1; + break; + case 'w': + write_value = atoi(optarg); + write_set = set = 1; + break; + case 'b': + bomb_value = atoi(optarg); + bomb_set = set = 1; + break; + + case 'h': + usage(), exit(0); + case 'v': + version(), exit(0); + + default: + usage(), exit(1); + } + } + + if (optind >= argc) + fprintf(stderr, _("missing blockdevice, use -h for help\n")), exit(1); + + while (optind < argc) { + devname = argv[optind++]; + + fd = open(devname, O_RDONLY|O_NONBLOCK); + if (fd < 0) { + perror("open"); + break; + } + + /* mmj: If we get EINVAL it's not a 2.4 kernel, so warn about + that and exit. It should return ENOTTY however, so check for + that as well in case it gets corrected in the future */ + + if (ioctl(fd, BLKELVGET, &elevator) < 0) { + int errsv = errno; + perror("ioctl get"); + if ((errsv == EINVAL || errsv == ENOTTY) && + get_linux_version() >= KERNEL_VERSION(2,5,58)) { + fprintf(stderr, + _("\nelvtune is only useful on older " + "kernels;\nfor 2.6 use IO scheduler " + "sysfs tunables instead..\n")); + } + break; + } + + if (set) { + if (read_set) + elevator.read_latency = read_value; + if (write_set) + elevator.write_latency = write_value; + if (bomb_set) + elevator.max_bomb_segments = bomb_value; + + if (ioctl(fd, BLKELVSET, &elevator) < 0) { + perror("ioctl set"); + break; + } + if (ioctl(fd, BLKELVGET, &elevator) < 0) { + perror("ioctl reget"); + break; + } + } + + printf("\n%s elevator ID\t\t%d\n", devname, elevator.queue_ID); + printf("\tread_latency:\t\t%d\n", elevator.read_latency); + printf("\twrite_latency:\t\t%d\n", elevator.write_latency); + printf("\tmax_bomb_segments:\t%d\n\n", elevator.max_bomb_segments); + + if (close(fd) < 0) { + perror("close"); + break; + } + } + + return 0; +} |