This Drill Down covers the init program, and the files and directories init<I> </I>uses to configure a Linux system for any run-level. It also covers adding and removing services from system run-levels so you can customize bootup and shutdown like a pro.
The ability to manage the Linux bootup and shutdown processes is essential for a system administrator. The administrator must know which services are running on the system, how to add new services, and how to remove services that are not required. This Daily Drill Down will provide Linux administrators with the information necessary to customize the files and directories involved in the Linux bootup and shutdown processes and will examine the tools available to customize these processes.
An overview of the boot process
When a Linux system is booted, the Linux boot loader (LILO) loads the kernel. When called by LILO, the kernel is uncompressed, the display device is initiated, and the kernel starts checking for hardware attached to your system. As it finds hardware devices, it loads kernel modules to provide support for these devices. Once hardware support is loaded, the kernel mounts the root (/) filesystem as read-only. If no problems are detected in /, the root filesystem is mounted as read-write.
After the root filesystem is mounted as read-write, the kernel executes a program called init. When init has completed its execution, the system is up and running. The init process is highly configurable, via the /etc/inittab file and files and directories with the init configuration process.
The following syntax is used for configuration lines in the /etc/inittab file:
- The first field is a unique label, which identifies an entry in the inittab file.
- The second field specifies which run-levels this entry applies to.
- The third field specifies the action to be taken.
- The fourth field identifies the process to be run and any arguments that apply to that process. Command-line arguments may also be specified in the fourth field.
The state of a Linux system is specified by its run-level. There are seven run-levels available on a Linux system.
- 0—Halt (Do not set initdefault to this run-level.)
- 1—Single-user mode
- 2—Multiuser—with no networking support
- 3—Full multiuser mode—with networking support
- 5—X11—with multiuser and networking support
- 6—Reboot (Do not set initdefault to this run-level.)
It’s possible to specify multiple run-levels in the same init configuration line. For example, to specify a configuration for both run-level 1 and run-level 3, use the following syntax:
Table A lists the possible actions for system run-levels.
|respawn||The process is restarted whenever it terminates.|
|wait||The process is run once, and init waits until it terminates.|
|once||The process is run once.|
|boot||The process is run during system boot, regardless of the run-level.|
|bootwait||The process is run during system boot, and init waits for the|
|process to terminate.|
|off||No action is taken. Used to disable a configuration line without|
|removing it. May be used instead of a comment (#).|
|ondemand||Normally not used.|
|initdefault||Specifies the default run-level for the system. The process filed is|
|sysinit||The process is run once during system boot. A sysinit action takes|
|precedence over boot or bootwait actions.|
|powerwait||Run when init receives a SIGPWR signal. An uninterruptible power|
|supply (UPS) will issue the SIGPWR signal when a power problem|
|Is detected. When the SIGPWR signal is issued, init will wait until|
|the process terminates.|
|powerfail||Same as powerwait, but init does not wait for the process to|
|powerokwait||Run when init receives a SGIPWR signal and the /etc/powerstatus|
|file contains the text string OK. This file is normally created by the|
|UPS monitoring software and is used to indicate that the power|
|problem is corrected.|
|ctrlaltdel||Run when init receives a SIGINT signal.|
|kbrequest||Run when init receives a keyboard signal from the keyboard handler.|
The /etc/rc.d/rc.sysinit script
When a Linux system is booted, the kernel runs init, which in turn runs the /etc/rc.d/rc sysinit script. This script is run before any other actions are taken because of the following line in the /etc/inittab file:
The run-level field in this line is empty because init recognizes sysinit as a system initialization action. The rc.sysinit performs several tasks, including setting the hostname, enabling the swap partition, checking filesystems, and loading kernel modules. Normally, you will not have to modify the /etc/rc.sysinit script.
The /etc/rc.d/rc script
When init is told to change to one of the seven possible run-levels, a script specified in one of the following seven lines in the /etc/inittab file is run:
For each run-level [0-6], a script named /etc/rc.d/rc is run, with the run-level used as the argument to the script. This script is used to start and stop all services in the specified run-level. For example, if init is told to change the run-level to 5, the /etc/rc.d/rc script will be run with an argument of 5 in a command-line like the following:
The rc script performs a three-step process:
- It checks to ensure that a subdirectory exists for the specified run-level. If the script is run with an argument of 5, it will make sure that the /etc/rc.d/rc5.d subdirectory exists. If this directory exists, the script continues to the next step. If this directory does not exist, the run-level is not changed.
- It determines whether any of the programs (often called services or processes) that are supposed to run in the specified run-level are already running. If a service is already running, the script will kill it so that the service may be started in the next step.
- Any script with the K argument is stopped and restarted, and any script with the S argument is started.
A typical /etc/rc.d/rc5.d file is shown below. This example shows an abbreviated version of the /etc/rc.d/rc.5 directory on my Red Hat 6.0 system. The listing shows the services that are to be started or stopped and the symbolic link to the scripts in the /etc/rc.d/init.d directory.
lrwxrwxrwx 1 root root 16 May 21 12:54 K08autofs -> ../init.d/autofs
lrwxrwxrwx 1 root root 15 May 21 12:54 K15httpd -> ../init.d/httpd
lrwxrwxrwx 1 root root 18 May 21 12:54 S75keytable -> ../init.d/keytable
lrwxrwxrwx 1 root root 13 May 21 12:54 S85gpm -> ../init.d/gpm
Note that the scripts in the /etc/rc.d/init.d directory are linked in two ways. Some are linked with the syntax
K[two-digit number] script-name
while others use the syntax
S[two-digit number] script-name
The scripts beginning with S are started, and the scripts beginning with K are stopped and then restarted if necessary. The two-digit specifies the order of execution for these services, with the lowest numbered services being executed first. In the above example, the script K08autofs is executed before the service K15httpd. Once the rc script is finished, the processing required for init is also finished, and the system becomes available in the specified run-level.
The /etc/rc.d/init.d directory
The /etc/rc.d/init.d directory is used to hold all the scripts needed by all run-levels. Each script in this directory is used to start or stop a particular service.
All the scripts in this directory use a command-line syntax. For example, to start the ipchains service, which is a program used to configure a Linux firewall, the following script would be run:
And to stop the ipchains service, use this command:
All scripts in the /etc/rc.d/init.d directory used start and stop as arguments to start or terminate a service. These scripts are read via symbolic links to the /etc/rc[0-6] directories.
The /etc/rc.d/rc.local script
The /etc/rc.d/rc.local script is run once at the end of run-levels 2, 3, and 5. Any command or script that needs to be run once per boot may be added to this file.
The /etc/rc.d/rc.serial script
The /etc/rc.d/rc.serial script is typically run once at the end of run-level 3 or 5 to initialize serial ports.
Booting up your system
During boot up, init first runs the rc.sysinit script and then runs the script for the default run-level. The default run-level is set in the /etc/inittab file with an entry similar to the example shown here:
In this example, the default is set to 3. This means that init will run the script required to put the system in multiuser mode, with networking support. The section following the default run-level setting contains a line specifying what needs to be done to change to each run-level. For run-level 3, the scripts in the /etc/rc.d/rc3.d directory that begin with S will be run. The rc script will also provide a start command to each script that begins with S. When all of these scripts are run, the rc script will finish and the system will be available in the specified run-level.
Overriding the default run-level
The default run-level for a Linux system may be overridden at the LILO prompt. The syntax for this command is
For example, to boot my system to single-user mode, instead of the default run-level 3, I would use the command
or the command
By using this command with the appropriate run-level, the default run-level is overridden.
Shutting down the system
The easiest way to shut down a Linux system is to enter the desired run-level in the command line. For example, the command
init linux 0
will shut down the system. However, this command does not inform users that the system is about to be halted, and they will be unable to save any files they have open. A more practical way to shut down the system is to use the shutdown command. The shutdown command broadcasts a message to all users that the run-level is about to change. The shutdown command also allows the administrator to schedule the shutdown command. The shutdown command tells init to change the current run-level by using either the halt or boot command.
Some examples are shown in Table B.
|shutdown -r now||Shuts down and reboots now.|
|shutdown -h 5||Shuts down and halts the system in five minutes.|
|shutdown -k 5||Does not shut down but sends broadcast message to users.|
|shutdown -c||Cancels a running shutdown.|
Disabling logins during shutdown
Users are able to log in during a shutdown countdown period. To prevent users from logging in during this period, create a text file called /etc/nologin, with an appropriate message stating that a shutdown is in progress and that logins are disabled. After this file is created, add the command
rm -f /etc/nologin
to the /etc/rc.local script, and make sure that it is run by init at the end of run-level 3.
Giving users permission to run shutdown
In its default configuration, the /etc/inittab file gives any user the ability to reboot a Linux server using the [Ctrl][Alt][Delete] key combination. The following line in /etc/inittab allows this action:
ca::ctrlaltdel: /sbin/shutdown -t3 -r now
This line allows the [Ctrl][Alt][Delete] key combination to be used for rebooting and calls the shutdown script to reboot immediately. To disable this function, add a comment (#) to this line or remove it from the /etc/inittab file. To give specific users permission to use the shutdown script, create the /etc/shutdown.allow file.
The /etc/shutdown.allow file is a text file that contains one username per line. Each user named in this file is allowed to use the shutdown command.
Dealing with power failures
Eventually, you’ll have to deal with a power failure on your system. My first concern when faced with a power failure is to make sure that my servers are shut down properly. This ensures that file systems are unmounted properly and that data contained in buffers is properly written to the hard disk. The default /etc/inittab file contains the following line:
pf::powerfail: /sbin/shutdown -f -h +2 "Power failure; System Shutting Down"
This line tells init to run shutdown in the event of a power failure. The powerfail action is enabled when the monitoring software on the Uninterruptible Power Supply (UPS), or powerd, the power-monitoring daemon, send the SIGPWR signal to init. The default setting allows the UPS to run the system for two minutes prior to running the shutdown script.
If power is restored during the shutdown process, the following line cancels the running shutdown:
pr:12345:powerokwait:/sbin/shutdown -c "Power Restored. Shutdown Cancelled"
When init receives a SIGPWR signal and the file /etc/powerstatus contains the text string OK, the powerok action is activated.
Managing init files
The System V init program uses numerous files, symbolic links, and directories. Fortunately, Linux includes three tools for managing init files:
The chkconfig utility allows the administrator to maintain the symbolic links required for starting and stopping services in a run-level; chkconfig can manage all scripts in the /etc/rc.d/init.d directory. Following are some typical uses for chkconfig.
List manageable services
To list what services will start in each run level, use the command
To check the run-level configuration for a particular service, use the command
/sbin/chkconfig --list inet
The preceding command lists the configuration for the inet service in each run-level. This command produces the following on my system:
inet 0:off 1:off 2:off 3:on 4:on 5:on 6:off
The output tells me that the inet service is enabled for run-levels 3 and 5 and is disabled for all other run-levels.
Add a new service
To make a new service available to the current run-level, run the following command:
chkconfig --add httpd
This command adds the httpd service to the current run-level.
To add a new service to a specific run-level, use the command
/sbin/config --level 4 --add inet
This command adds the inet service to run-level 4.
Delete a service
To remove a service from the current run-level, use the command
/sbin/chkconfig --del inet
This command deletes the inet service from the current run-level.
To delete a service from a specific run-level, use the command
/sbin/chkconfig --del gated --level 5
This command removes the gated service from run-level 5.
The ntsysv utility allows service management through a simple menu interface. To run ntsysv for the current run-level, use the command
Select the services you’d like to start in the current run-level and click OK.
To run ntsysv for a specific run-level, use the command
For example, to run ntsyscv for run-level 4, use the command
/usr/sbin/ntsysv --level 4
Select the services you’d like started for the specified run-level and click OK.
To use linuxconf to manage init files, follow these steps:
- From the command line, type linuxconf.
- Select Control | Control Panel | Control Service.
- Enable or disable the appropriate services.
- Accept the changes.
- Activate the changes prior to quitting linuxconf.
In this Daily Drill Down, I covered the bootup and shutdown procedures for a Linux system. I also explained the init program and the files and directories that init depends upon to configure a Linux system for any run-level. Finally, I showed you how to add and remove services from Linux system run-levels and discussed the tools available on a Linux system to manage init files.