The System Startup Daemon: init

11/29/2000

In the last few articles, we've learned how to view and manage running processes. Today, I'd like to take a look at how all those processes actually get started.

A lot of neat stuff happens when you boot up your computer into FreeBSD. I won't cover all the details here, as the FreeBSD handbook does an excellent job of explaining the bootup process. When you boot your computer, you have probably noticed that the kernel does a hardware probe and prints its results to your terminal. Once this probe is finished, the kernel starts two processes: process 0 (swapper) and process 1 (init).

The daemon responsible for process control initialization is init; without it, no other processes would be able to start. At boot time, init has two important jobs to do: First, it launches the startup scripts controlled by rc, then it initializes the terminals so they will be available for logins by users. Let's pick apart these functions, starting with rc:

whatis rcrc(8) - command scripts for auto-reboot and daemon startup

These scripts actually live in /etc/rc; normally, the configuration files found in /etc have a corresponding entry in section 5 of the manual so you can find out how to correctly make changes to the configuration file. However, if you type:

man 5 rc

you'll receive this message:

No entry for rc in section 5 of the manual

It seems a bit odd that a configuration file would be in section 8 of the manual, as this section contains system maintenance and operation commands, which are usually daemons. Let's take a closer look at this file to see what is going on here:

more /etc/rc

# System startup script run by init on autoboot
# or after single-user.
# Output and error are redirected to console by init,
# and the console is the controlling terminal.
# Note that almost all of the user-configurable behavior
# is no longer in # this file, but rather in /etc/defaults/rc.conf.
# Please check that file first before contemplating any changes
# here. If you do need to change this file for some reason, we
# would like to know about it.

OK, that's pretty clear; looks like we're not supposed to muck about with this file ourselves. There must be some pretty important stuff in here necessary for the proper bootup of our system. Let's skip through the file and look at some of its highlights to find out what actually is happening during this portion of startup. Note that init is recording all output and error messages to the terminal when the rc script is actually processed during bootup. (I'll tab in my comments; lines starting at the left are from the file /etc/rc)

One of the first things rc does is set a path variable so it can find the executables on your FreeBSD system:

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin

It then looks for the /etc/defaults/rc.conf and /etc/rc.conf files:

# If there is a global system configuration file, suck it in.
if [ -f /etc/defaults/rc.conf ]; then
. /etc/defaults/rc.conf
elif [ -f /etc/rc.conf ]; then
. /etc/rc.conf
fi

It then does a file system consistency check. If you've ever improperly shut down your FreeBSD system, you'll notice that it will complain at this point in the bootup process.

echo Automatic boot in progress...
fsck -p

Assuming that fsck did not encounter any problems, it will now mount your filesystems:

# Mount everything except nfs filesystems.
mount -a -t nonfs

Before any other daemons can be started, your CMOS clock must be adjusted so it will be understood by the kernel clock:

adjkerntz -i

The var directory is then cleaned up, and the boot messages are written to dmesg.boot:

# Clean up left-over files
# Clearing /tmp at boot-time seems to have a long tradition. It doesn't
# help in any way for long-living systems, and it might accidentally
# clobber files you would rather like to have preserved after a crash
# (if not using mfs /tmp anyway).
# See also the example of another cleanup policy in /etc/periodic/daily.
# Remove X lock files, since they will prevent you from restarting X11
# after a system crash.

Now rc is ready to start up some daemons, starting with syslogd and named:

# Start system logging and name service. Named needs to start before syslogd
# if you don't have a /etc/resolv.conf.

then inetd, cron, lpd, sendmail, sshd, and usbd:

# Now start up miscellaneous daemons that don't belong anywhere else

Then rc will update motd (message of the day) and print out "uname -m," which displays your type of architecture to the screen.

(end of /etc/rc)

Once we've reached the end of /etc/rc, rc's job is finished. Let's recap what happened here: init called the rc script which read several global and local configuration files in order to properly mount the filesystems and create an environment where the system daemons could be started. Your operating system is now up and running, but at this point, there is no environment where a user can actually interact with that operating system. This is where init's second important function kicks in.

The configuration file /etc/ttys will be read to determine which terminals need to be initialized. Unlike /etc/rc, this file is often edited by the superuser to ensure that the desired terminals will be initialized by init.