dracut {mainversion}
====================
:author: Harald Hoyer
:email: harald@profian.com
:revnumber: {version}
:language: bash

= Introduction
This section is a modified version of
http://en.wikipedia.org/wiki/Initrd which is licensed under the
Creative Commons Attribution/Share-Alike License.

== Definition
An _initial ramdisk_ is a temporary file system used in the boot process of the
Linux kernel. _initrd_ and _initramfs_ refer to slightly different schemes for
loading this file system into memory. Both are commonly used to make
preparations before the real root file system can be mounted.

== Rationale
Many Linux distributions ship a single, generic kernel image that is intended to
boot as wide a variety of hardware as possible. The device drivers for this
generic kernel image are included as loadable modules, as it is not possible to
statically compile them all into the one kernel without making it too large to
boot from computers with limited memory or from lower-capacity media like floppy
disks.

This then raises the problem of detecting and loading the modules necessary to
mount the root file system at boot time (or, for that matter, deducing where or
what the root file system is).

To further complicate matters, the root file system may be on a software RAID
volume, LVM, NFS (on diskless workstations), or on an encrypted partition. All
of these require special preparations to mount.

Another complication is kernel support for hibernation, which suspends the
computer to disk by dumping an image of the entire system to a swap partition or
a regular file, then powering off. On next boot, this image has to be made
accessible before it can be loaded back into memory.

To avoid having to hardcode handling for so many special cases into the kernel,
an initial boot stage with a temporary root file system
—now dubbed early user space— is used.  This root file system would contain
user-space helpers that would do the hardware detection, module loading and
device discovery necessary to get the real root file system mounted.

== Implementation
An image of this initial root file system (along with the kernel image) must be
stored somewhere accessible by the Linux bootloader or the boot firmware of the
computer. This can be:

* The root file system itself
* A boot image on an optical disc
* A small ext2/ext3/ext4 or FAT-formatted partition on a local disk
  (a _boot partition_)
* A TFTP server (on systems that can boot from Ethernet)

The bootloader will load the kernel and initial root file system image into
memory and then start the kernel, passing in the memory address of the image.

Depending on which algorithms were compiled statically into it, the kernel can
currently unpack initrd/initramfs images compressed with gzip, bzip2 and LZMA.

== Mount preparations
dracut can generate a customized initramfs image which contains only whatever is
necessary to boot some particular computer, such as ATA, SCSI and filesystem
kernel modules (host-only mode).

dracut can also generate a more generic initramfs image (default mode).

dracut's initramfs starts only with the device name of the root file system (or
its UUID) and must discover everything else at boot time. A complex cascade of
tasks must be performed to get the root file system mounted:

* Any hardware drivers that the boot process depends on must be loaded. All
kernel modules for common storage devices are packed onto the initramfs and then
udev pulls in modules matching the computer's detected hardware.

* On systems which display a boot rd.splash screen, the video hardware must be
initialized and a user-space helper started to paint animations onto the display
in lockstep with the boot process.

* If the root file system is on NFS, dracut does then:
** Bring up the primary network interface.
** Invoke a DHCP client, with which it can obtain a DHCP lease.
** Extract the name of the NFS share and the address of the NFS server from the
lease.
** Mount the NFS share.

* If the root file system appears to be on a software RAID device, there is no
way of knowing which devices the RAID volume spans; the standard MD utilities
must be invoked to scan all available block devices with a raid signature and
bring the required ones online.

* If the root file system appears to be on a logical volume, the LVM utilities
must be invoked to scan for and activate the volume group containing it.

* If the root file system is on an encrypted block device:
** Invoke a helper script to prompt the user to type in a passphrase and/or
insert a hardware token (such as a smart card or a USB security dongle).

* Create a decryption target with the device mapper.

dracut uses udev, an event-driven hotplug agent, which invokes helper programs
as hardware devices, disk partitions and storage volumes matching certain rules
come online. This allows discovery to run in parallel, and to progressively
cascade into arbitrary nestings of LVM, RAID or encryption to get at the root
file system.

When the root file system finally becomes visible:

* Any maintenance tasks which cannot run on a mounted root file system
are done.
* The root file system is mounted read-only.
* Any processes which must continue running (such as the rd.splash screen helper
and its command FIFO) are hoisted into the newly-mounted root file system.

The final root file system cannot simply be mounted over /, since that would
make the scripts and tools on the initial root file system inaccessible for any
final cleanup tasks. On an initramfs, the initial root file system cannot be
rotated away. Instead, it is simply emptied and the final root file system
mounted over the top.

If the systemd module is used in the initramfs, the ordering of the services
started looks like <<dracutbootup7>>.

== Dracut on shutdown

On a systemd driven system, the dracut initramfs is also used for the shutdown
procedure.

The following steps are executed during a shutdown:

* The system starts to shut down
* ``$prefix/lib/systemd/system/sysinit.target.wants/dracut-shutdown.service``
  gets its ``ExecStop`` target triggered.
* ``dracut-shutdown.service`` executes
  ``/usr/lib/dracut/dracut-initramfs-restore`` which unpacks the initramfs to
  ``/run/initramfs``
* systemd kills all processes
* systemd tries to unmount everything and mounts the remaining read-only
* systemd checks if there is a ``/run/initramfs/shutdown`` executable
* if yes, it does a pivot_root to ``/run/initramfs`` and executes ``./shutdown``.
  The old root is then mounted on ``/oldroot``.
  ``/usr/lib/dracut/modules.d/99shutdown/shutdown.sh`` is the shutdown executable.
* shutdown will try to unmount every ``/oldroot`` mount and calls the various
  shutdown hooks from the dracut modules

This ensures, that all devices are disassembled and unmounted cleanly.

= User Manual

:leveloffset: 1
include::dracut.8.adoc[]

:leveloffset: 1
[[dracutconf5]]
include::dracut.conf.5.adoc[]

[[dracutcmdline7]]
include::dracut.cmdline.7.adoc[]

[[lsinitrd1]]
include::lsinitrd.1.adoc[]

= Developer Manual

:leveloffset: 1
[[dracutmodules7]]
include::dracut.modules.7.adoc[]

[[dracutbootup7]]
include::dracut.bootup.7.adoc[]

:leveloffset: 0
[appendix]
License
-------
This work is licensed under the Creative Commons Attribution/Share-Alike
License. To view a copy of this license, visit
http://creativecommons.org/licenses/by-sa/3.0/ or send a letter to Creative
Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
