Running Linux, 5th Edition (2009)
Part II. System Administration
Chapter 17. System Start and Shutdown
Booting the System
There are several ways of booting Linux on your system. The most common methods involve booting from the hard drive or using a boot floppy . In many cases, the installation procedure will have configured one or both of these for you; in any case, it's important to understand how to configure booting for yourself.
Using a Boot Floppy
Traditionally, a Linux boot floppy simply contains a kernel image, which is loaded into memory when you insert the floppy and start the system.[*]
Many Linux distributions create a boot floppy for you in this way when installing the system. Using a boot floppy is an easy way to boot Linux if you don't want to bother booting from the hard drive. (For example, Windows NT/2000/XP's boot manager is somewhat difficult to configure for booting Linux. We talk about this in the next section.) Once the kernel has booted from the floppy, you are free to use the floppy drive for other purposes.
We include some technical information here in order to explain the boot process, but rest assured that in most cases, you can just insert the floppy disk, and booting works. Reading the following paragraphs will help you understand your system, though.
The kernel image is usually compressed, using the same algorithm as the gzip or the bzip2 compression programs (more on this in "Compiling the kernel" in Chapter 18). Compression allows the kernel, which may be several megabytes or more in size, to require only a few hundred kilobytes of disk space. Part of the kernel code is not compressed: this part contains the routines necessary to uncompress the kernel from the disk image and load it into memory. Therefore, the kernel actually bootstraps itself at boot time by uncompressing into memory.
A number of parameters are stored in the kernel image. Among these parameters is the name of the device to use as the root filesystem once the kernel boots. Another parameter is the text mode to use for the system console. All these parameters may be modified using the rdev command, which we discuss later in this section.
After the kernel has started, it attempts to mount a filesystem on the root device hardcoded in the kernel image itself. This will serve as the root filesystem—that is, the filesystem on /. "Managing Filesystems" in Chapter 10 discusses filesystems in more detail; all that you need to know for now is that the kernel image must contain the name of your root filesystem device. If the kernel can't mount a filesystem on this device, it gives up, issuing a kernel "panic" message. (Essentially, a kernel panic is a fatal error signaled by the kernel itself. A panic will occur whenever the kernel is terminally confused and can't continue with execution. For example, if there is a bug in the kernel itself, a panic might occur when it attempts to access memory that doesn't exist. We'll talk about kernel panics more in the section "What to Do in an Emergency" in Chapter 27.)
The root device stored in the kernel image is that of your root filesystem on the hard drive. This means that once the kernel boots, it mounts a hard drive partition as the root filesystem, and all control transfers to the hard drive. Once the kernel is loaded into memory, it stays there—the boot floppy need not be accessed again (until you reboot the system, of course).
Given a reasonably small kernel image, you can create your own boot floppy. On many Linux systems, the kernel itself is stored in the file /boot/vmlinuz.[*] This is not a universal convention, however; other Linux systems store the kernel in /vmlinuz or /vmlinux, and still others in a file such as /Image. (If you have multiple kernel images, you can use GRUB to select which one to boot. See the next section.) Note that newly installed Linux systems may not have a kernel image on the hard drive if a boot floppy was created for you. In any case, you can build your own kernel. It's often a good idea to do this anyway: you can customize the kernel to include only those drivers for your particular hardware. See "Building the Kernel" in Chapter 18 for details.
All right. Let's say that you have a kernel image in the file /boot/vmlinuz. To create a boot floppy, the first step is to use rdev to set the root device to that of your Linux root filesystem. (If you built the kernel yourself, this should be already set to the correct value, but it can't hurt to check withrdev.) We discussed how to create the root device in "Editing /etc/fstab" in Chapter 2.
As root, use rdev -h to print a usage message. As you will see, there are many supported options, allowing you to specify the root device (our task here), the swap device, ramdisk size, and so on. For the most part, you needn't concern yourself with these options now.
If we use the command rdev /boot/vmlinuz, the root device encoded in the kernel found in /boot/vmlinuz will be printed:
courgette:/# rdev /boot/vmlinuz
Root device /dev/hda1
If this is incorrect, and the Linux root filesystem is actually on /dev/hda3, we should use the following command:
courgette:/# rdev /boot/vmlinuz /dev/hda3
rdev is the strong, silent type; nothing is printed when you set the root device, so run rdev /boot/vmlinuz again to check that it is set correctly.
Now you're ready to create the boot floppy. For best results, use a brand-new, formatted floppy. You can format the floppy under Windows or using fdformat under Linux; this will lay down the sector and track information so that the system can autodetect the size of the floppy. (See the section "Managing Filesystems" in Chapter 10 for more on using floppies.)
To create the boot floppy, use dd to copy the kernel image to it, as in the following example:
courgette:/# dd if=/boot/vmlinuz of=/dev/fd0 bs=8192
If you're interested in dd, the manual page will be illustrative; in brief, this copies the input file (if option) named /boot/vmlinuz to the output file (of option) named /dev/fd0 (the first floppy device), using a block size (bs) of 8192 bytes. Of course, the plebian cp can be used as well, but we Unix sysadmins love to use cryptic commands to complete relatively simple tasks. That's what separates us from mortal users.
Your boot floppy should now be ready to go. You can shut down the system (see "Shutting Down the System" later in this chapter) and boot with the floppy, and if all goes well, your Linux system should boot as it usually does. It might be a good idea to make an extra boot floppy as a spare. In "What to Do in an Emergency," in Chapter 27, we describe methods by which boot floppies can be used to recover from disaster.
GRUB is a general-purpose boot manager that can boot whatever operating systems you have installed on your machine, including Linux. There are dozens of ways to configure GRUB. Here, we discuss the two most common methods: installing GRUB on the master boot record of your hard drive and installing GRUB as a secondary bootloader for Linux only.
GRUB is the most common way to boot Linux from the hard drive. (By the expression "boot from the hard drive," we mean that the kernel itself is stored on the hard drive and no boot floppy is required, but remember that even when you use a boot floppy, control is transferred to the hard drive once the kernel is loaded into memory.) If GRUB is installed on your drive's master boot record, or MBR, it is the first code to run when the hard drive is booted. GRUB can then boot other operating systems—such as Linux or Windows—and allow you to select between them at boot time.
It should be mentioned here that GRUB is not the only boot manager available for booting Linux. There are alternatives, such as the older LILO (Linux Loader) that work just as well. However, because most distributions these days use GRUB, this is what we cover here.
Windows NT and later versions of Windows have boot managers of their own that occupy the MBR. If you are using one of these systems, in order to boot Linux from the hard drive, you may have to install GRUB as the "secondary" bootloader for Linux only. In this case, GRUB is installed on the boot record for just your Linux root partition, and the boot manager software (for Windows NT/2000) takes care of executing GRUB from there when you wish to boot Linux.
As we'll see, however, the Windows NT/2000/XP boot managers are somewhat uncooperative when it comes to booting GRUB. This is a poor design decision, and if you must absolutely use one of these boot managers, it might be easier to boot Linux from floppy instead. Read on. Or, if you really want to go with Linux all the way, you can use GRUB to boot Windows NT/2000/XP and dump the Windows boot managers completely. That is usually a fairly painless way, and the one we recommend. It is also what most distributions install automatically if you try to install Linux on a computer with an existing Windows installation.
Use of GRUB with Windows 95/98/ME/2000/XP is quite simple. You just configure GRUB to boot Windows 95/98/ME/2000/XP (see the next section). However, if you install Windows 95/98/ME/2000/XP after installing GRUB, you need to reinstall GRUB (as the Windows 95/98/ME/2000/XP installation procedure overwrites the MBR of your primary hard drive). Just be sure you have a Linux boot floppy on hand so that you can boot Linux and rerun GRUB.
Before proceeding you should note that a number of Linux distributions are capable of configuring and installing GRUB when you first install the Linux software. It might be a good idea to just let your distribution's installation program do its thing, install GRUB, and then check what it has done; this gives you something working to start with that you can then tweak to your taste.
The /etc/grub.conf file
The first step in configuring GRUB is to set up the GRUB configuration file, which is often stored in /etc/grub.conf. The /etc/grub.conf file references other configuration files that we look at later. Often, the /etc/grub.conf file can be very short.
We are going to look at a sample grub.conf file. You can use this file as a base for your own grub.conf and edit it for your own system.
It should be said at this point that GRUB is very flexible and can actually drop you into a shell that lets you enter GRUB commands interactively during the boot process. However, most users would find this both tedious and error-prone, which is why we describe another use here, which will provide you with a convenient menu that you can select from (for example, in order to boot different kernels or even different operating systems). With this setup, the grub.conf file can be quite concise. Here is an example:
install --stage2=/boot/grub/stage2 /grub/stage1 (hd0) /grub/stage2 0x8000
The first line specifies the drive to boot from. In this case, it is the first partition on the first hard disk--hd is for hard disk, the first zero is for the first hard disk in the system, and the second zero for the first partition on that particular hard disk (GRUB always starts counting at zero!). It is quite common among Linux users to reserve a small partition (often mounted as /boot) for the kernel image and booting-related files. Because there have been limits in the past regarding the parts of the disk from which bootloaders could load kernel images, it has become customary to make this partition the very first one. Although these limits are mostly gone with modern hardware, modern BIOSes, and modern bootloaders, this tradition prevails, and it definitely does not hurt to keep it.
A few more examples: (fd0) would mean to boot from the first floppy disk in the system, and (hd3,4) would mean the fifth partition on the fourth hard drive (of one lucky Linux user who apparently can afford lots of hardware). There is also the special name (nd) which is used for booting the kernel image from the network, something that is beyond the scope of this book.
The second line is fairly complex. It would go too far to dissect the complete booting process, but we can at least say that GRUB uses a two-stage booting process, and this command specifies where to get the instructions for the two stages from, at which address to load them into the computer's memory, and what to do then. The "what to do then" part is the most interesting for us; in the example configuration file, it is the (hd0,0)/grub/menu.lst part at the end. Where should this file be located so that GRUB can find it? If you try:
pooh:~ # ls /grub/menu.lst
/bin/ls: /grub/menu.lst: No such file or directory
you will not find it. But remember that GRUB uses the parentheses to denote a device, in our case a hard disk partition, the first partition on the first hard drive. This could be anywhere, of course, but if you remember that most systems create a small partition that does not contain much except the kernel image and the bootloader files, and that it is often mounted as /boot, you can try:
pooh:~ # ls /boot/grub/menu.lst
Aha! Of course, if you are installing GRUB from scratch on your system and, unlike us, do not have a preinstalled configuration that you are just fiddling around with, then you will not get a result here either. Rest assured, however, that this is where GRUB will search for the menu file.
What would such a menu file look like? Here is an example of a version that loads two different Linux configurations and MS-Windows, all presented in a convenient menu:
kernel (hd0,5)/boot/vmlinuz root=/dev/hda6 vga=0x314
title Linux Failsafe
kernel (hd0,5)/boot/vmlinuz root=/dev/hda6 ide=nodma apm=off acpi=off vga=normal noresume
barrier=off nosmp noapic maxcpus=0 3
The first two lines together mean that when the boot menu is presented by GRUB, the user has 10 seconds (timeout) to make a choice; otherwise, the first entry of the following list will be booted.
After these two initial lines, there are three sections that each start with title. After the title, a string is specified that will be shown in the boot menu at boot time. For the two Linux configurations, there is then a kernel line that shows where the kernel image is loaded from. Everything else is passed directly to the kernel as boot parameters, including what the root device should be, and the terminal mode (vga=0x314). In the so-called failsafe configuration, we specify a lot of kernel parameters that turn off just about any kernel functionality that has the slightest chance of going wrong. Such a system will be slow and not have complete functionality, but if you have misconfigured something, the failsafe kernel may still get along and let you at least boot the system so that you can repair things.
If you type in those commands manually at the GRUB shell, you would have ended with the command boot. The kernel command loads the kernel into memory, but does not actually boot it; the boot command performs the actual booting process. However, if you use the GRUB menu system as we do here, the boot command is implicit and can be left out at the end of each section.
Loading Windows works differently. GRUB is not able to load operating systems other than Linux, the BSD family, and a few others directly. For those other systems, such as Windows, it invokes instead the bootloader that comes with those systems. This is called chain-loading, and theGRUB command to do this is not surprisingly called chainloader. The +1 means that GRUB can find the bootloader on the partition specified with the previous root command, one sector into the partition.
When you are satisfied with your GRUB setup, you still need to install it. This is best done with the command grub-install, which expects to be told the directory in which the stage files and kernel images can be found, and on which device to install the bootloader. This could look like this:
pooh:~ # grub-install --root-directory=/boot /dev/hda
This installs the bootloader on the first IDE hard drive (/dev/hda), which is typically the one that the computer's BIOS searches for finding the initial booting information.
This was just a short introduction into the world of GRUB. GRUB can do a lot more, such as booting kernel images from the network or over a serial line, providing fancy graphics, and so on. If you plan to do any serious work with GRUB (and since a bootloader is crucial for being able to use the system at all, any changes of configuration files beyond trivial things such as changing the strings of the menu entries, the default entry, or the timeout, can be considered serious in this context), we urge you to read the excellent GRUB documentation that comes as Info files, and that you can read nicely in KDE by typing info:grub in Konqueror's location bar.
Specifying boot-time options
When you first installed Linux, more than likely you booted either from a floppy or a CD-ROM, which very likely gave you a GRUB (or other bootloader) boot menu. Selecting an entry and typing e gets you a boot prompt. At this prompt you can enter several boot-time options, such as:
to specify the hard drive geometry. Each time you boot Linux, it may be necessary to specify these parameters in order for your hardware to be detected correctly. If you are using GRUB to boot Linux from the hard drive, you can specify these parameters in the kernel line in the GRUBconfiguration file instead of entering them at the boot prompt each time. To the Linux entry, just add a line such as:
append = "hd=683,16,38"
This causes the system to behave as though hd=683,16,38 were entered at the GRUB boot prompt. If you wish to specify multiple boot options, you can do so with a single append line, as in:
append = "hd=683,16,38 hd=64,32,202"
In this case, we specify the geometry for the first and second hard drives, respectively. Once you are done with your changes at the boot prompt, press the Esc key to go back to the boot menu, and boot from there.
Note that you need to use such boot options only if the kernel doesn't detect your hardware at boot time, which is unlikely unless you have very old or very uncommon hardware. You should already know if this is necessary, based on your experiences with installing Linux; in general, you should have to specify kernel parameters in the kernel lines in the GRUB menu file only if you had to specify these boot options when first booting the Linux installation media.
There are a number of other boot-time options. Most of them deal with hardware detection, which has already been discussed in Chapter 2. However, the following additional options may also be useful to you:
Boot the system in single-user mode; skip all the system configuration and start a root shell on the console. See "What to Do in an Emergency" in Chapter 27 for hints on using this.
Mounts the named partition as the Linux root filesystem.
Mounts the root filesystem as read-only. This is usually done in order to run fsck; see "Checking and Repairing Filesystems" in Chapter 10.
Specifies a size, in bytes, for the ramdisk device. Most users need not worry about using the ramdisk; it's useful primarily for installation.
Sets the VGA display mode. Valid modes are normal, extended, ask, or an integer.
Tells the kernel how much RAM you have. If you have 64 MB or less, the kernel can get this information from the BIOS, but if you use an older kernel and you have more, you will have to tell the kernel the exact amount, or it will use only the first 64 MB. For example, if you have 128 MB, specify mem=128m. Fortunately, this is no longer necessary with newer kernels.
Any of these options can be entered by hand at the GRUB boot prompt or specified in the kernel line in the GRUB configuration file.
If you have GRUB installed on your MBR, the easiest way to remove it on Windows 95/98/ME is to use Windows FDISK. The command:
runs FDISK and overwrites the MBR with a valid Windows boot record. On Windows NT/2000/XP, the procedure is a lot more involved.
[*] A Linux boot floppy may instead contain a GRUB boot record, which causes the system to boot a kernel from the hard drive. We discuss this in the next section, when we talk more about GRUB.
[*] Why the silly filename? On many Unix systems, the kernel is stored in a file named /vmunix where vm stands for "virtual memory." Naturally, Linux has to be different and names its kernel images vmlinux, and places them in the directory /boot to get them out of the root directory. The name vmlinuz was adopted to differentiate compressed kernel images from uncompressed images. Actually, the name and location of the kernel don't matter a bit, as long as you either have a boot floppy containing a kernel, or GRUB knows how to find the kernel image.
System Startup and Initialization
In this section, we talk about exactly what happens when the system boots. Understanding this process and the files involved is important for performing various kinds of system configuration.
Kernel Boot Messages
The first step is booting the kernel. As described in the previous section, this can be done from floppy or hard drive. As the kernel loads into memory, it will print messages to the system console, but usually also saves them in the system logfiles as well. As root, you can always check the file/var/log/messages (which contains kernel messages emitted during runtime as well). The command dmesg prints out the last lines of the kernel message ring buffer; directly after booting, naturally, you will get the boot messages .
The following few paragraphs go through a couple of the more interesting messages and explain what they mean. These messages are all printed by the kernel itself, as each device driver is initialized. The exact messages printed depend on what drivers are compiled into your kernel and what hardware you have on your system. You are likely to have more, fewer, or different messages; we'll concentrate here on the messages that are quite common.
Linux version 188.8.131.52-21.7-default (geeko@buildhost) (gcc version 3.3.5 2005011
7 (prerelease) (SUSE Linux)) #1 Thu Jun 2 14:23:14 UTC 2005
tells you the version number of the kernel, on which machine, when, and with which compiler it was built.
Next, the kernel reports a number of things about the BIOS, the amount of memory found, power management settings, and so one. Here are some of the more interesting lines (of course, depending on your hardware and setup, these may look different for you):
127MB HIGHMEM available.
896MB LOWMEM available.
Kernel command line: root=/dev/hda6 vga=0x314 selinux=0 splash=silent resume=/de
Detected 599.481 MHz processor.
Notice in particular the kernel command line; you can double-check here that you are actually booting the configuration that you think you are booting.
Then, the kernel tells us which console settings it has picked and which console type it has detected:
Console: colour dummy device 80x25
Note that this involves only the text mode being used by the kernel, not the capabilities of your video card. It also has nothing to do with the X Window System; the kernel is not concerned with that at all.
You'll then see the "BogoMIPS" calculation for your processor:
Calibrating delay loop... 1187.84 BogoMIPS (lpj=593920)
This is an utterly bogus (hence the name) measurement of processor speed, which is used to obtain optimal performance in delay loops for several device drivers.
The kernel gathers information about the PCIbus and checks for any PCI cards present in the system:
PCI: PCI BIOS revision 2.10 entry at 0xfd8d6, last bus=8
PCI: Using configuration type 1
PCI: Probing PCI hardware (bus 00)
PCI: Ignoring BAR0-3 of IDE controller 0000:00:1f.1
PCI: Transparent bridge - 0000:00:1e.0
Linux then sets up networking, the mouse port, and the serial driver. A line such as:
ttyS00 at 0x03f8 (irq = 4) is a NS16550A
means that the first serial device (/dev/ttyS00, or COM1) was detected at address 0x03f8, IRQ 4, using 16550A UART functions. Next comes some more hardware detection, such as the real-time clock and the floppy drive:
Real Time Clock Driver v1.12
Floppy drive(s): fd0 is 1.44M
FDC 0 is a National Semiconductor PC87306
loop: loaded (max 8 devices)
Adding 1029632k swap on /dev/hda5. Priority:42 extents:1
tells you how much swap space the kernel has found. Among the further tasks performed during a typical boot are finding and configuring a parallel port (lp1), detecting and configuring the network card, and finally setting up the USB subsystem.
Again, depending on the kernel version and your configuration and hardware, you will see other messages (this was just an excerpt, after all).
init, inittab, and rc Files
Once the device drivers are initialized, the kernel executes the program init, which is found in /etc, /bin, or /sbin (it's /sbin/init on most systems). init is a general-purpose program that spawns new processes and restarts certain programs when they exit. For example, each virtual console has agetty process running on it, started by init. Upon login, the getty process is replaced with another. After logging out, init starts a new getty process, allowing you to log in again.
init is also responsible for running a number of programs and scripts when the system boots. Everything init does is controlled by the file /etc/inittab. To understand this file, you need to understand the concept of runlevels first.
A runlevel is a number or letter that specifies the current system state, as far as init is concerned. For example, when the system runlevel is changed to 3, all entries in /etc/inittab containing 3 in the column specifying the runlevels will be executed. Runlevels are a useful way to group entries in /etc/inittab together. For example, you might want to say that runlevel 1 executes only the bare minimum of configuration scripts, runlevel 2 executes everything in runlevel 1 plus networking configuration, runlevel 3 executes everything in levels 1 and 2 plus dial-in login access, and so on. Today, the Red Hat and SUSE distributions are set up so that runlevel 5 automatically starts the X Window System graphical interface. Debian does so at runlevels 2 through 5--provided you have installed an X display manager such as xdm.
For the most part, you don't need to concern yourself with runlevels. When the system boots, it enters the default runlevel (set in /etc/inittab, as we will soon show). On most systems, this default is runlevel 3 or 5. After we discuss normal booting, we'll show you how to enter another runlevel that you will sometimes need to use—runlevel 1, or single-user mode. Debian users may want to investigate the file-rc package, which lets you configure runlevels in a single file.
Let's take a look at a sample /etc/inittab file:
# Set the default runlevel to three
# First script to be executed
# Run /etc/init.d/rc with the runlevel as an argument
# Executed when we press ctrl-alt-delete
ca::ctrlaltdel:/sbin/shutdown -t3 -rf now
# Start agetty for virtual consoles 1 through 6
1:2345:respawn:/sbin/mingetty --noclear tty1
Fields are separated by colons. The last field is the most recognizable: it is the command that init executes for this entry. The first field is an arbitrary identifier (it doesn't matter what it is as long as it's unique in the file), and the second indicates what runlevels cause the command to be invoked. The third field tells init how to handle this entry; for example, whether to execute the given command once or to respawn the command whenever it exits.
The exact contents of /etc/inittab depend on your system and the distribution of Linux you have installed.
In our sample file, we see first that the default runlevel is set to 3. The actionfield for this entry is initdefault, which causes the given runlevel to be set to the default. That's the runlevel normally used whenever the system boots. You can override the default with any level you want by running init manually (which you might do when debugging your configuration) and passing in the desired runlevel as an argument. For instance, the following command shuts down all services that belong to the current runlevel, but not to runlevel 5 (warn all your users before doing this!):
tigger# init 5
GRUB can also boot in single-user mode (usually runlevel 1)--see "Specifying boot-time options," earlier in this chapter.
The next entry tells init to execute the script /etc/init.d/boot when the system boots. (The action field is si [sysinit], which specifies that this entry should be executed when init is first started at system boot.) On other distributions, this file might be elsewhere, but /etc/init.d/boot is where it belongs according to the Linux Filesystem Hierarchy Standard (FHS). The file is simply a shell script containing commands to handle basic system initialization; for example, swapping is enabled, filesystems are checked and mounted, and the system clock is synchronized with the CMOSclock. Many of the commands in this file are discussed in "Managing Filesystems" and "Managing Swap Space" in Chapter 10.
Next, we see that the system executes the script /etc/init.d/rc when it enters any of the runlevels through 6, with the appropriate runlevel as an argument. rc is a generic startup script that executes other scripts as appropriate for that runlevel. The action field here is wait, which tells init to execute the given command and to wait for it to complete execution before doing anything else.
Linux stores startup commands in files with rc in the name, using an old Unix convention. The commands do all the things necessary to have a fully functioning system, such as starting the servers or daemons mentioned in "Processes" in Chapter 10. Thanks to these commands, the system comes up ready with logging facilities, mail, a web server, or whatever you installed and asked it to run. As explained in the previous section, the files are invoked from /etc/inittab. The commands are standard shell commands, and you can simply read the various rc files to see what they do.
In this section, we describe the structure of the rc files so that you can understand where everything starts, and so that you can start or stop servers manually in the rare case that they don't do what you want them to do. We use SUSE as our model, but once you get the idea of what to look for, you can find the corresponding files on any Linux distribution. SUSE is pretty good at sticking with the FHS, so other distributions are likely to look fairly similar, or at least will converge to look fairly similar. The Linux FHS is a distribution-neutral initiative to define standard directory names and filenames for important system files. Any Linux distribution that wants to be a good Linux citizen should follow this standard. Debian is another example of a distribution that does so. On Red Hat, the top-level rc script is /etc/rc.d/rc.
In the previous section, you saw how /etc/inittab invokes the script under a variety of circumstances with different numbers from 0 to 6 as arguments. The numbers correspond to runlevels, and each one causes the rc files to invoke a different set of scripts. So our next step is to find the scripts corresponding to each runlevel.
According to the FHS, scripts for each runlevel are stored in the directory /etc/init.d/rcN.d, where N is the runlevel being started. Thus, for runlevel 3, scripts in /etc/rc.d/rc3.d would be used. Again, slightly different conventions are the rule in other distributions.
Take a look in one of those directories; you will see a number of filenames of the form Snnxxxx or Knnxxxx where nn is a number from 00 to 99, and xxxx is the name of some system service. The scripts whose names begin with K are executed by /etc/rc.d/rc first to kill any existing services, and then the scripts whose names begin with S are executed to start new services.
The numbers nn in the names are used to enforce an ordering on the scripts as they are executed: scripts with lower numbers are executed before those with higher numbers. The name xxxx is simply used to help you identify to which system service the script corresponds. This naming convention might seem odd, but it makes it easy to add or remove scripts from these directories and have them automatically executed at the appropriate time by /etc/rc.d/rc. For customizing startup scripts, you'll find it convenient to use a graphical runlevel editor, such as KSysV in KDE (discussed later in this chapter). Some distributions also include a graphical runlevel editor as part of their administration tool.
For example, the script to initialize networking might be called S10network, while the script to stop the system logging daemon might be called K70syslog. If these files are placed in the appropriate /etc/init.d/rcN.d directories, /etc/init.d/rc will run them, in numerical order, at system startup or shutdown time. If the default runlevel of your system is 3, look in /etc/init.d/rc3.d to see which scripts are executed when the system boots normally.
Because the same services are started or stopped at different runlevels, the SUSE distribution uses symbolic links instead of repeating the same script in multiple places. Thus, each S or K file is a symbolic link that points to a central directory that stores startup or shutdown scripts for all services, typically /etc/init.d. On Debian and SUSE, the directory contains a script called skeleton that you can adapt to start and stop any new daemons you might write.
Knowing the location of a startup or shutdown script is useful in case you don't want to completely reboot or enter a different runlevel, but need to start or stop a particular service. Look in the init.d directory for a script of the appropriate name and execute it, passing the parameter start orstop. For example, on SUSE, if you want the Apache web server to be running but your system is in a runlevel that does not include Apache, just enter the following:
tigger# /sbin/init.d/apache start
Many distributions are set up such that the script /etc/init.d/boot.local is executed at the end of the boot process. You can edit this file to accomplish any peculiar or otherwise out-of-place system commands at boot time, or if you're not sure where else they should be executed. For shutting down, there is often the equivalent /etc/init.d/halt.local.
The next entry, labeled ca, is executed when the key combination Ctrl-Alt-Delete is pressed on the console. This key combination produces an interrupt that usually reboots the system. Under Linux, this interrupt is caught and sent to init, which executes the entry with the action field ofctrlaltdel. The command shown here, /sbin/shutdown -t3 -rf now, will do a "safe" reboot of the system. (See "Shutting Down the System," later in this chapter.) This way we protect the system from sudden reboot when Ctrl-Alt-Delete is pressed.
Finally, the inittab file includes entries that execute /sbin/mingetty for the first six virtual consoles. mingetty is one of the several getty variants available for Linux. These programs permit logins on terminals; without them the terminal would be effectively dead and would not respond when a user walked up and pressed a key or mouse button. The various getty commands open a terminal device (such as a virtual console or a serial line), set various parameters for the terminal driver, and execute /bin/login to initiate a login session on that terminal. Therefore, to allow logins on a given virtual console, you must be running getty or mingetty on it. mingetty is the version used on a number of Linux systems, but others use getty or agetty, which have a slightly different syntax. See the manual pages for getty, mingetty, and agetty on your system.
mingetty takes one argument, a device name. The port names for Linux virtual consoles are /dev/tty1, /dev/tty2, and so forth. mingetty assumes the given device name is relative to /dev. The baud rate for virtual consoles should generally be 38,400, which is why mingetty, unlike, for example,agetty, defaults to this value and does not require it to be explicitly specified.
Note that the action field for each mingetty entry is respawn. This means that init should restart the command given in the entry when the mingetty process dies, which is every time a user logs out.
Most of the time, you operate the system in multiuser mode so that users can log in. But there is a special state called single-user mode in which Unix is running but there is no login prompt. When you're in single-user mode, you're basically the superuser (root). You may have to enter this mode during installation if something goes wrong. Single-user mode is important for certain routine system administration tasks, such as checking corrupted filesystems. (This is not fun; try not to corrupt your filesystem. For instance, always shut down the system through a shutdowncommand before you turn off the power. This is described in the next section.)
Under single-user mode, the system is nearly useless; very little configuration is done, filesystems are unmounted, and so on. This is necessary for recovering from certain kinds of system problems; see "What to Do in an Emergency" in Chapter 27 for details.
Note that Unix is still a multiprocessing system, even in single-user mode. You can run multiple programs at once. Servers can run in the background so that special functions, such as the network, can operate. But if your system supports more than one terminal, only the console can be used. And the X Window System cannot run.
Shutting Down the System
Fortunately, shutting down the Linux system is much simpler than booting and startup. However, it's not just a matter of hitting the reset switch. Linux, like all Unix systems, buffers disk reads and writes in memory. This means disk writes are delayed until absolutely necessary, and multiple reads on the same disk block are served directly from RAM. This greatly increases performance, because disks are extremely slow relative to the CPU.
The problem is that if the system were to be suddenly powered down or rebooted, the buffers in memory would not be written to disk, and data could be lost or corrupted. The kernel flushes dirty buffers (ones that have been changed since they were read from the disk) back to disk every five seconds or so (depending on configuration) to prevent serious damage from occurring should the system crash. However, to be completely safe, the system needs to undergo a "safe" shutdown before rebooting. This will not only ensure that disk buffers are properly synchronized, but also allow all running processes to exit cleanly.
shutdown is the general, all-purpose command used to halt or reboot the system. As root, you can issue the command:
/sbin/shutdown -r +10
to cause the system to reboot in 10 minutes. The -r switch indicates the system should be rebooted after shutdown, and +10 is the amount of time to wait (in minutes) until shutting down. The system will print a warning message to all active terminals, counting down until the shutdown time. You can add your own warning message by including it on the command line, as in the following example:
/sbin/shutdown -r +10 "Rebooting to try new kernel"
You can also specify an absolute time to shutdown, as in:
/sbin/shutdown -r 13:00
to reboot at 1:00 p.m. Likewise, you can say:
/sbin/shutdown -r now
to reboot immediately (after the safe shutdown process).
Using the -h switch instead of -r will cause the system to simply be halted after shutdown; you can then turn off the system power without fear of losing data. If you specify neither -h nor -r, the system will go into single-user mode.
As we saw in "init, inittab, and rc Files," you can have init catch the Ctrl-Alt-Delete key sequence and execute a shutdown command in response to it. If you're used to rebooting your system in this way it might be a good idea to check that your /etc/inittab file contains a ctrlaltdel entry. Note that you should never reboot your Linux system by pressing the system power switch or the reboot switch on the front panel of your machine. Unless the system is flat-out hung (a rare occurrence), you should always use shutdown. The great thing about a multiprocessing system is that one program may hang, but you can almost always switch to another window or virtual console to recover.
shutdown provides a number of other options. The -c switch will cancel a currently running shutdown. (Of course, you can kill the process by hand using kill, but shutdown -c might be easier.) The -k switch will print the warning messages but not actually shut down the system. See the manual page for shutdown(8) if you're interested in the gory details.
A Graphical Runlevel Editor: KSysV
If you think that editing runlevels by copying symbolic links around is too arcane and error-prone, you may want to try a graphical runlevel editor. Your distribution most likely ships one, but if you have installed the KDE Desktop Environment, you probably have KSysV anyway.[*] You can start this program either from the K menu (as System → Service Configuration → KSysV in KDE's normal distribution) or by invoking ksysv on any command line.
If you are starting KSysV for the first time, it will ask you a few questions about your distribution so that it can determine the right location of your runlevel configuration files. Then it will show its main screen, as seen in Figure 17-1.
To the left, you can see the list of available services, and to the right of it are two lines of boxes; the upper line for entering runlevels, the lower line for leaving them. For each runlevel, one box per line is shown (unless you turn some runlevels off using the checkboxes in the status bar, which can be helpful if you only want to work on a few runlevels).
To add a service to a runlevel, simply use the mouse to drag the service name from the left to the box on the right. Don't forget to do this for both the Start and the Stop box. To remove an entry from a box, grab it and drag it to the waste bin in the lower-left corner. You can also click any entry in the runlevel boxes to configure it or to manually stop, start, or restart it immediately.
When you are done, use the menu entry File → Save Configuration to save your work. This will only be allowed, however, if you have started KSysV as root, as you will otherwise not have write access to the runlevel configuration files. But if you start KSysV from within KDE, it will ask you to supply the root password anyway and switch to superuser mode.
Figure 17-1. The KSysV main window
[*] The name comes from the fact that the current Linux booting system, as was described in the previous sections, comes from a family of Unix systems called System V. Long ago in Linux history, a different booting system that did not use runlevels was used, but then Linux distributions switched to the so-called SysV system.