Section 6.3. The Init Process


6.3. The Init Process

Unless you are doing something highly unusual, you will never need to provide a customized initial process because the capabilities of the standard init process are very flexible. The init program, together with a family of startup scripts that we examine shortly, implement what is commonly called System V Init, from the original UNIX System V that used this schema. We now examine this powerful system configuration and control utility.

We saw in the previous section that init is the first user space process spawned by the kernel after completion of the boot process. As you will learn, every process in a running Linux system has a child-parent relationship with another process running in the system. init is the ultimate parent of all user space processes in a Linux system. Furthermore, init provides the default set of environment parameters for all other processes to inherit, including such things as PATH and CONSOLE.

Its primary role is to spawn additional processes under the direction of a special configuration file. This configuration file is usually stored as /etc/inittab. init has the concept of a runlevel. A runlevel can be thought of as a system state. Each runlevel is defined by the services enabled and programs spawned upon entry to that runlevel.

init can exist in a single runlevel at any given time. Runlevels used by init include runlevels from 0 to 6 and a special runlevel called S. Runlevel 0 instructs init to halt the system, while runlevel 6 results in a system reboot. For each run-level, a set of startup and shutdown scripts is usually provided that define the action a system should take for each runlevel. Actions to perform for a given runlevel are determined by the /etc/inittab configuration file, described shortly.

Several of the runlevels have been reserved for specific purposes in many distributions. Table 6-2 details the runlevels and their purpose in common use in many Linux distributions.

Table 6-2. Runlevels

Runlevel

Purpose

0

System shutdown (halt)

1

Single-user system configuration for maintenance

2

User defined

3

General purpose multiuser configuration

4

User defined

5

Multiuser with graphical user interface on startup

6

System restart (reboot)


The runlevel scripts are commonly found under a directory called /etc/rc.d/init.d. Here you will find most of the scripts that enable and disable individual services. Services can be configured manually, by invoking the script and passing one of the appropriate arguments to the script, such as start, stop, or restart. Listing 6-3 displays an example of restarting the nfs service.

Listing 6-3. NFS Restart

$ /etc/rc.d/init.d/nfs restart Shutting down NFS mountd:                           [  OK  ] Shutting down NFS daemon:                           [  OK  ] Shutting down NFS quotas:                           [  OK  ] Shutting down NFS services:                         [  OK  ] Starting NFS services:                              [  OK  ] Starting NFS quotas:                                [  OK  ] Starting NFS daemon:                                [  OK  ] Starting NFS mountd:                                [  OK  ]

If you have spent any time with a desktop Linux distribution such as Red Hat or Fedora, you have undoubtedly seen lines like this during system startup.

A runlevel is defined by the services that are enabled at that runlevel. Most Linux distributions contain a directory structure under /etc that contains symbolic links to the service scripts in /etc/rc.d/init.d. These runlevel directories are typically rooted at /etc/rc.d. Under this directory, you will find a series of runlevel directories that contain startup and shutdown specifications for each runlevel. init simply executes these scripts upon entry and exit from a runlevel. The scripts define the system state, and inittab instructs init on which scripts to associate with a given runlevel. Listing 6-4 contains the directory structure beneath /etc/rc.d that drives the runlevel startup and shutdown behavior upon entry to or exit from the specified runlevel, respectively.

Listing 6-4. Runlevel Directory Structure

$ ls -l /etc/rc.d total 96 drwxr-xr-x 2 root root  4096 Oct 20 10:19 init.d -rwxr-xr-x 1 root root  2352 Mar 16  2004 rc drwxr-xr-x 2 root root  4096 Mar 22  2005 rc0.d drwxr-xr-x 2 root root  4096 Mar 22  2005 rc1.d drwxr-xr-x 2 root root  4096 Mar 22  2005 rc2.d drwxr-xr-x 2 root root  4096 Mar 22  2005 rc3.d drwxr-xr-x 2 root root  4096 Mar 22  2005 rc4.d drwxr-xr-x 2 root root  4096 Mar 22  2005 rc5.d drwxr-xr-x 2 root root  4096 Mar 22  2005 rc6.d -rwxr-xr-x 1 root root   943 Dec 31 16:36 rc.local -rwxr-xr-x 1 root root 25509 Jan 11  2005 rc.sysinit

Each of the runlevels is defined by the scripts contained in the rcN.d, where N is the runlevel. Inside each rcN.d directory, you will find numerous symlinks arranged in a specific order. These symbolic links start with either a K or an S. Those beginning with S point to service scripts, which are invoked with startup instructions; those starting with a K point to service scripts that are invoked with shutdown instructions. An example with a very small number of services might look like Listing 6-5.

Listing 6-5. Example Runlevel Directory

lrwxrwxrwx 1 root root 17 Nov 25  2004 S10network -> ../init.d/network lrwxrwxrwx 1 root root 16 Nov 25  2004 S12syslog  -> ../init.d/syslog lrwxrwxrwx 1 root root 16 Nov 25  2004 S56xinetd  -> ../init.d/xinetd lrwxrwxrwx 1 root root 16 Nov 25  2004 K50xinetd  -> ../init.d/xinetd lrwxrwxrwx 1 root root 16 Nov 25  2004 K88syslog  -> ../init.d/syslog lrwxrwxrwx 1 root root 17 Nov 25  2004 K90network -> ../init.d/network

