Thursday, June 12, 2008

Using chkconfig To Manage Linux Service Run Levels

Hey there,

If you're like me, you've probably gotten used to creating init scripts and all the various linking to run level directories that needs to be done so that certain services will start and stop at the run levels you decide you want them to.

Even so, I'm always impressed with ways to make this sort of setup easier. Especially when it comes to manipulation of start and stop (init) scripts that come with system software. Solaris' mish-mosh of hard and soft linked run level scripts can be a headache, for sure, but Redhat, Fedora and other Linux flavours can be a bit of a pain, as well. The main problem I run into is making a customized change that ends up getting overwritten by an RPM upgrade or things of that nature.

Thankfully, that issue has been addressed, more than adequately, in a few ways. One of my favorites is the chkconfig command (usually located in the /sbin directory). This tool makes it very easy for an administrator to control at what run levels virtually every system-controlled service starts and stops.

Today, we're going to look at a few common ways to use chkconfig to make administration of run levels more convenient.

The first way is the most obvious. If you want to know everything that's going on with every service that's being controlled, simply type:

host # /sbin/chkconfig --list

and you'll get output similar to this:

acpid 0:off 1:off 2:off 3:off 4:on 5:on 6:off
anacron 0:off 1:off 2:on 3:on 4:on 5:on 6:off
...


An easy way to find out what services are "on" is to just pipe the above command to grep. If you want to know what's running "now" (or, at least, what should be ;), you can find your run level with the who command and then use chkconfig to find all the active services:

host # who -r
run-level 3...
host # chkconfig --list|grep "3:on"


or, if you're only interested in one service, you can specify it and chkconfig will query its state at your current run level, like so:

host # chkconfig anacron

More specifically (since that would only show you services that get started at run level 3, you could do this:

host # chkconfig --list|egrep '[123]:on'

and you should see all the services that are running currently (assuming your machine boots normally, through run levels 1 and 2, before getting to 3).

You can also use chkconfig to configure any listed service to start and/or stop at any run level you choose. You can even do multiple run levels at once. So, all of the following commands would be valid (assuming you have the service "anacron" on your machine):

host # chkconfig anacron on
host # chkconfig anacron off
host # chkconfig --level 3 anacron on
host # chkconfig --level 3 anacron off
host # chkconfig --level 235 anacron on
host # chkconfig --level 046 anacron off


Also note that on some systems, on and off only apply to run levels 2, 3, 4 and 5. Setting other levels may not work, but should not cause failure.

An alternative to on or off, is to use reset. This keyword will reset the service to start and stop at the run levels it defaults to (look near the bottom of this post to see from where chkconfig gets that information).

host # chkconfig anacron reset

Some simple scripting can make it so that you can replicate this behaviour for multiple services. At this point, to my knowledge, you can only either make changes globally or per-service. In any event, something like this is simple enough to work out at the command line (after checking out all of the services with --list, put the ones you want to start at runlevels 3 and 5 , and be turned off at all other levels, into a text file, one service per line). Note, that this is just my little command line script, and can be done a lot of different ways, so you should do this however makes the most sense for you:

host # for x in `cat MYSERVICES`;do /sbin/chkconfig --level 35 $x on;/sbin/chkconfig --level 01246 off;done

And the final (and most helpful, since it keeps you from having to remember how to format an init script to work with chkconfig) thing chkconfig does, is allow you to add and delete services. If your service isn't standard, you may still have to write your own init script, but for all packaged (and handled) services, this is a snap.

To remove a service that's currently active, just type:

host # chkconfig --del anacron

And to reinstate it, just type

host # chkconfig --add anacron

And, bingo, you're all set :) Note that the above add/del function really only creates and destroys symlinks from the init directory to the run level directories, so if you've deleted the actual init script, using chkconfig to re-add the service probably won't work. If you still have access to the RPM for that package, you can fix it to replace any missing files that way first.

If you do decide to create your own init script, and want it to be controlled by chkconfig, just make sure that you have these lines near the top of the script, in the comment section, below the shebang line and above any other comments in the script, like this:

#!/bin/sh

#
# chkconfig: 235 10 60


This part of the init script is what chkconfig looks for, and, in this instance, it tells chkconfig that the service should start at run levels 2, 3 and 5, it should be turned off for all other run levels (chkconfig's default assumption) and that it should have a start priority of 10 and a stop priority of 60. The priority numbers that you include in your script are relative and shouldn't generally be an issue. The defaults are usually 20 and 80. You can also add a "#description:" line (directly after the required chkconfig line) to your script if you want to be able to see that in chkconfig output, but it's not necessary.

Here's hoping this helps your run level management step up and get easier, all at the same time! :)

Cheers,

, Mike