init

Although you may think that the init program must be very complicated, actually all it does is call the inittab file and follow the instructions therein.

The following descriptions are extracts from the man pages for "init":

Init is the parent of all processes. Its primary role is to create processes from a script stored in the file /etc/inittab. This file usually has entries which cause init to spawn gettys on each line that users can log in. It also controls autonomous processes required by any particular system.

RUNLEVELS

A runlevel is a software configuration of the system which allows only a selected group of processes to exist. The processes spawned by init for each of these runlevels are defined in the /etc/inittab file. Init can be in one of eight runlevels: 0-6 and S or s. The runlevel is changed by having a privileged user run telinit, which sends appropriate signals to init, telling it which runlevel to change to.

Runlevels 0, 1, and 6 are reserved. Runlevel 0 is used to halt the system, runlevel 6 is used to reboot the system, and runlevel 1 is used to get the system down into single user mode. Runlevel S is not really meant to be used directly, but more for the scripts that are executed when entering runlevel 1. For more information on this, see the manpages for shutdown(8) and inittab(5).

Runlevels 7-9 are also valid, though not really documented. This is because "traditional" Unix variants don't use them. In case you're curious, runlevels S and s are in fact the same. Internally they are aliases for the same runlevel.

BOOTING

After init is invoked as the last step of the kernel boot sequence, it looks for the file /etc/inittab to see if there is an entry of the type initdefault (see inittab(5)). The initdefault entry determines the initial runlevel of the system. If there is no such entry (or no /etc/inittab at all), a runlevel must be entered at the system console.

Runlevel S or s bring the system to single user mode and do not require an /etc/inittab file. In single user mode, a root shell is opened on /dev/console. ONLY When entering single user mode, init reads the console's ioctl(2) states from /etc/ioctl.save. If this file does not exist, init initializes the line at 9600 baud and with CLOCAL settings.

When init leaves single user mode, it stores the console's ioctl settings in this file so it can re-use them for the next single-user session.

When entering a multi-user mode for the first time, init performs the boot and bootwait entries to allow file systems to be mounted before users can log in. Then all entries matching the runlevel are processed.

CHANGING RUNLEVELS

After it has spawned all of the processes specified in /etc/inittab, init waits for one of its descendant processes to die, a powerfail signal, or until it is signaled by telinit to change the system's runlevel.

When one of the above three conditions occurs, it re-examines the /etc/inittab file.

New entries can be added to this file at any time. However, init still waits for one of the above three conditions to occur. To provide for an instantaneous response, the telinit Q or q command can wake up init to re-examine the /etc/inittab file.

When init is requested to change the runlevel, it sends the warning signal SIGTERM to all processes that are undefined in the new runlevel. It then waits 5 seconds before forcibly terminating these processes via the SIGKILL signal.

Note that init assumes that all these processes (and their descendants) remain in the same process group which init originally created for them. If any process changes its process group affiliation it will not receive these signals. Such processes need to be terminated separately.

TELINIT(Older technology look at "init q")

/sbin/telinit is linked to /sbin/init. It takes a one-character argument and signals init to perform the appropriate action. The following arguments serve as directives to telinit:

0,1,2,3,4,5 or 6 -- tell init to switch to the specified run level.

a,b,c -- tell init to process only those /etc/inittab file entries having runlevel a,b or c.

Q or q -- tell init to re-examine the /etc/inittab file.

S or s -- tell init to switch to single user mode.

U or u -- tell init to re-execute itself (preserving the state). No re-examining of /etc/inittab file happens. Run level should be one of Ss12345, otherwise request would be silently ignored.

BOOTFLAGS

It is possible to pass a number of flags to init from the boot monitor (e.g. LILO).

Init accepts the following flags:

-s, S, single

Single user mode boot. In this mode /etc/inittab is examined and the bootup rc scripts are usually run before the single user mode shell is started.

1-5

Runlevel to boot into.

-b, emergency

Boot directly into a single user shell without running any other startup scripts.

-a, auto

The LILO boot loader adds the word "auto" to the command line if it booted the kernel with the default command line (without user intervention). If this is found init sets the "AUTOBOOT" environment variable to "yes". Note that you cannot use this for any security measures - of course the user could specify "auto" or -a on the command line manually.

-z xxx

The argument to -z is ignored. You can use this to expand the command line a bit, so that it takes some more space on the stack. Init can then manipulate the command line so that ps(1) shows the current runlevel.

INTERFACE

Init listens on a fifo in /dev, /dev/initctl, for messages. Telinit uses this to communicate with init. The interface is not very well documented or finished. Those interested should study the initreq.h file in the src/ subdirectory of the init source code tar archive.

SIGNALS

Init reacts to several signals:

SIGHUP

