View previous topic :: View next topic |
Author |
Message |
Bones McCracker Veteran
Joined: 14 Mar 2006 Posts: 1611 Location: U.S.A.
|
Posted: Wed Jul 18, 2007 4:29 pm Post subject: HOWTO: Initscript to Dynamically Manage I/O Schedulers |
|
|
Purpose: (A tiny initscript to facilitate effective use of multiple I/O schedulers, without use of additional daemons or overhead).
a) Automatically set kernel I/O schedulers for individual devices (e.g. CFQ for sda, deadline for sdb, noop for hda).
b) Automatically apply different settings for different runlevels (e.g. different settings for each device in "default" vs "graphical" runlevels). It will do this for you if you selectively boot into various runlevels, and it will also do it if you switch back and forth between runlevels "on the fly" (i.e. "init 5").
(E.g.: "default" runlevel: anticipatory for sda and deadline for sdb; but in "qraphical" runlevel: SD for sda and CFS for sdb (or whatever)).
Disclaimer: This HOWTO assumes an understanding of (and makes no attempt to explain) the Gentoo init system, the nature of various kernel I/O schedulers, use of kernel modules, and use of multiple user-defined runlevels.
Step 1.
Create the initscript
Create /etc/init.d/iosched using the code below. Code: | #!/sbin/runscript
# /etc/init.d/iosched
# Rev. 17 July 2007
# Purpose: dynamically switch I/O Scheduler according to runlevel
# For each runlevel in which this script is to be run:
# - Create a uniquely-named symlink to this file in /etc/init.d
# - Create a configuration file with the same filename in /etc/conf.d
# E.g:
# Symlink: /etc/init.d/iosched.desktop
# Configuration: /etc/conf.d/iosched.desktop
# Symlink: /etc/init.d/iosched.server
# Configuration: /etc/conf.d/iosched.server
depend() {
need localmount
need modules
}
start() {
ebegin "Checking appropriateness of I/O Scheduler"
INDEX=0
RUNLEVEL=`/sbin/runlevel | awk '{print $2}'` #TODO Supposedly, init provides $RUNLEVEL visible to init
#+ children, but in testing it wasn't visible.
for DEV in ${io_devices[*]}; do
CTLFILE=/sys/block/$DEV/queue/scheduler
if [ -w $CTLFILE ]; then
OLD=`/bin/cat $CTLFILE | grep -o "\[.*\]" | tr -d "\[\]"`
NEW=${schedulers[$INDEX]}
if [ $NEW != $OLD ]; then
echo "Changing I/O Scheduler for $DEV from $OLD to $NEW"
/bin/echo $NEW > $CTLFILE
eend $?
fi
else
eerror "iosched: Invalid Device: $DEV (check /etc/conf.d/iosched)"
fi
INDEX=$(($INDEX+1))
done
}
# vim:ts=4 | Ownership and permissions should be: -rwxr-x--- 1 root root
Step 2.
Create Runlevel-Unique Symlinks to the Initscript
Because the initscript will need to restart and use a different configuration for each runlevel it runs in, you now need to create soft symlinks to the initscript within the /etc/init.d directory - one for each runlevel you want to use the script in. You don't have to use this initscript in multiple runlevels, but that's a main part of it's purpose. For example, if you have a "server" runlevel and a "desktop" runlevel, you would:
Code: | ln -s /etc/init.d/iosched /etc/init.d/iosched.server
ln -s /etc/init.d/iosched /etc/init.d/iosched.desktop |
If you just want to use it to set the schedulers for your default runlevel (different schedulers for various devices), then you don't need to create a symlink.
Step 3.
Create Your Configuration Files
Use the code below to create configuration files in /etc/conf.d. These need to match the initscript symlinks (one for each, having the same names). For example, if you created symlinks /etc/init.d/iosched.server and /etc/init.d/iosched.desktop, then you need to now create the files /etc/conf.d/iosched.server and /etc/conf.iosched.desktop. The code below is a template that you must adapt to your system.
Code: | # /etc/conf.d/iosched.desktop
# John Brendler
# Rev. 17 July 2007
# This configuration is applied when you enter the "desktop" runlevel.
# Syntax: two valid bash array constructs.
io_devices=( sda sdb hda )
schedulers=( cfq anticipatory cfq ) |
(Valid devices: If there is a file /sys/block/<$device>/queue/scheduler, then you can include the device.)
For example, you might create the configuration file above for a "desktop", "graphical", or "dev-test" runlevel and then create a separate file (probably by copying this file and then modifying it) for your "server", "default", or "production" runlevel:
Code: | # /etc/conf.d/iosched.server
io_devices=( sda sdb hda )
schedulers=( anticipatory deadline anticipatory ) |
If you are just using the initscript to set the schedulers for one runlevel (e.g. default), then you just need one configuration file (named /etc/init.d/iosched).
Note that the syntax of the configuration must remain a valid bash array construct. Among other things, this means no spaces around the equal sign. (There are other ways of specifying arrays and those will work too.)
Optional: You can test at this point (for example, supposing I am already in my "desktop" runlevel): Code: | # /etc/init.d/iosched.desktop start
*Checking the appropriateness of I/O Schedulers..."
* Switching I/O Scheduler for device blah from foo to bar" # This line only shows up if a change is actually being made. |
Step 4.
Enable the Initscript
For each runlevel in which the initscript is to be run, enable the appropriate symlink. Continuing the examples above: Code: | #rc-update -a iosched.server server
#rc-update -a iosched.desktop desktop |
Or, if you are only using the script in one runlevel: Code: | rc-update -a iosched default |
You should now be able to switch back and forth between the various modes of operation you desire for your machine and have the appropriate I/O schedulers automatically engaged for you on each device.
Direction:
One idea I have for improvement is to extend it to manipulate the fine controls available in /sys/block/<$device>/queue/iosched, i.e.: Code: |
back_seek_max fifo_expire_async quantum slice_async_rq slice_sync
back_seek_penalty fifo_expire_sync slice_async slice_idle |
At the time of this writing, the CFS scheduler was just being merged into the latest kernel. Since I run a version marked 'stable' by Gentoo, I have not yet tested the method outlined above with the CFS scheduler (or the SD scheduler, which is NOT being merged but may remain available as part of the ck patch set), I assume these will be handled in the same fashion. So adapting the approach outlined above should be trivial - and I'd like to know if anyone does so.
Finally, I welcome all suggestions as to how to improve this (or even replace it with another means to achieve the same result).
Last edited by Bones McCracker on Sat Feb 09, 2008 1:51 pm; edited 1 time in total |
|
Back to top |
|
|
IQgryn l33t
Joined: 05 Sep 2005 Posts: 764 Location: WI, USA
|
|
Back to top |
|
|
Bones McCracker Veteran
Joined: 14 Mar 2006 Posts: 1611 Location: U.S.A.
|
Posted: Wed Nov 28, 2007 12:57 am Post subject: |
|
|
You're right that softlevels work that way, at least during boot. With a single initscript and multple service.runlevel configurations in /etc/conf.d, the appropriate configuration file is sourced.
However, I found it necessary to use two symlinks (in the style of net.eth0, net.eth1) to make it work when dynamically switching runlevels (after boot). Two differently-named symlinks (in /etc/init.d) cause the init system to re-run the initscript when the runlevel/softlevel changes. Without these, the init system sees the service as already "started" and does nothing -- it doesn't run the initscript again.
Maybe there's another way around this (I just lack the knowledge), by writing the initscript to somehow terminate itself after it switches the ioschedulers (i.e. setting service status to "stopped"). Or maybe the initscript can be flagged as requiring a restart when runlevels change. But I don't know how to do either and neither do other people I've asked.
https://forums.gentoo.org/viewtopic-t-570982.html
To select runlevel at boot time:
Using softlevel: add this to end of bootline -> softlevel=foobar
Standard way: add this to end of bootline -> 4
To switch runlevel on the fly:
Using softlevel: rc foobar
Standard way: init 4
Last edited by Bones McCracker on Sat Feb 09, 2008 1:59 pm; edited 4 times in total |
|
Back to top |
|
|
likewhoa l33t
Joined: 04 Oct 2006 Posts: 778 Location: Brooklyn, New York
|
Posted: Thu Nov 29, 2007 1:14 am Post subject: |
|
|
thanks for the great init script. |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|