diff options
-rw-r--r-- | include/applets.h | 1 | ||||
-rw-r--r-- | include/usage.h | 10 | ||||
-rw-r--r-- | miscutils/Config.in | 7 | ||||
-rw-r--r-- | miscutils/Kbuild | 1 | ||||
-rw-r--r-- | miscutils/ionice.c | 99 |
5 files changed, 117 insertions, 1 deletions
diff --git a/include/applets.h b/include/applets.h index 63cc738..af21a0d 100644 --- a/include/applets.h +++ b/include/applets.h @@ -193,6 +193,7 @@ USE_INOTIFYD(APPLET(inotifyd, _BB_DIR_SBIN, _BB_SUID_NEVER)) USE_INSMOD(APPLET(insmod, _BB_DIR_SBIN, _BB_SUID_NEVER)) USE_MODPROBE_SMALL(APPLET_ODDNAME(insmod, modprobe, _BB_DIR_SBIN, _BB_SUID_NEVER, modprobe)) USE_INSTALL(APPLET(install, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +USE_IONICE(APPLET(ionice, _BB_DIR_BIN, _BB_SUID_NEVER)) #if ENABLE_FEATURE_IP_ADDRESS \ || ENABLE_FEATURE_IP_ROUTE \ || ENABLE_FEATURE_IP_LINK \ diff --git a/include/usage.h b/include/usage.h index 9ceb366..cfe12c6 100644 --- a/include/usage.h +++ b/include/usage.h @@ -1932,7 +1932,7 @@ /* -v, -b, -c are ignored */ #define install_trivial_usage \ - "[-cdDsp] [-o USER] [-g GRP] [-m MODE] [source] dest|directory" + "[-cdDsp] [-o USER] [-g GRP] [-m MODE] [source] dest|directory" #define install_full_usage "\n\n" \ "Copy files and set attributes\n" \ "\nOptions:" \ @@ -1948,6 +1948,14 @@ "\n -Z Set security context" \ ) +#define ionice_trivial_usage \ + "[-c 1-3] [-n 0-7] [-p PID] [PROG]" +#define ionice_full_usage "\n\n" \ + "Change I/O scheduling class and priority\n" \ + "\nOptions:" \ + "\n -c Class. 1:realtime 2:best-effort 3:idle" \ + "\n -n Priority" \ + /* would need to make the " | " optional depending on more than one selected: */ #define ip_trivial_usage \ "[OPTIONS] {" \ diff --git a/miscutils/Config.in b/miscutils/Config.in index 68732e6..94174de 100644 --- a/miscutils/Config.in +++ b/miscutils/Config.in @@ -238,6 +238,13 @@ config FBSPLASH "NN" (ASCII decimal number) - percentage to show on progress bar "exit" - well you guessed it +config IONICE + bool "ionice" + default n + help + Set/set program io scheduling class and priority + Requires kernel >= 2.6.13 + config INOTIFYD bool "inotifyd" default n diff --git a/miscutils/Kbuild b/miscutils/Kbuild index e6e4347..7665130 100644 --- a/miscutils/Kbuild +++ b/miscutils/Kbuild @@ -16,6 +16,7 @@ lib-$(CONFIG_DEVFSD) += devfsd.o lib-$(CONFIG_DEVMEM) += devmem.o lib-$(CONFIG_EJECT) += eject.o lib-$(CONFIG_FBSPLASH) += fbsplash.o +lib-$(CONFIG_IONICE) += ionice.o lib-$(CONFIG_HDPARM) += hdparm.o lib-$(CONFIG_INOTIFYD) += inotifyd.o lib-$(CONFIG_FEATURE_LAST_SMALL)+= last.o diff --git a/miscutils/ionice.c b/miscutils/ionice.c new file mode 100644 index 0000000..88d771c --- /dev/null +++ b/miscutils/ionice.c @@ -0,0 +1,99 @@ +/* vi: set sw=4 ts=4: */ +/* + * ionice implementation for busybox based on linux-utils-ng 2.14 + * + * Copyright (C) 2008 by <u173034@informatik.uni-oldenburg.de> + * + * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. + */ + +#include <sys/syscall.h> +#include <asm/unistd.h> +#include "libbb.h" + +static int ioprio_set(int which, int who, int ioprio) +{ + return syscall(SYS_ioprio_set, which, who, ioprio); +} + +static int ioprio_get(int which, int who) +{ + return syscall(SYS_ioprio_get, which, who); +} + +enum { + IOPRIO_WHO_PROCESS = 1, + IOPRIO_WHO_PGRP, + IOPRIO_WHO_USER +}; + +enum { + IOPRIO_CLASS_NONE, + IOPRIO_CLASS_RT, + IOPRIO_CLASS_BE, + IOPRIO_CLASS_IDLE +}; + +static const char to_prio[] = "none\0realtime\0best-effort\0idle"; + +#define IOPRIO_CLASS_SHIFT 13 + +int ionice_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int ionice_main(int argc UNUSED_PARAM, char **argv) +{ + /* Defaults */ + int ioclass = 0; + int pri = 0; + int pid = 0; /* affect own porcess */ + int opt; + enum { + OPT_n = 1, + OPT_c = 2, + OPT_p = 4, + }; + + /* Numeric params */ + opt_complementary = "n+:c+:p+"; + /* '+': stop at first non-option */ + opt = getopt32(argv, "+n:c:p:", &pri, &ioclass, &pid); + argv += optind; + + if (opt & OPT_c) { + if (ioclass > 3) + bb_error_msg_and_die("bad class %d", ioclass); +// Do we need this (compat?)? +// if (ioclass == IOPRIO_CLASS_NONE) +// ioclass = IOPRIO_CLASS_BE; +// if (ioclass == IOPRIO_CLASS_IDLE) { +// //if (opt & OPT_n) +// // bb_error_msg("ignoring priority for idle class"); +// pri = 7; +// } + } + + if (!(opt & (OPT_n|OPT_c))) { + if (!(opt & OPT_p) && *argv) + pid = xatoi_u(*argv); + + pri = ioprio_get(IOPRIO_WHO_PROCESS, pid); + if (pri == -1) + bb_perror_msg_and_die("ioprio_%cet", 'g'); + + ioclass = (pri >> IOPRIO_CLASS_SHIFT) & 0x3; + pri &= 0xff; + printf((ioclass == IOPRIO_CLASS_IDLE) ? "%s\n" : "%s: prio %d\n", + nth_string(to_prio, ioclass), pri); + } else { +//printf("pri=%d class=%d val=%x\n", +//pri, ioclass, pri | (ioclass << IOPRIO_CLASS_SHIFT)); + pri |= (ioclass << IOPRIO_CLASS_SHIFT); + if (ioprio_set(IOPRIO_WHO_PROCESS, pid, pri) == -1) + bb_perror_msg_and_die("ioprio_%cet", 's'); + if (*argv) { + BB_EXECVP(*argv, argv); + bb_simple_perror_msg_and_die(*argv); + } + } + + return EXIT_SUCCESS; +} |