The Linux boot process is a very cool combination of hard-wired and
flexible steps that make it easy to customize the services that
are started on your system and the order in which they
Ubuntu Startup and Shutdown ProcessesNowadays, booting an Ubuntu Linux system involves watching a friendly splash screen display a variety of system status messages and progress bars as it proceeds through the various commands that are part of the boot, initialization, and startup processes. This is all well and good, but sometimes it’s nice to know what’s actually going on under the hood. It’s similarly interesting to know how your Ubuntu system performs an orderly shutdown, which is what happens when you select Username(up right) ➪ Shut Down. (Describing what happens when you do a disorderly shutdown by pulling the plug is much easier. The system’s off, but the boot process next time will be a tad slower as the system checks for filesystem problems and repairs everything that it can).
This post describes the general phases of the Linux boot process and any things that are specific to Ubuntu Linux. It then discusses how you can get detailed information about all of the processes executed when your system starts, so that you can look for ways to speed up your system’s boot process, and discusses upcoming improvements that will further speed up the boot process in general. Then we conclude with an explanation of what happens when you shut down your system, which is relatively short, because this is really just the reverse of the last stage of the boot process.
Overview of the Ubuntu Linux Startup Process
This section describes the process of booting an Ubuntu Linux system, from the time that you turn it on to the point at which your operating system is running. I’ve tried to provide a detailed description of the boot process for most of the hardware that is capable of running Linux, which means that some of the following subsections will not apply to all hardware. If you are running Ubuntu Linux on a desktop or server system that has an x86-compatible processor, all of the following &s are relevant.
The Boot Monitor or BIOS
When you first turn on a computer system, it loads a boot monitor or Basic Input/Output system (BIOS) from storage on the motherboard. This storage is usually a programmable read-only memory chip (PROM) or a section of flash memory that is present on the board.
The BIOS or boot monitor is a very low-level, hardware oriented application that does some basic hardware initialization, performs some amount of hardware testing and verification (often optional), waits for keyboard or console input for some predetermined period of time, and then usually begins to execute a set of predetermined instructions to load another program into memory. These instructions load another program into memory from a predetermined location such as a portion of flash memory or the Master Boot Record (MBR) of a storage device such as a hard drive or CD-ROM, and then specify the memory address at which to begin executing the program once it has been loaded successfully.On systems with limited hardware resources, such as many embedded systems, the program loaded into memory by a boot monitor is the Linux kernel.
However, the boot process is slightly more involved on most desktop and server computer systems. On these types of systems, an intermediate program is loaded into memory ---from the MBR--- that provides additional configuration and customization options for the boot process.
On modern x86, PPC, and SPARC systems, the program that is loaded into memory at this point is known as a boot loader, which is a configurable application that provides higher-level options for loading an operating system on the computer. The boot loader that is most commonly used on modern x86 systems (including 64-bit systems) is the Grand Unified Boot Loaders (GRUB) though some Linux distributions still use an older, simpler boot loader known as the Linux Loader (LiLo).
Desktop PPC and SPARC systems that run Linux do not use these boot loaders(GRUB, LILO), but instead load system-specific boot loaders that work with their boot monitors.
The Boot Loader
Boot loaders typically consist of two stages: a minimal first-stage boot loader and a more elegant, second-stage boot loader. The size of a first-stage boot loader is constrained by the size of the MBR on a storage device, which is a single sector (512 bytes). The first-stage boot loader therefore primarily contains enough information to locate and load the second-stage boot loader, which is where all the action is.
As mentioned earlier, Linux offers two boot loaders, LiLo and GRUB. The LiLo boot loader was developed long before GRUB, and does not understand Linux filesystem formats — it identifies its second-stage boot loader (/boot/boot.b) and other boot-related information through direct offsets into the device where these files are stored.
The GRUB boot loader, which is the boot loader used by Ubuntu, follows a similar process, but uses an intermediate step in the boot process, first loading what GRUB calls a stage 1.5 boot loader that understands a specific type of Linux filesystem, and can therefore load GRUB’s text-format configuration file directly from your machine’s root filesystem. GRUB provides many different stage 1.5 boot loaders as follows:
- e2fs_stage1_5, for booting from a partition containing an ext2 or ext3 filesystem
- fat_stage1_5, for booting from a partition containing a DOS or Microsoft Windows VFAT filesystem
- ffs_stage1_5, for booting from a partition containing a Berkeley Fast filesystem
- iso9660_stage1_5, for booting from a partition containing an ISO 9660 filesystem, such as a CD-ROM
- jfs_stage1_5, for booting from a partition containing a JFS filesystem
- minix_stage1, for booting from a partition containing a Minix filesystem
- reiserfs_stage1_5, for booting from a partition containing a ReiserFS filesystem
- ufs2_stage1_5, for booting from a partition containing a traditional Unix filesystem
- vstafs_stage1_5, for booting from a partition containing a Plan 9 VSTa filesystem
- xfs_stage1_5, for booting from a partition containing an XFS filesystem
The fundamental difference between LiLo and GRUB is whether they load boot loader configuration and menu data from a filesystem, or whether the location of this information needs to be built into the boot loader.A second-stage boot loader typically provides access to a menu that enables you to choose between different ways of loading an operating system on your computer. Both GRUB and LiLo can be configured to display this menu for a short period of time, to display it only in response to specific keyboard input (such as pressing the Escape key), or to not display it at all.
Though both boot loaders use a configuration file, you must rerun the LiLo command (/sbin/lilo) each time you modify LiLo’s configuration file (/etc/lilo.conf), so that LiLo can repackage information about available menu options and kernels into the boot.b file that it locates by a direct filesystem offset, and so that it can update the location of this file in the MBR. GRUB’s stage 1.5 boot loaders work around this problem by enabling GRUB to locate its configuration information and associated files in a filesystem. There is no need to rerun GRUB after modifying its configuration data.
Once your system boots Linux, you can modify the configuration of the boot loader to automatically display a menu by modifying the boot loader’s configuration file, which is either /etc/lilo.conf for LiLo or /boot/grub/menu.lst for GRUB.
Ubuntu Linux systems use the GRUB boot loader, so that’s the primary focus of this section. For more information about LiLo (which is still used by some other Linux distributions, such as Xandros Linux), see ,the FreshMeat project page for LILO.
By default, the GRUB boot loader on Ubuntu systems is configured to boot a default configuration without displaying a menu(that's not true in latest Ubuntu releases), but you can press the Escape key when GRUB first starts (do it quickly — you have five seconds) to display a menu that shows all of the available GRUB boot options. If you do not press Escape during the boot process, GRUB will automatically boot the default configuration that its file directs it to use.Some Linux distributions, such as Fedora Core, provide prettier GRUB menu screens than the one shown in Ubuntu (older releases). Who cares? You will have to interact with the GRUB menu if you set up a dual-boot machine and want to boot your other operating system for some odd reason, but other than that, GRUB boot menus should be something that you never need to see.
Each time that you install a newer version of the Linux kernel on your system, such as through the Update Manager, the package installation process automatically updates your GRUB configuration to boot the new kernel and associated files. The GRUB menu entry for the previous kernel is still available on the GRUB boot menu. If you experience problems with a new kernel on a system, you can reboot a previous kernel by pressing Escape during the GRUB boot process, using the arrow keys to select the kernel that you want to boot, and pressing Return.GRUB configuration files typically contain multiple definitions for ways to boot your system. Each set of related entries is referred to as a stanza, and looks like the following:
title Ubuntu 9.10, kernel 2.6.31-19-generic root (hd0,0) kernel /vmlinuz-2.6.31-19-generic root=/dev/hda1 ro quiet splash initrd /initrd.img-2.6.31-19-generic savedefault boot
Each line in a stanza begins with a keyword that identifies the aspect of the boot process that it described. In the preceding example, these entries have the following meanings:
- title: provides the name for this entry displayed on the grub menu
- root: identifies the absolute location of the runtime root filesystem using GRUB’s own nomenclature
- kernel: identifies the kernel to boot and provides command-line boot parameters for that kernel
- initrd: identifies an initial RAM disk or initial RAM filesystem image that should be loaded by the kernel during the boot process
- savedefault: identifies this entry as the default GRUB boot entry
- boot: tells GRUB to boot using the configuration described in the current stanza
Loading the Kernel
- A kernel specified in a GRUB stanza is typically a compressed kernel image that is loaded directly into memory. This compressed kernel is prefixed by some instructions that perform initial hardware and execution environment setup (stack definition, page table initialization, starting the swapper, and so on)
- Uncompress the kernel image into high memory, store any initial RAM disk or initial RAM filesystem in memory for subsequent access, and then begin execution of the uncompressed kernel.
- The kernel sets up interrupts, performs additional hardware initialization, and then uncompresses and mounts any initial RAM disk or filesystem that is found in the kernel image or is specified using GRUB’s initrd keyword.
- If an initial RAM disk or filesystem is found or specified, the system follows the sequence of events described in the next paragraph, “Loading and Using an Initial RAM Disk or RAM Filesystem.”
- If no initial RAM disk or initial RAM filesystem is found in the kernel identified using the initrd parameter, the kernel mounts the root filesystem identified on the command line using the disk identifiers specified in GRUB’s root entry, and then starts the standard system initialization process, as described later in this section in the section entitled “The Init Process.”
Loading and Using an Initial RAM Disk or RAM Filesystem
Many Linux systems use a special type of filesystem as part of the boot process, before actually mounting the non-transient storage devices that are attached to your system. These initial filesystems are optional, and come in two different flavors: an initrd (initial RAM disk) or initramfs (initial RAM filesystem).
On most desktop and server computer systems, these initial filesystems are typically used to load kernel modules, such as specialized device drivers that the kernel needs but which are not built into the kernel, and to perform specialized hardware and software initialization functions.On desktop and server systems such as Ubuntu Linux systems, an initial RAM disk or initial RAM filesystem is almost always a transient part of the boot process. On embedded Linux systems with sufficient memory, the initramfs or initrd might be the actual root filesystem used when Linux is running.
- Initial RAM disks are the traditional mechanism used (by many 2.6 and all earlier Linux kernels) to enable the kernel to load drivers and execute processes that must be available to boot successfully.
- Initial RAM disks are compressed files that provide an initial filesystem for use by the Linux kernel at boot time.
- Initial RAM disks are compressed files that contain an actual filesystem in a format such as ext2, romfs, and so on.
- Initial RAM disks are uncompressed into a pre-allocated portion of memory and are then mounted for use by the kernel. The primary problem with initial RAM disks is that they consume a substantial amount of system memory and, because they are actual block devices, require the kernel to contain drivers for whatever type of filesystem they use.
Using the file and directory cache as a filesystem substantially reduces the amount of memory required for the initial RAM filesystem because files and directories live in the kernel’s page and directory entry (dentry) cache, where they would be copied anyway if they were used from a filesystem located on a block device.
An initial RAM filesystem is an instance of the Linux tmpfs filesystem.
- Linux systems that boot with an initial RAM disk execute the file /linuxrc from that filesystem after uncompressing and mounting the filesystem. This file is typically a command file, but can also be a version of the /sbin/init program that follows the standard initialization process described later in this section in the & entitled “The Init Process.” (This is typically done when the initial RAM disk will be your runtime filesystem, as in embedded systems.)
- Linux systems that boot with an initial RAM filesystem execute the file /init from that filesystem after loading it into the file and directory entry cache. Like the /linuxrc file used with initial RAM disks, /init is typically a command file, but can also be a version of the init program that follows the standard initialization process described in the next section.
Comparing Initial RAM Disks and RAM-based Filesystems: Some of the more significant ways in which initial RAM disks and initial RAM filesystems differ are the following:On desktop and server systems that use physical root filesystems, the last step in the /linuxrc or /init instructions is to mount the real root filesystem (identified in the kernel or using the root= kernel boot parameter), begin using that root filesystem as the new root filesystem (by using a pivot_root or chroot command), and start the init process, as described in the next section.
The contents of an initial RAM disk or initial RAM filesystem differ based on the hardware, system capabilities, and type of Linux system that you are using.
- You do not need any special privileges to build an initial RAM filesystem file or a kernel that contains one. Building an initial RAM disk typically requires root privileges unless you do so using an external application such as the genext2fs application.
- Initial RAM disks (initrd) are compressed files containing a filesystem in a specific format such as ext2, romfs, cramfs, squashfs, and so on. Initial RAM filesystems (initramfs) are compressed archive files in the format used by the Linux/Unix cpio application.
- Initial RAM disks must be prepared outside the kernel and identified during the kernel build process if you want to link them directly into the kernel. Initial RAM filesystems can be prepared outside the kernel and identified during the kernel build process, but can also be automatically created during the kernel build process. Versions 2.6 and later kernels enable you to identify a directory that contains the files that you want to have in your initial RAM filesystem or a configuration file that describes their contents.
- Initial RAM disks allocate and require a fixed amount of memory that is specified when building the kernel, regardless of the actual size of the files and directories that they contain. Any space not used by files and directories in the initial RAM disk is completely wasted. Initial RAM filesystems are directly allocated in the kernel’s page and dentry cache, and therefore only require allocating the amount of memory that is required by the files and directories that they contain.
- You can easily add a new script or file to an initial RAM filesystem that is specified as an external file in GRUB by using the gunzip application to uncompress the cpio archive, using the cpio --append command to add the new file to the archive, and using the gzip command to recompress the archive. You should only do this for testing purposes, because your modification will go away the next time you build a kernel or receive an update. You can permanently add the file or script to future initial RAM filesystems that you build by adding that file or script to the directory or script pointed to by the CONFIG_INITRAMFS_SOURCE kernel configuration variable for your kernel.
- Initial RAM disks automatically execute the file /linuxrc from the RAM disk. Initial RAM filesystems automatically execute the file /init from the RAM filesystem. The /init file in an initramfs filesystem runs with process ID 1, just like the init process in a standard Linux system.
- Desktop Linux systems typically use these filesystems to provide loadable device drivers or mandatory system setup procedures that are required to proceed with the boot process.
- Embedded Linux systems often use initial RAM disks or initial RAM filesystems as their actual runtime filesystems in the absence of usable disk, flash, or compact Flash storage.Both initial RAM disks and initial RAM filesystems provide only transient storage that does not enable you to save files across system restarts, but initial RAM filesystems are much more efficient and place fewer requirements on the kernel.
The Init Process
After loading the kernel and mounting their runtime root filesystem, traditional Unix and Linux systems execute a system application known as the init (initialization) process, which is typically found in /sbin/init on Linux systems. Typically, the init process is process number 1 on the system, as shown in a process status listing produced using the ps command, and is therefore the ancestor of all other processes on your system.
The init process reads the file /etc/inittab to identify the way in which the system should boot and defines all of the other processes and programs that it should start.
The init binary is part of a package of applications known as the SysVInit-utils package. The SysVInit-utils package uses a package of related command scripts known as the initscripts package, to identify the processes that are started when a system boots into different run levels and the order in which they are started.Most desktop and server Linux systems use the concept of run levels to identify the applications that the system executes and the order in which they are executed. Different run levels are simply a way of defining a set of applications that the system administrator believes should be run when the system is being used in a certain way. For example, run level 1 is usually known as single-user mode, and is used for system maintenance. Only the core set of applications required for a system administrator to contact the system and perform maintenance tasks are running when the system is in run level 1. The run levels used by Ubuntu are the following:
- 0: halt
- 1: single-user
- 2: default multiuser run level on Ubuntu/Debian systems
- 3-5: other multiuser run levels, used for customized run levels
- 6: reboot
Most Linux distributions other than Ubuntu and other Debian-inspired distributions use run level 3 as the default, non-graphical multiuser run level. These distributions use run level 5 as the default graphical multiuser run level.Systems that use both the SysVInit-utils and initscripts packages boot in the following sequence:
- Once the kernel is loaded and begins executing from its runtime root filesystem, it invokes a process known as the /sbin/init (initialization) process, which reads the file /etc/inittab to identify the basic processes and programs that it should start.
- In the /etc/inittab file, the default run level for your system is identified with a line containing the string initdefault, as in the following example (In this case, the default run level is 2): id:2:initdefault:
- An additional entry in the /etc/inittab file identifies a command script that is run to initialize the system itself, as in the following example: si::sysinit:/etc/init.d/rcS
NOTE: On Ubuntu systems, the /etc/init.d/rcS command actually runs the /etc/init.d/rc command with an argument of S, which executes all of the scripts in the directory /etc/rcS.d -- that begin with an uppercase S--, as described in the rest of this section. On some other Linux distributions, the system initialization script is a single script to which you manually add any initialization commands that you want to run.
- After the system initialization script is run, Linux distributions that use the SysVInit-utils and initscripts packages then define what occurs when the system enters a specific run level. For example, a few lines later in the /etc/inittab file, you might see additional information about run level 2 in an entry like the following: l2:2:wait:/etc/init.d/rc 2
- This line specifies that when the system enters run level 2, the /etc/init.d/rc command will be executed with an argument of 2. This causes the rc (run command) command to execute all of the appropriate files located in the directory /etc/rc2.d. The files in this directory have names of the form SNNname or KNNname, and are usually executable shell scripts (or are links to a common set of scripts) that contain lists of other system commands to execute. Files beginning with the letter S are executed when the system starts a specified run level. Entries beginning with the letter K are executed when the system leaves a specified run level. Commands are executed in the numerical order specified by the number NN. The “name” portion of an entry is user-defined, but is generally evocative of the program or subsystem that the file starts.
- All device drivers have been initialized, local filesystems have been mounted, and networking is available after all of the S40* scripts have completed.
- The system clock has been set, NFS filesystems have been mounted (if any are listed in /etc/fstab or you use the automounter, which is started later), and all filesystems have been checked for consistency after all of the S60* scripts have been executed.
Using symbolic links rather than explicit startup and shutdown scripts for each run level makes it easy to add or remove services from a given run level without duplicating the master scripts, and leaves /etc/init.d as a single, central location where you can modify any of these scripts to propagate your changes to the startup/shutdown process for all of the associated run levels.As the last step of the startup process for any multiuse run level, the init process runs the script /etc/rc.local, which is provided so that you can customize the startup process for a specific machine without making general changes to the startup scripts and symbolic links for that machine. See “Optimizing the Ubuntu Boot Process,” later in this section, for a discussion of some applications that can help you manage the startup/shutdown scripts and links associated with different Ubuntu run levels.
Examining the Boot Process with Boot Chart
Boot chart, by Ziga Mahkovec, is an impressive and useful utility that monitors the boot process, creating data files that it uses to generate a graphical representation of your system’s boot process.
Boot chart isn’t installed by default on Ubuntu systems, but you can install it manually using either the Synaptic Package Manager or the apt-get utility. When installed on Ubuntu systems, Boot chart adds itself to the initial RAM filesystem used by your kernel to capture data about the boot process, and then adds a script to your runtime root filesystem’s startup process (/etc/init.d/stop-bootchart, symlinked to /etc/rc2.d/S99stop-bootchart) that processes the collected data and generates the graphical record of the boot/startup process.
On Linux distributions that do not yet use an initial RAM filesystem (but still use an initial RAM disk), you can still use Boot chart by installing it on your system and modifying the GRUB boot entry for your kernel to include an init=/sbin/bootchartd entry so that the system runs the Bootchart data collection script before starting the /sbin/init program and executing the normal sequence of startup scripts.Boot chart uses a Java application(or better pybootchartgui) to generate a Portable Network Graphics (PNG) graphics file in /var/log/bootchart. This file is named based on the day that it was created and a version number, so that multiple files created on the same day don’t overwrite each other. You can configure Boot chart to produce graphics in SVG or EPS formats (or to preserve the data files that it creates) by modifying the /etc/init.d/stop-bootchart script.
Not only is it really cool to have a graphical record of the boot process, but that graphical record can be very valuable in terms of helping you identify startup scripts that are running that you don’t want or need to run, extra invocations of system or X Window system processes, and so on. Boot chart adds very little overhead to your system’s startup process, but the view of the system startup process that it provides can be invaluable.
Optimizing the Ubuntu Boot Process
The & earlier in this section entitled “The Init Process” described how the /sbin/init process uses an entry in /etc/inittab for your system’s default run level to run scripts that start various services at boot time. You can manually customize the run levels at which various services start, but this is tedious at best. As you might expect, the Ubuntu repositories provide a number of applications that simplify editing the startup and shutdown scripts associated with different run levels.
Ubuntu comes with an application (System ➪ Administration ➪ Services (now on Startup applications)) that promises to provide coarse control over which services are started at boot time, but does not provide granular control over the run levels with which these services are associated or the sequence in which they are started. (This is odd because it used to do this. I guess that progress is not always forward.)
My two favorite tools for modifying the scripts started at various Ubuntu run levels are the following:
- sysv-rc-conf: An application that runs in any Ubuntu terminal application, such as an xterm or the GNOME Terminal. The SysV Runlevel Config application provides a simple interface for enabling or disabling services at various run levels, and includes on-screen help for its user interface.
- Boot-Up Manager: A graphical application that provides an excellent user interface for enabling and disabling startup/shutdown scripts at various run levels.
The Boot-Up Manager is by far the more interesting of these two applications (as long as you’re running an X Window system desktop or window manager). Installing this application adds the System ➪ Administration ➪ Boot-Up Manager menu item, which you can use to start the application. Like most administrative applications, you’ll need to supply your password to run this application. The Boot-Up manager requires a fair amount of time to start, as it must read and process every startup script in the /etc/init.d directory and must read every symbolic link in any of your /etc/rc directories. This additional startup time is worth it in terms of usability.
Once the Boot-Up Manager is running, it provides some basic information about each of the startup scripts that your system is running, which helps you make intelligent decisions about the services that you want to enable or disable. However, clicking the Advanced checkbox on its main dialog displays two additional tabs that provide access to the real power of the Boot-Up Manager. You can click either of these tabs to display more detailed information about the topic with which it is associated, or click the Summary tab to display the standard Boot-Up Manager screen. You can start or stop any existing service, remove it from the startup and shutdown sequence, or modify the sequence in which that script is executed during the startup or shutdown processes by right-clicking any entry in the Services tab to display the pop-up menu.
To change the sequence in which a script is executed during the startup and shutdown processes, select Change start/stop priority from the pop-up menu. (Identifying a script’s sequence number as its priority is somewhat misleading, but c’est le vie.)
After modifying these values, click OK to save your changes and return to the Services tab or click Cancel to return to the Services tab without making any changes. Any changes that you specify are made to your system immediately. (The current Boot-Up manager doesn’t update its internal display to use the new sequence number until the next time that you start the Boot-Up Manager, which is certainly a bug.) In addition to enabling you to modify the startup and shutdown scripts associated with various system services, clicking the Boot-Up Manager’s Advanced checkbox also displays a tab on which you can examine the startup and shutdown scripts that are run during the boot process through the system initialization script identified by the sysinit entry in your /etc/inittab file. Click the Startup and shutdown scripts tab to see a list of these other scripts and the part of the system startup or shutdown sequence that they are associated with.
Init, the Next Generation: The SysVInit process is well-known and well-established, but has been used for years without any substantial modifications. Its biggest problem is that all of the scripts that it executes are executed sequentially, which means that your system’s startup process can take much longer than it needs to, assuming that there are no major dependencies between startup scripts. Jimmy Wennlund’s initng (Init, Next generation) replacement for the standard /sbin/init process is a great step in the right direction, supporting parallel execution of startup scripts whenever possible. The InitNG program also enables you to collect additional statistics that may be useful to you when analyzing your system’s startup performance. See the InitNG home page, for more information about this project (and the source code). Anyway Ubuntu has adopted Upstart.
InitNG is actively under development and is still maturing, but you can experiment with it by building and installing it on your system, and then modify your GRUB kernel command line to include the statement init=/sbin/initng. This enables you to experiment with InitNG without risking any problems with your current, traditional initialization sequence.Because these scripts are associated with the core system initialization process, this dialog only enables you to see the scripts associated with the system initialization process. Attempting to deactivate any of these scripts displays the slightly irritating warning dialog. (You’ll notice that the Apply button is also deactivated on this tab.)
I am being kind by calling this warning dialog “slightly irritating,” because modifying your system’s startup and shutdown scripts in any way is an administrative task that requires some knowledge of what you’re doing. I’m sure that editing these scripts will be added in a future release of the Boot-Up Manager. This is open source, after all!
To accept and permanently apply any changes that you have made to various services, click the Boot-Up Manager’s Apply button before exiting, and then click OK.
The Ubuntu Linux Shutdown Process
To shut down your Ubuntu Linux system, you can select the System ➪ Administration ➪ Quit menu item or from (After Jaunty) User name(up right) ➪ shout down... begins the system shutdown process, which is essentially the opposite of the startup process.
- After selecting this item, the system logs you out, and the /sbin/init process begins to run the shutdown scripts associated with your current run level, which are the scripts beginning with the letter K in the /etc/rcNN.d directory, where NN is your current run level.
- The system then runs any shut-down scripts in the system initialization directory, and turns off your system.
The line in the /etc/inittab file that identifies what happens when the Control+Alt+Delete key combination is pressed is identified with the crtlaltdel keyword, and looks like the following on Ubuntu systems:
ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r nowThis command tells the system to run the /sbin/shutdown command with options that tell it to wait one second between sending a shutdown warning and actually terminating processes (-t1), use the /etc/shutdown.allow text file to determine the users that can shut down the system using this key combination (-a), to reboot after shutting down (-r), and to do everything now (now). For more detailed information about the /sbin/shutdown command, see the online reference information available for this command by typing the man shutdown command from any xterm or GNOME Terminal window. You should probably do this at least once before actually shutting down your system — one second isn’t a lot of time to read a man page during the actual shutdown process.