The initrd Interface of systemd
systemd supports both initrd and initrd-less boots. If an initrd is used it is a good idea to pass a few bits of runtime information from the initrd to systemd in order to avoid duplicate work and to provide performance data to the administrator. In this page we attempt to roughly describe the interfaces that exist between the initrd and systemd. These interfaces are currently used by dracut and the ?ArchLinux initrds.
- The initrd should mount /run as a tmpfs and pass it pre-mounted when jumping into the main system when executing systemd. The mount options should be mode=755,nodev
- It's highly recommended that the initrd also mounts /usr (if split off) as appropriate and passes it pre-mounted to the main system, to avoid the problems described in Booting without /usr is Broken.
- In the $RD_TIMESTAMP environment variable the initrd shall pass the monotonic and realtime timestamp when execution of the initrd began. This is then used by systemd to estimate the time that is spent in the kernel initialization, the initrd initialization and the main system initialization at boot. The monotonic and realtime timestamps shall be formatted as ASCII values of usecs, separated by a space character. The /lib/systemd/systemd-timestamp tool will generate a properly formatted timestamp for you, consider adding it to your initrd.
- If the file /run/initramfs/root-fsck exists systemd will skip the root file system check. It is recommended that the initrd completes the root fsck before mounting the root file system, using this file to inform systemd not to repeat the step. The initrd should write the exit code of the fsck process into the file, in order to inform the main OS about the result of the file system check.
- If the executable /run/initramfs/shutdown exists systemd will jump back into the initrd on shutdown. /run/initramfs should be a usable initrd environment to which systemd will pivot back and the "shutdown" executable in it should be able to detach all complex storage that for example was needed to mount the root file system. It's the job of the initrd to set up this directory and executable in the right way so that this works correctly.
- Storage daemons run from the initrd should follow the the guide on systemd and Storage Daemons for the Root File System to survive properly from the boot initrd all the way to the point where systemd jumps back into the initrd for shutdown. One last clarification: we use the term initrd very generically here describing any kind of early boot file system, regardless whether that might be implemented as an actual ramdisk, ramfs or tmpfs. We recommend using initrd in this sense as a term that is unrelated to the actual backing technologies used.
Oh, and one last question before closing: instead of implementing these features in your own distro's initrd, may I suggest just using Dracut instead? It's all already implemented there!
Using systemd inside an initrd
It is also possible and recommended to implement the initrd itself based on systemd. Here are a few terse notes:
- Provide /etc/initrd-release in the initrd image. The idea is that it follows the same format as the usual /etc/os-release but describes the initial RAM disk implementation rather than the OS. systemd uses the existence of this file as a flag whether to run in initial RAM disk mode, or not.
- When run in initrd mode, systemd and its components will read a couple of additional command line arguments, which are generally prefixed with rd.
- To transition into the main system image invoke "systemctl switch-root".
- The switch-root operation will result in a killing spree of all running processes. Some processes might need to be excluded from that, see the guide on systemd and Storage Daemons for the Root File System.
