Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
HOWTO: Initscript to Dynamically Manage I/O Schedulers
View unanswered posts
View posts from last 24 hours

 
Reply to topic    Gentoo Forums Forum Index Documentation, Tips & Tricks
View previous topic :: View next topic  
Author Message
Bones McCracker
Veteran
Veteran


Joined: 14 Mar 2006
Posts: 1611
Location: U.S.A.

PostPosted: Wed Jul 18, 2007 4:29 pm    Post subject: HOWTO: Initscript to Dynamically Manage I/O Schedulers Reply with quote

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. :D

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
View user's profile Send private message
IQgryn
l33t
l33t


Joined: 05 Sep 2005
Posts: 764
Location: WI, USA

PostPosted: Tue Nov 27, 2007 6:02 pm    Post subject: Reply with quote

It looks pretty good, but I think (after reading http://gentoo-wiki.com/TIP_Vary_Configuration_Files_Based_on_Softlevel) that you can simply have one file in /etc/init.d (iosched) and two files in /etc/conf.d (iosched.desktop and iosched.server). You shouldn't have to create any symlinks.

Also, you can use rc to switch softlevels on the fly: see http://gentoo-wiki.com/HOWTO_create_a_run_level#After_boot.
Back to top
View user's profile Send private message
Bones McCracker
Veteran
Veteran


Joined: 14 Mar 2006
Posts: 1611
Location: U.S.A.

PostPosted: Wed Nov 28, 2007 12:57 am    Post subject: Reply with quote

IQgryn wrote:
It looks pretty good, but I think (after reading http://gentoo-wiki.com/TIP_Vary_Configuration_Files_Based_on_Softlevel) that you can simply have one file in /etc/init.d (iosched) and two files in /etc/conf.d (iosched.desktop and iosched.server). You shouldn't have to create any symlinks.


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
View user's profile Send private message
likewhoa
l33t
l33t


Joined: 04 Oct 2006
Posts: 778
Location: Brooklyn, New York

PostPosted: Thu Nov 29, 2007 1:14 am    Post subject: Reply with quote

thanks for the great init script.
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index Documentation, Tips & Tricks All times are GMT
Page 1 of 1

 
Jump to:  
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