|< Free Open Study >|| |
In Chapter 3, the two common models for system startup scripts—the BSD model and the SysV model—were briefly mentioned. In Chapter 4, Red Hat Linux's model, which is based on the SysV approach, was discussed in detail. That chapter contains enough information to reach proficiency with the startup mechanism of any SysV-based system. This chapter, meanwhile, will discuss Slackware's startup script model. Since Slackware is very BSD-like, this chapter will provide detailed information on the BSD model of initialization scripts. Finally, this chapter assumes that you've already read the "System Startup Scripts" section in Chapter 4, and relies on comparisons to that material.
The first step toward understanding the BSD init scripts model used by Slackware is to list the relevant files. It's important to remember that fundamentally, both the SysV model used by Red Hat and the BSD model used by Slackware do the same things. Only the structure of the scripts varies between the two. This section will outline the following files used by the BSD model, and discuss how they compare to their SysV counterparts:
/etc/rc.d/rc.0 and /etc/rc.d/rc.6
/etc/rc.d/rc.inet1 and /etc/rc.d/rc.inet2
The primary directory containing all of these files is /etc/rc.d—just as with the SysV model.
Remember that the ultimate purpose of the init scripts is to configure the various services that are to be kicked off by the init global parent process. Since both Slackware and Red Hat use the same implementation of the base init program, they share the same starting point, which is the /etc/inittab file—the "init table."
As was discussed in Chapter 4, /etc/inittab contains lines that specify programs (usually shell scripts) that should be run when init enters a certain runlevel, or when various other events (such as a power failure) occur. The init program itself allows for there to be up to seven runlevels, numbered 0 through 6. A given Unix system can assign whatever meanings to these runlevels it desires, but traditionally runlevel 0 corresponds to system halt, and runlevel 6 corresponds to system reboot. The other runlevels are up to the system. Table 5-1 summarizes the meanings Slackware assigns to the runlevels.
Single-user (root-user only; typically used for system maintenance)
Unused, equivalent to runlevel 3
Standard multiuser mode (no X Window)
Multiuser mode with X desktop (via a graphical login)
Unused, equivalent to runlevel 3
Many of the lines in the standard Slackware /etc/inittab file are the same as or similar to the equivalent lines in the Red Hat version. Since those lines were discussed in Chapter 4, they won't be rehashed here. However, there are some lines that are different, and these lines will be dissected in detail. First, though, it's useful to make a few generalities.
One way to characterize the SysV model of init scripts is as a framework of scripts you can plug services into. In essence, each runlevel in /etc/inittab is configured to invoke the same script, and the script itself does the work of starting and stopping services appropriate to the new runlevel. The BSD model, however, doesn't have the same kind of extensive script framework. Instead, the BSD model defines a separate script for each runlevel, and /etc/inittab binds each script to the corresponding runlevel. This is really what goes in most of the lines in Slackware's /etc/inittab file that differ from the Red Hat version. Here are the relevant lines:
si:S:sysinit:/etc/rc.d/rc.S su:1S:wait:/etc/rc.d/rc.K rc:2345:wait:/etc/rc.d/rc.M
The first line defines the file /etc/rc.d/rc.S as a script to run when the system starts up, regardless of runlevel; the second line defines /etc/rc.d/rc.K as the script to run when entering runlevel 1 (which is single-user mode); the third line defines /etc/rc.d/rc.M as the script to execute for all the multiuser modes. These are the three key scripts used by Slackware to configure the system.
Later in the file, this series of lines appears:
c1:1235:respawn:/sbin/agetty 38400 tty1 linux c2:1235:respawn:/sbin/agetty 38400 tty2 linux c3:1235:respawn:/sbin/agetty 38400 tty3 linux c4:1235:respawn:/sbin/agetty 38400 tty4 linux c5:1235:respawn:/sbin/agetty 38400 tty5 linux c6:12345:respawn:/sbin/agetty 38400 tty6 linux x1:4:wait:/etc/rc.d/rc.4
These lines define six text "virtual consoles" that run on all of the multiuser runlevels, except runlevel 4 (that is, runlevels 2, 3, and 5). Runlevel 4 is the one that includes X; the last line of code starts X via the /etc/rc.d/rc.4 script. Recall that Red Hat's "multiuser with X" is runlevel 5. Thus, runlevel 5 on Red Hat Linux is more or less equivalent to runlevel 4 on Slackware Linux.
There is one small difference: under Slackware, only one of the consoles (tty6) is configured for runlevel 4, while under Red Hat Linux all six consoles are present and X is simply added on the seventh console. The reason is that Slackware treats runlevel 4 slightly differently than the way Red Hat treats its runlevel 5. Whereas Red Hat leaves all six virtual consoles running and simply adds X to the seventh console, Slackware disables all but one of the text consoles. This is, of course, really just "administrivia", but it's a subtle difference: Slackware is viewing runlevel 4 as a different "mode of usage", where Red Hat views runlevel 5 as simply starting X for convenience.
On any distribution, you can always start X by first logging in to one of the virtual text consoles and using the xinit command, so in the end starting X automatically is really just a convenience.
The /etc/rc.d/rc.S file is the sysinit script that does very basic work such as activating memory swap space, checking local disk partitions for errors, and mounting non-networked filesystems. It also configures hardware such as the system clock and random number seed, and configures kernel modules for device drivers (by invoking the rc.modules file, which is described later) and PCMCIA devices.
It also configures the serial port hardware via the rc.serial script. This file is pretty low-level and generally straightforward, and chances are you won't have to modify it very much. The important thing to understand is that since it handles very basic tasks, this file is configured to be invoked no matter what runlevel is being used. It may be worthwhile to scan through the file just to get a sense of the kinds of tasks it performs.
The /etc/rc.d/rc.K file is the script that is run when the system enters single-user mode (which is runlevel 1). The ".K" is short for "kill," because this script kills processes. It first terminates all currently running processes, and then simply switches to runlevel 1. The only processes that will be started in runlevel 1, therefore, are the tty consoles defined in /etc/inittab. This state obviously won't be all that useful (since it's not running any daemons or other processes) so it is primarily used for administrative mode.
The /etc/rc.d/rc.M file is the script responsible for configuring the system for all the multiuser modes. It picks up where the rc.S sysinit script leaves off; once rc.S has finished configuring the hardware and preparing the system basics like mounting filesystems, the rc.M script begins starting server processes.
The /etc/rc.d/rc.M script begins by starting the basic processes, such as the syslog (system logging) facility, the crond and atd daemons for scheduling tasks, and also sets a few parameters for the login consoles and CD-ROM drive. It also starts various daemons, such as the printer daemon (lpd), mail server (Sendmail), and web server. One of the most important tasks that rc.M performs is activating the network. It accomplishes this by calling two other scripts: rc.inet1 and rc.inet2. (These scripts are described separately, later in this section.)
Many daemons (such as lpd and sendmail) can sometimes be security risks; for more information, see the section on "Ensuring System Security" later in this chapter.
Finally, rc.M invokes other system scripts. Slackware, even though it primarily uses the BSD init scripts model, also supports scripts written for the SysV model. It supports these files through the script rc.sysvinit, which is described later in this section, in the "/etc/rc.d/rc.sysvinit" sub-section. The last step in the BSD model, meanwhile, is to invoke a script called rc.local, which is the same as the rc.local script discussed in Chapter 4 as part of the SysV model Red Hat Linux uses. This script simply contains whatever additional code the administrator requires for a particular system. It's intended to allow administrators to customize a system's configuration without having to make extensive modifications to the other init scripts. By default, this file is empty on Slackware (unlike under Red Hat Linux).
These are actually the same file: rc.0 is a symbolic link to rc.6. The script has a block in which it detects whether it was called for runlevel 0 (system halt) or runlevel 6 (system reboot). These runlevels are almost identical; they differ only in whether the system is automatically rebooted at the end. So, the two scripts are really a single file, to avoid duplicating code across two files.
In a certain sense, this file is just the "inverse" of /etc/rc.d/rc.M and /etc/rc.d/rc.S. That is, where rc.M has code that starts a variety of services, rc.6 stops them all. It also does a bit of work related to things that were initialized in the rc.S "sysinit" script, such as synchronizing the current time to the hardware clock, saving the random number seed, and deactivating the swap space. The rc.6 script also shuts down NFS (if it's running), turns off disk quotas and process accounting, and deactivates any RAID arrays that might be running. It unmounts local disks, and then reboots the system (if it was called as rc.6; if it was called as rc.0, it simply halts).
The /etc/rc.d/rc.modulesis file is responsible for configuring whatever kernel modules are required to support the system's hardware. The file actually contains lines for essentially every kernel module that is available with the Linux kernel. It has code to check for the presence of various kernel modules, and if they are found, it attempts to load them. It also has many lines for other kernel modules, which are commented out. Generally, an administrator would modify this file to activate support for the hardware for a given system. Most of the time, the appropriate lines simply need to be uncommented, but occasionally a line may need to be added. Red Hat Linux handles this functionality more or less automatically via the kudzu hardware detection utility, and so there is really no analog to this file.
The only other notable thing that rc.modules does is to call out to the rc.netdevice script. This script is responsible for configuring the device driver for the network card; usually it consists of a single line, which loads the kernel module for the network card (if one is present). This script is invoked from rc.modules, which is invoked from rc.S, and so the network device is guaranteed to be up before the network scripts (rc.inet1 and rc.inet2) are invoked.
These scripts are responsible for configuring the network for the host. They are invoked in order: rc.inet1 first, and rc.inet2 next. The rc.inet1 script brings up the various network interfaces, and either configures the IP addresses and routing tables, or requests the settings from a DHCP (Dynamic Host Configuration Protocol) server. (These settings are set by the administrator during installation.) The rc.inet1 script is roughly analogous to the /etc/rc.d/init.d/network file used by Red Hat Linux (discussed in Chapter 4).
The rc.inet2 script starts network-related processes and performs other network-related work, once the network is up and running. This script, for example, starts the inetd "superserver", the portmap daemon, and the Secure Shell (SSH) daemon for remote login, among other processes. This file also performs other tasks, such as mounting network filesystems. Some of the less common functions of rc.inet2 are commented out by default; for example, most systems don't need to run a Domain Nameserver (DNS) or router software, and so the corresponding lines, while present in the file as samples, are disabled by default.
The rc.inet2 file starts up most network-related servers. However, it doesn't handle quite everything that has to do with the network; it really only handles the basics. Some servers, such as the Sendmail server for SMTP and the Apache web server, are actually started directly from the rc.M file that calls rc.inet2.
Slackware Linux is based on the BSD init scripts model. However, some software packages come with pre-written scripts for starting and stopping (or otherwise managing) the software. If these scripts are written to use the SysV init framework, they might be a bit cumbersome to integrate into the BSD framework. As a convenience to administrators, Slackware Linux actually includes support for the SysV init scripts model. This support is kicked off by the /etc/rc.d/rc.sysvinit file, which itself is invoked by the other scripts. (The rc.M script invokes rc.sysvinit to start the SysV processes, and the rc.6 script invokes it to shut them down.)
Any SysV init scripts that are started via this file must be placed in the directory corresponding to the runlevel—the same naming convention used in standard SysV init systems (such as Red Hat Linux). For example, the directory for runlevel 3 would be /etc/rc.d/rc3.d . In general, most of the functionality discussed in Chapter 4 is supported by Slackware's SysV init scripts support. When entering a new runlevel, the kill scripts (scripts starting with the letter "K") are executed, and then all start scripts (which start with an S) are executed for the new runlevel.
Slackware's support for SysV init scripts is pretty complete, but not sophisticated; it's an afterthought or a convenience, and so it's really only useful for easily hooking in scripts that you may already have written, rather than for managing the system itself. To complete most low-level tasks, you'll have to edit the BSD init scripts directly, as discussed in the rest of this section.
There is a smattering of other files, mostly responsible for specific activities. For example, the rc.httpd file is responsible for starting up the Apache HTTP server. The rc.sshd script is responsible for starting the SSH server (which is OpenSSH on Slackware 8.0). These files are typically self-explanatory; a simple reading of them will reveal what they do, since they're not very complicated.
The reason that Red Hat chose to use the SysV model was to allow administrators to add software into the startup process without having to modify shell scripts. The SysV model will automatically pick up any scripts placed in it. The advantage of this approach is that it's easier to automate system administration; the downside is that there's more structure to the files, and that can make the learning curve more difficult. The BSD model, in contrast, is very straightforward: there's one script for one task, and it's a very "shallow" structure—you don't have to dig very deep to find the script you're looking for.
Modifying Slackware's startup process means understanding which scripts are responsible for what tasks. If you want to change the network settings, you have to edit rc.inet1. If you want to start a new server process or disable one of the defaults you would edit either rc.M or rc.inet2. If you just want to add a small script snippet to clear stale files on each reboot, you might put the code in rc.local. The simplicity of the BSD approach makes it easy to tell where and what to modify. Once you've read this section and taken a look through the scripts themselves, you'll be managing Slackware's startup process with the best of them.
The best way to understand how the BSD init scripts work together is to take a quick look at a typical boot process. We've already covered most of the actual contents of the script in the sections above, so we'll keep this section brief. In this example, we'll assume that the system is entering runlevel 4—normal multiuser mode with X.
When init starts, it processes /etc/inittab. It first encounters this line:
This line instructs init to execute the /etc/rc.d/rc.S script, no matter what runlevel is being entered. This script, in turn, does basic system configuration, and invokes the /etc/rc.d/rc.modules script to load appropriate device drivers. The rc.modules script, in turn, invokes /etc/rc.d/rc.netdevice to configure the ethernet (or other network) hardware separately.
The next line in the file configures a script to be executed for runlevel 1; since that's not the current runlevel, it is skipped. Next up is the /etc/rc.d/rc.M script, which is configured to execute for runlevels 2 through 5:
This script does the lion's share of the work in configuring the system. It activates the network (by invoking rc.inet1 and rc.inet2), configures things such as the system font and mouse (via rc.font and rc.gpm), and starts additional higher-level network servers. Finally, it activates any SysV scripts that may have been configured, by executing the rc.sysvinit script.
After executing the /etc/rc.d/rc.M script, init continues reading /etc/inittab. The next few lines define scripts to be run in response to various events, such as power failures or the "three finger salute" sequence (control-alt-delete) for rebooting the system. It also defines the scripts to be run on system halt and reboot (/etc/rc.d/rc.0 and /etc/rc.d/rc.6).
The last block of lines sets up the text consoles, as described in the section above on "/etc/inittab." However, since we're entering runlevel 4, the first five consoles are skipped. (Only tty6 is defined for runlevel 4.) The final line starts up X via the /etc/rc.d/rc.4 script, and is executed in this case since we're in runlevel 4.
That's pretty much all there is to the BSD init script model used by Slackware Linux. If you've read this whole section, you'll be able to bend Slackware to your will—or at least, bend its startup scripts. More importantly, if you've also read the equivalent section in Chapter 4, you'll now have exposure to both of the prominent models for init scripts on Unix-like systems in general. You might find some minor variants from system to system, but generally what you've learned will be applicable. This knowledge alone will probably prove useful on any number of occasions as you work with Unix systems. It might even be worth the price of this book by itself!
|< Free Open Study >|| |