In this example, we are instructing the startup scripts to start three services upon entry to this fictitious runlevel: network, syslog, and xinetd. Because the S* scripts are ordered with a numeric tag, they will be started in this order. In a similar fashion, when exiting this runlevel, three services will be terminated: xinetd, syslog, and network. In a similar fashion, these services will be terminated in the order presented by the two-digit number following the K in the symlink filename. In an actual system, there would undoubtedly be many more entries. You can include your own entries for your own custom applications, too.

The top-level script that executes these service startup and shutdown scripts is defined in the init configuration file, which we now examine.

6.3.1. inittab

When init is started, it reads the system configuration file /etc/inittab. This file contains directives for each runlevel, as well as directives that apply to all run-levels. This file and init's behavior are well documented in man pages on most Linux workstations, as well as by several books covering system administration. We do not attempt to duplicate those works; we focus on how a developer might configure inittab for an embedded system. For a detailed explanation of how inittab and init work together, view the man page on most Linux workstations by typing man init and man inittab.

Let's take a look at a typical inittab for a simple embedded system. Listing 6-6 contains a simple inittab example for a system that supports a single runlevel as well as shutdown and reboot.

Listing 6-6. Simple Example inittab

   # /etc/inittab   # The default runlevel (2 in this example)   id:2:initdefault:   # This is the first process (actually a script) to be run.   si::sysinit:/etc/rc.sysinit   # Execute our shutdown script on entry to runlevel 0   l0:0:wait:/etc/init.d/sys.shutdown   # Execute our normal startup script on entering runlevel 2   l2:2:wait:/etc/init.d/runlvl2.startup   # This line executes a reboot script (runlevel 6)   l6:6:wait:/etc/init.d/sys.reboot   # This entry spawns a login shell on the console   # Respawn means it will be restarted each time it is killed   con:2:respawn:/bin/sh

This very simple[6] inittab script describes three individual runlevels. Each run-level is associated with a script, which must be created by the developer for the desired actions in each runlevel. When this file is read by init, the first script to be executed is /etc/rc.sysinit. This is denoted by the sysinit tag. Then init enters runlevel 2, and executes the script defined for runlevel 2. From this example, this would be /etc/init.d/runlvl2.startup. As you might guess from the :wait: tag in Listing 6-6, init waits until the script completes before continuing. When the runlevel 2 script completes, init spawns a shell on the console (through the /bin/sh symbolic link), as shown in the last line of Listing 6-6. The respawn keyword instructs init to restart the shell each time it detects that it has exited. Listing 6-7 shows what it looks like during boot.

[6] This inittab is a nice example of a small, purpose-built embedded system.

Listing 6-7. Example Startup Messages

... VFS: Mounted root (nfs filesystem). Freeing init memory: 304K INIT: version 2.78 booting This is rc.sysinit INIT: Entering runlevel: 2 This is runlvl2.startup #

The startup scripts in this example do nothing except announce themselves for illustrative purposes. Of course, in an actual system, these scripts enable features and services that do useful work! Given the simple configuration in this example, you would enable the services and applications for your particular widget in the /etc/init.d/runlvl2.startup script and do the reversedisable your applications, services, and devicesin your shutdown and/or reboot scripts. In the next section, we look at some typical system configurations and the required entries in the startup scripts to enable these configurations.

6.3.2. Example Web Server Startup Script

Although simple, this example startup script is designed to illustrate the mechanism and guide you in designing your own system startup and shutdown behavior. This example is based on busybox, which has a slightly different initialization behavior than init. These differences are covered in detail in Chapter 11.

In a typical embedded appliance that contains a web server, we might want several servers available for maintenance and remote access. In this example, we enable servers for HTTP and Telnet access (via inetd). Listing 6-8 contains a simple rc.sysinit script for our hypothetical web server appliance.

Listing 6-8. Web Server rc.sysinit

 #!/bin/sh  echo "This is rc.sysinit"  busybox mount -t proc none /proc  # Load the system loggers  syslogd  klogd  # Enable legacy PTY support for telnetd  busybox mkdir /dev/pts  busybox mknod /dev/ptmx c 5 2  busybox mount -t devpts devpts /dev/pts

In this simple initialization script, we first enable the proc file system. The details of this useful subsystem are covered in Chapter 9. Next we enable the system loggers so that we can capture system information during operation. This is especially useful when things go wrong. The last entries enable support for the UNIX PTY subsystem, which is required for the implementation of the Telnet server used for this example.

Listing 6-9 contains the commands in the runlevel 2 startup script. This script contains the commands to enable any services we want to have operational for our appliance.

Listing 6-9. Example Runlevel 2 Startup Script

 #!/bin/sh  echo "This is runlvl2.startup"  echo "Starting Internet Superserver"  inetd  echo "Starting web server"  webs &

Notice how simple this runlevel 2 startup script actually is. First we enable the so-called Internet superserver inetd, which intercepts and spawns services for common TCP/IP requests. In our example, we enabled Telnet services through a configuration file called /etc/inetd.conf. Then we execute the web server, here called webs. That's all there is to it. Although minimal, this is a working configuration for Telnet and web services.

To complete this configuration, you might supply a shutdown script (refer back to Listing 6-6), which, in this case, would terminate the web server and the Internet superserver before system shutdown. In our example scenario, that is sufficient for a clean shutdown.



Embedded Linux Primer(c) A Practical Real-World Approach
Embedded Linux Primer: A Practical Real-World Approach
ISBN: 0131679848
EAN: 2147483647
Year: 2007
Pages: 167

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net