Init looks for /etc/initrunlvl and /var/log/initrunlvl. If one of these files exist and contain an ASCII runlevel, init switches to the new runlevel. This is for backwards compatibility only! . In the normal case (the files don't exist) init behaves like telinit q was executed.

SIGUSR1

On receipt of this signals, init closes and re-opens its control fifo, /dev/initctl. Useful for bootscripts when /dev is remounted.

SIGINT

Normally the kernel sends this signal to init when CTRL-ALT-DEL is pressed. It activates the ctrlaltdel action.

SIGWINCH

The kernel sends this signal when the KeyboardSignal key is hit. It activates the kbrequest action.

Run Level versus programs

Examples of programs for specified run level taken from the /etc/inittab file:

  1. Always running in runlevels 2, 3, 4, or 5 and displays login (from getty) on console (tty1)

    1:2345:respawn:/sbin/getty 9600 tty1 
                            

  2. Always running in runlevels 2, 3, or 4 and displays login (getty) on console (tty2)

    2:234:respawn:/sbin/getty 9600 tty2 
                            

  3. Run once when switching to runlevel 3 and uses scripts stored in /etc/rc3.d/

    3:3:wait:/etc/init.d/rc 3 
                            

  4. 4.Shutdown the machine, with the relevant options when control-alt-delete is pressed

    ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now
                            

Default run level to go to as defined in /etc/inittab

id:3:initdefault:
            

By default the system must boot to run-level 3.

Sysinit:

si::sysinit:/etc/init.d/rcS
            

The run-level specified here is single-user mode and once reached it calls the "sysinit", which runs all the scripts in /etc/init.d/rcS.

As defined in Debian as /etc/init.d/rcS which then runs all the /etc/rcS.d/S* scripts and then symlinks to /etc/init.d/* and /etc/rc.boot/* (depreciated)

Example Debian /etc/rcS.d/ directory

Start up file Program Comment
README    
S05keymaps-lct.sh /init.d/keymaps-lct.sh  
S10checkroot.sh /init.d/checkroot.sh  
S20modutils /init.d/modutils  
S30checkfs.sh /init.d/checkfs.sh  
S35devpts.sh /init.d/devpts.sh  
S35mountall.sh /init.d/mountall.sh  
S35umsdos /init.d/umsdos  
S40hostname.sh /init.d/hostname.sh  
S40network /init.d/network  
S41ipmasq /init.d/ipmasq  
S45mountnfs.sh /init.d/mountnfs.sh  
S48console-screen.sh /init.d/console-screen.sh  
S50hwclock.sh /init.d/hwclock.sh  
S55bootmisc.sh /init.d/bootmisc.sh  
S55urandom /init.d/urandom  

A typical /etc/rc3.d/ directory

3:3:wait:/etc/init.d/rc 3 
            
Script Program called Comment
K25nfs-server /init.d/nfs-server  
K99xdm /init.d/xdm  
S10sysklogd /init.d/sysklogd  
S12kerneld /init.d/kerneld  
S15netstd_init /init.d/netstd_init  
S18netbase /init.d/netbase  
S20acct /init.d/acct  
S20anacron /init.d/anacron  
S20gpm /init.d/gpm  
S20postfix /init.d/postfix  
S20ppp /init.d/ppp  
S20ssh /init.d/ssh  
S20xfs /init.d/xfs  
S20xfstt /init.d/xfstt  
S20xntp3 /init.d/xntp3  
S89atd /init.d/atd  
S89cron /init.d/cron  
S99rmnologin /init.d/rmnologin  

When changing run levels to run level 3 or down from run level 3, use the scripts just once in the directory file /etc/init.d/rc 3. The scripts starting with an S* (Start) are used at bootup time and the scripts starting with a K* (Kill) are used at shutdown time.

Below are some of the files that would be in this directory /etc/rc3.d:

Each time a process terminates, init records the fact and the reason it died in /var/run/utmp and /var/log/wtmp, provided that these files exist. (See full desciption on Processes Chapter 6).

Getty and gettdefs

The file /etc/inittab contains the background programs that used to keep the system running. One of these programs is one getty process per serial port.

co:2345:respawn:/sbin/getty ttyS0 CON9600 vt102 respawn
            

Re-run the program if it dies. We want this to happen so that a new login prompt will appear when you log out of the console.

/sbin/getty ttyS0 CON9600 vt102 
            

In this case, we're telling the program called getty to connect to /dev/ttyS0 using the settings for CON9600.

This is a line that exists in /etc/gettydefs. This entry represents a terminal running at 9600bps.

The terminal is a later-model VT102 (later than vt100).

The getty program lives in /sbin and is used by /etc/inittab to call the /etc/gettydefs file as follows:

Define co in gettydefs:

# Serial console 9600, 8, N, 1, CTS/RTS flow control
co# B9600 CS8 -PARENB -ISTRIP CRTSCTS HUPCL # B9600 
SANE CS8 -PARENB -ISTRIP CRTSCTS HUPCL #@S @L login: #co
            

This means that the console is a serial console running at 9600 baud rate, 8 bits, No parity, 1 stop bit and carrier and receive flow control set up.

If the line does not manage to handshake then it refers to the end of line label of where to try next, in the case above it is looking at "co" again.

If you check the man pages you can find out all the labels that you can use in a gettydefs, definition.

As long as you define each label in the inittab correctly and then follow it up with a corresponding entry in the gettydefs file you can redefine any handshake between, terminals, consoles, printers and any other serial devices.

Each configuration line has the syntax:

<label>#<initial_flags>#<final_flags>#<login_prompt>#<next_label>
            

The <label> is referred to on the getty command line.

The <next_label> is the definition used if a RS-232 Break is sent. As the console is always 9600bps, this points back to the original label.

<initial_flags> are the serial line parameters used by getty.

<final_flags> are the serial line parameters set by getty before it calls login. You will usually want to set a 9600bps line, SANE terminal handling, eight data bits, no parity and to hang up the modem when the login session is finished.

The <login_prompt> for serial lines is traditionally the name of the machine, followed by the serial port, followed by login: and a space. The macro that inserts the name of the machine and the serial port may vary.

Dialling in from a modem

When using a modem, you will have top investigate and ultimately use the uugetty program. This program does file lock checking.

Modem entries in /etc/gettydefs

38400# B38400 CS8 # B38400 SANE -ISTRIP HUPCL #@S @L @B login: #19200
19200# B19200 CS8 # B19200 SANE -ISTRIP HUPCL #@S @L @B login: #9600
9600# B9600 CS8 # B9600 SANE -ISTRIP HUPCL #@S @L @B login: #2400
2400# B2400 CS8 # B2400 SANE -ISTRIP HUPCL #@S @L @B login: #1200
1200# B1200 CS8 # B1200 SANE -ISTRIP HUPCL #@S @L @B login: #300
300# B300 CS8 # B300 SANE -ISTRIP HUPCL #@S @L @B login: #38400
                

Add the following line to your /etc/inittab, so that uugetty is run on your serial port (use the information pertaining to your environment):

1:456:respawn:/sbin/uugetty ttyS1 F38400 vt100
                

The first lines in the preceding extract are typical for the system console. They set many initial and final flags that control how the console behaves.

console# B19200 OPOST ONLCR TAB3 BRKINT IGNPAR ISTRIP IXON IXANY 
PARENB ECHO ECHOE ECHOK ICANON ISIG CS8 CREAD # B19200 OPOST ONLCR
TAB3 BRKINT IGNPAR ISTRIP IXON IXANY PARENB ECHO ECHOE ECHOK ICANON
ISIG CS8 CREAD #Console Login: #console
                
[Note] Note

This entry would be one line in the /etc/gettydefs file, but because of display and printing issues we have entered linebreaks.

Using term with X (Some extracts from man pages)

You can use the term utility from within an X terminal window. X (or XFree86 with most versions of Linux) enables you to open a window specifically to run term.

Most of the X connection handling is with a utility called txconn. You must execute the txconn program on the remote machine (connected over a network, as X doesn't work with any reasonable degree of speed over a modem) and place it in the background as a daemon. When txconn goes to the background, it returns a message containing a display number that identifies the process:

Xconn bound to screen 11
                

When you connect to the remote txconn daemon from an X window, you use this number to identify the screen. You identify the screen by using the DISPLAY environment variable. If the binding were to screen 11, as shown in the preceding message, you would set the variable to

setenv DISPLAY remotename:11
                

Where remotename is the name of the remote machine (for the C shell). With the Bourne or Korn shell, you set the same environment variable with the following commands:

DISPLAY=remotename:11

export DISPLAY
                

When the term client is started in the local X window, it will connect to screen 11 on the remote machine. txconn knows about screen 11 on the remote so all X instructions will be transferred to the local machine's X window.

You can run the local machine with windows opening on the remote system's X session using txconn, but a better approach is to use the tredir command.

Running X sessions over a modem using txconn is possible, although the high amount of traffic X involves can bring even the fastest modem to a crawl. A local area network connection has enough speed to sustain X window traffic. A low-overhead version of X called LBX is available for some platforms that may help solve the overhead problem for modems. Also useful is a utility called sxpc, which compresses X protocol packets for transmission over modems. You can get sxpc with some versions of term, and it has worked well with 14.4kbps and higher speed modems, although performance is predictably slow.

Check gettydefs(5), stty(1), termio(3), agetty(8), mgetty(8), setserial(8) for further insight.