How Linux finds the root filesystem at boot time
Between loading the kernel and mounting the actual root filesystem sits a step that stays invisible on most servers until it fails: the initramfs. Anyone running LVM, LUKS, or a custom storage setup needs to understand how dracut builds this minimal pre boot system, so that an unable to mount root error does not turn into hours of troubleshooting.
Table of Contents
- 1. Why the kernel needs an initramfs
- 2. Structure of an initramfs image
- 3. dracut: a modular tool for building the initramfs
- 4. Rebuilding the initramfs with dracut
- 5. Debugging unable to mount root
- 6. Debug options through rd kernel parameters
- 7. Adjustments for custom storage setups
- 8. dracut compared to initramfs-tools
- 9. Best practices for production use
- 10. Summary
- 11. FAQ
1. Why the kernel needs an initramfs
At boot time, the Linux kernel itself only contains a limited set of built in drivers and initially has no idea where the actual root filesystem lives. If root sits on an LVM volume, behind LUKS encryption, on software RAID, or even on a remote iSCSI target, the kernel simply lacks the knowledge to get there without an extra step.
The initramfs, an initial RAM filesystem, solves exactly this chicken and egg problem: it is a compressed cpio archive that the bootloader loads into memory together with the kernel, containing all the kernel modules and userspace tools needed to locate, decrypt, and mount the real root filesystem before the kernel switches over to it with switch_root.
Without an initramfs, every needed driver would have to be compiled directly into the kernel, forcing distributions into a single, massive kernel covering every conceivable hardware and storage combination. The initramfs instead allows a lean standard kernel that only loads the modules it actually needs at runtime, straight from the initramfs.
2. Structure of an initramfs image
An initramfs image is essentially a gzip or zstd compressed cpio archive containing its own minimal root filesystem: a small set of binaries such as busybox or systemd components, the relevant kernel modules for storage and filesystems, and configuration files and scripts that drive the actual boot sequence.
In a modern dracut based initramfs, systemd itself actually runs as PID 1 inside the initramfs, with specialized units for tasks like waiting on an LVM volume or prompting for a LUKS passphrase, instead of a simple shell script as used by older initramfs generators.
# List the contents of an initramfs image without unpacking it
lsinitrd /boot/initramfs-$(uname -r).img | head -40
# Show the kernel modules included in the image
lsinitrd /boot/initramfs-$(uname -r).img -m
# Show the dracut modules (feature blocks) included in the image
lsinitrd /boot/initramfs-$(uname -r).img | grep dracut-
3. dracut: a modular tool for building the initramfs
On RHEL, Fedora, SUSE, and by now many Debian derivatives, dracut has replaced the older initramfs generators and works modularly: every dracut module in /usr/lib/dracut/modules.d encapsulates support for a specific feature, such as lvm, crypt, network, or nfs, and only gets included when it is either auto detected or explicitly requested.
Configuration happens through /etc/dracut.conf and fragments in /etc/dracut.conf.d, where additional modules, drivers, or kernel command line options can be pinned permanently, without having to pass long command line parameters on every invocation.
# /etc/dracut.conf.d/10-storage.conf: force additional modules and drivers
cat <<'EOF' | sudo tee /etc/dracut.conf.d/10-storage.conf
add_dracutmodules+=" lvm crypt "
force_drivers+=" nvme megaraid_sas "
compress="zstd"
EOF
4. Rebuilding the initramfs with dracut
After changes to the storage configuration, such as a new LVM volume, an updated LUKS passphrase file, or an additional kernel module, the initramfs for the affected kernel needs to be rebuilt, otherwise the changes only take effect after manual intervention on the next boot. The command dracut -f overwrites the image for the currently running kernel, while an explicit kernel name also allows rebuilding for a different installed kernel.
For environments running several installed kernel versions, for example after a larger distribution update, dracut --regenerate-all rebuilds the initramfs images for every installed kernel in one pass, which is especially useful after changes that affect all kernels, such as a new force_drivers entry in the dracut configuration.
# Rebuild the initramfs for the currently running kernel
sudo dracut -f
# Rebuild the initramfs for a specific, already installed kernel
sudo dracut -f /boot/initramfs-5.14.0-570.el9.x86_64.img 5.14.0-570.el9.x86_64
# Rebuild the initramfs for every installed kernel version
sudo dracut --regenerate-all -f
5. Debugging unable to mount root
The message dracut Warning: Could not boot, or unable to mount root filesystem, usually drops into a minimal dracut emergency shell. The first thing to check inside that shell is journalctl, along with the output of lvm vgscan or cryptsetup status, to see whether the expected volume group or encrypted device is even visible before the actual root mount is attempted.
Common causes include an initramfs still referencing the old UUID after a reformat, a missing storage driver module after a hardware change, for example from virtio to a physical RAID controller, or an LVM volume that goes undetected inside the initramfs due to an incorrect filter configuration in lvm.conf.
# In the dracut emergency shell: check volume groups and devices
dracut:/# vgscan
dracut:/# lvm lvs
dracut:/# cryptsetup status luks-root
dracut:/# blkid | grep -i uuid
# Manually mount the root filesystem and continue booting
dracut:/# mount /dev/mapper/vg-root /sysroot
dracut:/# exit
6. Debug options through rd kernel parameters
dracut ships its own family of kernel parameters, all starting with rd., that are only evaluated during the early boot phase. rd.debug writes a detailed log file to /run/initramfs/rdsosreport.txt, rd.break pauses the boot process at a specific point and hands over an interactive shell, and rd.shell forces an emergency shell on every failure instead of an immediate kernel panic.
These parameters get added through the GRUB menu with the e key for the current boot only, and should not end up permanently in GRUB_CMDLINE_LINUX_DEFAULT, since they deliberately slow down the boot process and provide no value in a production environment without active troubleshooting underway.
# Temporarily extend the kernel line in the GRUB menu with debug parameters
rd.debug rd.break=pre-mount
# After boot: review the collected dracut debug log
less /run/initramfs/rdsosreport.txt
7. Adjustments for custom storage setups
For unusual storage combinations, such as root over iSCSI, root on software RAID with mdadm, or root over multipath on a SAN, dracut's automatic detection often is not enough and requires additional kernel parameters as well as explicitly enabled modules like network, iscsi, mdraid, or multipath.
For environments like these, a dedicated configuration fragment that permanently pins the required modules is worth setting up, instead of relying on dracut's automatic detection again after every kernel update, which does not always reliably find every dependency, particularly for network storage.
# /etc/dracut.conf.d/20-iscsi-root.conf: permanently support root over iSCSI
cat <<'EOF' | sudo tee /etc/dracut.conf.d/20-iscsi-root.conf
add_dracutmodules+=" network iscsi "
EOF
sudo dracut -f --kver $(uname -r)
8. dracut compared to initramfs-tools
Debian and Ubuntu historically rely on initramfs-tools instead of dracut, with their own set of commands: update-initramfs -u to rebuild the current image, and /etc/initramfs-tools/modules to explicitly add kernel modules. Functionally both tools cover the same job, but they differ noticeably in architecture, configuration syntax, and whether systemd runs inside the initramfs at all.
Anyone switching between Debian and RHEL based servers should keep the different command lines in mind: dracut -f roughly corresponds to update-initramfs -u, while lsinitrd has no direct counterpart under initramfs-tools, where manually unpacking the cpio archive is the only option instead.
9. Best practices for production use
After every kernel update, it is worth a quick check to confirm a fresh initramfs actually exists for the new kernel, since a missing or stale image reliably produces an unable to mount root error on the next boot. Most package managers call dracut automatically through a kernel post install hook, but a manual sanity check still does not hurt.
Before major storage changes, such as moving from a single disk to an LVM setup, a fresh initramfs should be built and ideally tested through a rescue console before rebooting the production server. Backing up the previous initramfs image under a different file name is a cheap safeguard against a failed rebuild.
| Command | Purpose | When to use it | Note |
|---|---|---|---|
| dracut -f | Rebuild the initramfs for the running kernel | After changes to storage or configuration | Overwrites the existing image without confirmation |
| dracut --regenerate-all -f | Rebuild the initramfs for every installed kernel | After distribution wide changes | Can take a while with many kernel versions installed |
| lsinitrd | Inspect an image's contents without unpacking it | Check whether a module is included | Use -m to list kernel modules specifically |
| rd.break / rd.debug | Pause the boot process or log it in detail | Troubleshooting unable to mount root | Set only temporarily through the GRUB menu |
| update-initramfs -u | Debian/Ubuntu equivalent of dracut -f | On systems using initramfs-tools | Different configuration syntax than dracut |
Mironsoft
Server administration, Docker hosts, and performance tuning
Linux servers nobody on the team really understands anymore?
We handle setup, hardening, and performance tuning of Linux servers and Docker hosts for Magento deployments, documented and traceable instead of grown and unclear.
Server Audit
Review the existing server configuration for security gaps and performance bottlenecks.
Docker Host Setup
Set up and secure production-ready Docker environments for Magento cleanly.
Monitoring & Tuning
Measure resource usage and tune systemd, kernel, and services with purpose.
10. Summary
initramfs and dracut
Purpose
A pre boot system loads storage drivers before the kernel finds the real root
Tool
dracut on RHEL/SUSE, initramfs-tools on Debian/Ubuntu
Rebuild after changes
dracut -f or dracut --regenerate-all -f
Troubleshooting
dracut emergency shell, rd.break and rd.debug kernel parameters