Run Levels

What are run levels ?
Each of the run levels of Linux is a different "operating mode". This means that it has different settings, independent of any other run level, allowing it to run different tasks and applications as required. Each run level can be configured to perform different tasks using a configuration file in the /etc directory (discussed later). If you are familiar with Microsoft's Windows, it may be helpful to think of the run level system as being similar to the choice between "Safe Mode", "Safe Mode with Networking", "Command Prompt", etc, that you are presented with when the system has shutdown uncleanly - not that Linux needs to be shutdown uncleanly to change run level.

What does each run level do?
As was indicated, a runlevel is defined by the scripts executed in it, thus what a runlevel does is variable. Most frequently,


 * Run level 1 provides single-user mode
 * Run level 2 provides single-user mode with networking support
 * Run level 3 provides multi-user mode with a command-line interface, rather than a graphical window manager. This is convenient if you wish to work without the overhead of pretty anti-aliased windows
 * Run level 4 has not yet been defined
 * Run level 5 provides multi-user mode with a graphical window manager. This is the default run level that is booted on many distributions and the one that you are most likely to have for everyday use.
 * Run level 6 shuts down the system, closing necessary applications and daemon. For obvious reasons, this run level should not be used if you want to do anything productive.

However, these are the default runlevels in Slackware:
 * 0 = halt
 * 1 = single user mode
 * 2 = unused (but configured the same as runlevel 3)
 * 3 = multiuser mode (default Slackware runlevel)
 * 4 = X11 with KDM/GDM/XDM (session managers)
 * 5 = unused (but configured the same as runlevel 3)
 * 6 = reboot

Configuring each run level
Run levels are not configured so much as added to.

The run levels are configured in the /etc/inittab config file. This file tells init what is the default runlevel, and what to do when entering or leaving each runlevel. That usually consists of executing /etc/rc.d/rc x, where x is the runlevel.

This script, then, looks in a runlevel control directory (usually /etc/rc.d/rcX.d), where it will find a series of symbolic links with special names. The first letter of the name is S ("start") or K ("kill"). The next two characters are two digits -- used to control the order in which the files will be processed -- and the remainder of the name is the name of a particular service. (Note: what Microsoft calls a "service," Linux/Unix people call a "daemon," but the idea is the same so take your pick...) This simple strategy allows you to make sure that, when one service depends upon another, they will be started and stopped in the proper sequence.

We said that each of these files (in /etc/rc.d/rcX.d) is a symbolic link, which means that it "points to," or "refers to," another file located somewhere else. That "somewhere else" will be the directory /etc/init.d. The symbolic link will point to a shell command-file which takes a single parameter such as "start" or "stop." When init is processing a "S"tart link, it will supply the parameter "start." When following a "K"ill link, it will supply "stop."

There can be any number of symbolic-links pointing to the same file, and very frequently there are. If a service (daemon) needs to be started in more than one runlevel, you simply have a symbolic-link in each of the appropriate /etc/rc.d/rcX.d directories.

As a quick example, my http daemon has a script in /etc/init.d/httpd and a symbolic link from each of the 7 run levels:

/etc/rc.d/rc0.d/K15httpd /etc/rc.d/rc1.d/K15httpd /etc/rc.d/rc2.d/S85httpd /etc/rc.d/rc3.d/S85httpd /etc/rc.d/rc4.d/S85httpd /etc/rc.d/rc5.d/S85httpd /etc/rc.d/rc6.d/K15httpd

When my machine enters run level 0, 1 or 6, then, the httpd process will be killed (/etc/init.d/httpd stop will be run), and rather early on in the process of shutting down (because "15" is a small number). Likewise, when moving to run levels 2-5, httpd will be started (/etc/init.d/httpd start</tt>) somewhat late in the potential list of scripts that are run (because "85" is a large number). This usually ensures that httpd is killed before networking, for instance, and started after it so that httpd will always have a run-time environment with networking enabled.

(Note: if you are moving from a runlevel where (say) httpd</tt> should be running, to a runlevel where it also should be running, init may simply leave the service alone, recognizing that there is no need to stop it just to immediately restart it.)

Most often, one can tune the run level configuration via the chkconfig</tt> command, or start and stop these initialization scripts via the service</tt> command: chkconfig --list httpd chkconfig --levels 345 httpd on service httpd start service httpd restart service httpd status

However, in Slackware (and it is closer to this on certain systems like Arch or the *BSDs than it is to that described above) there are no directories full of numbered symlinks. /etc/rc.d/ contains a few scripts for several of the daemons or subsystems a system may run, and the scripts rc.{0,S,K,M,6}. rc.0 actually is a symlink to the rc.6 script because it's so similar: rc.6 reboots the system except when invoked as rc.0, in which case it halts the system. rc.S is the general system configuration script, rc.K is run for single-user mode, and rc.M is run in multi-user mode. The rc.? scripts do several things directly, as well as running the other scripts. The specialized tools chkconfig and service do not exist on Slackware, where runlevels are administered with vi</tt> or other editors. However, there is some SysV compatibility for programs that aren't intelligent enough to adapt to their environment.

How to change run level
To switch between run levels in the terminal you use the init</tt> command:

init [-a] [-s] [-b] [-z xxx] <Run Level Number>

or telinit</tt>

telinit [-t sec] <Run Level Number>

If already in X and using a graphical login, one mechanism to switch between run levels using the keyboard is to first switch to a virtual console with this command: Ctrl+Alt+F<Console Number> (For example, to switch to console 1, you use Ctrl+Alt+F1</tt>)

Then you can acquire superuser privileges (.e.g, su</tt>) and issue the init</tt> or telinit</tt> commands to change the actual run level. You can switch run levels from within an xterm while still in X, but you may be surprised when your xterm goes away! It's less stressful for new people to first switch to the virtual console, but switching while still in X isn't harmful.

If in X having used the 'startx' mechanism, just shut down your window manager and invoke (tel)init or, as stated above, let init do it for you. If already on a virtual terminal, just invoke (tel)init directly.

Determine the current run level
To check the current run level use $ who -r This will report the current intended run level.