Controlling which services to auto-run under each runlevel


A typical linux computer has installed on it some set of "services." These are programs that can potentially be launched automatically when the machine is turned on, as part of its boot process. A runlevel is a choice, from among these installed services, of some particular subset actually to be launched.

The set of installed services is represented in /etc/rc.d/init.d, which houses a script (i.e., batch file) for each of them. There's a one-to-one correspondence between the services and the scripts-- each service has its script and each script has a service. The script for a given service contains a conditional branch (that is, an if/else statement) to either run the binary for that service if it isn't running ("start" it), or shut it down if it is ("kill" it). The scripts for almost all services follow this same structural pattern. The purpose of doing things this way is to centralize the startup scripts in one place. Note that the locations of the actual binaries for the service programs can be scattered around different parts of the hierarchical filesystem tree. However, scripts to call them can all be found concentrated in /etc/rc.d/init.d. Here are the scripts, from a RedHat Enterprise Linux 3.0 system on which "Everything" was installed:

A runlevel expresses a subset of these. It does so in a subdirectory. Each runlevel has a subdirectory of its own for the purpose. For example, runlevel 2 uses /etc/rc.d/rc2.d, while runlevel 3 uses /etc/rc.d/rc3.d. These subdirectories are full of symbolic links ("shortcuts") pointing to the startup scripts shown above. Whether, for a given runlevel, the script for a particular service will be used to start it or kill it can be discerned by whether the name of that service's symbolic link begins with "S" or "K."

Consider kudzu as an example of a service. Below is the subdirectory for runlevel 2 that expresses how it treats each service. As for kudzu, on entry into runlevel 2 kudzu will be killed because runlevel 2's symbolic link ("K95kudzu") to kudzu's startup script (/etc/rc.d/init.d/kudzu) begins with the letter K.

Runlevel 3 by contrast does the opposite. Below is the subdirectory that determines how that runlevel treats each service.  And for kudzu you can see that on entry into runlevel 3 kudzu will be started because runlevel 3's symbolic link ("S05kudzu") to kudzu's startup script (/etc/rc.d/init.d/kudzu) begins with the letter S.

 

The in-class exercise:

Manipulate one of the per-runlevel symbolic links that select which services to run and which to kill when entering a runlevel.

Go to the directory that defines what services to run for runlevel 5. There, find out about kudzu-- examine whether it is to be killed or started when entering runlevel 5. There are at least 2 ways to examine it. Most directly, check whether the symbolic link to its startup script (which is /etc/rc.d/init.d/kudzu) begins with letter K or S. Alternatively, there's a useful utility for doing this called chkconfig.

Once you know how kudzu is set, please set it the opposite way. If it's set to be started, set it to be killed instead; if it's set to be killed, set it to be started instead. Again, you can do this directly by deleting the existing symbolic link and creating a new one. Or you can use chkconfig.

After you've reversed it, examine it as you did earlier to verify your change was effective and as you intended. Then finally leave it, or set it, so that it remains off (K as opposed to S) in runlevel 5; and do the same in runlevel 3, so that kudzu won't run on boot into either runlevel.


Here might be the commands you actually use to do the above, assuming that the symbolic link for kudzu for runlevel 5 on your system is K05kudzu.

# go to the directory for runlevel 5
cd /etc/rc.d/rc5.d

ls | grep kudzu # direct examination of the symbolic link
chkconfig --list | grep kudzu # indirect, by a utility for the purpose

# change it so kudzu's to be started instead of killed 
rm K05kudzu
ln -s ../init.d/kudzu S05kudzu

ls | grep kudzu
chkconfig --list | grep kudzu

# change it back to its original state
rm S05kudzu
ln -s ../init.d/kudzu K05kudzu
(or instead of the above pair of lines, chkconfig --level 5 kudzu off)