Lead Image © Barmaliejus, Fotolia.com

Lead Image © Barmaliejus, Fotolia.com

Rebuilding the Linux ramdisk

A New Beginning

Article from ADMIN 55/2020
By
If your Linux system is failing to boot, the dracut tool can be a convenient way to build a new ramdisk.

After moving your hard disk to a new system, the Linux system suddenly fails to boot. Often this happens because of missing drivers in the ramdisk, which the kernel needs to boot the system. In this article, I take a closer look at the handling of the initramfs file and introduces dracut [1] as a practical helper.

Many users only see the initramfs (initial random access memory filesystem) archive file as yet another file in the boot directory. It is automatically created when a new kernel is installed and deleted again when the kernel is removed from the system. But this initial ramdisk plays an important role, since it ensures that the root filesystem can be accessed after the computer has been restarted, to be able to access all the tools that are necessary for the computer to continue booting.

The GRUB2 bootloader, used in most cases today, is responsible for loading the Linux kernel (vmlinuz) and a ramdisk (initramfs) into memory at boot time. The kernel then mounts the ramdisk on the system as a root volume and then starts the actual init process. On current Linux systems, this is typically systemd. The init process can then use the drivers and programs provided by initramfs to gain access to the root volume itself. The root volume is usually available on a local block device but can also be mounted over the network, if required. For this to work, all the required drivers must, of course, be available in the initramfs.

These can be drivers for LVM, RAID, the filesystem, the network, or a variety of other components. The details of this depend on the individual configuration of the system. For example, if the root filesystem is located on an encrypted partition, the tools for accessing it must be available within the ramdisk.

When installing a new kernel, the ramdisk is automatically created and installed based on the system properties. On RPM-based distributions, for example, the new-kernel-pkg tool is used; it is called automatically as part of the kernel installation. By default, the ramdisk resides alongside the kernel in the /boot directory, and a new entry for the bootloader is created so that, after a reboot, the new kernel loads with the appropriate initramfs.

You can view the contents of the disk with the cpio tool. The associated file is simply a cpio archive, but lsinitrd gives you a more elegant and convenient approach:

lsinitrd /boot/initramfs-$(uname -r).img | less

If you are only interested in the kernel drivers provided by this ramdisk, you can restrict the output:

lsinitrd /boot/initramfs-$(uname -r).img | grep -o '/kernel/drivers/.*xz'

The command in Listing 1 tells the tool to display only the available network card drivers.

Listing 1

Available Network Card Drivers

lsinitrd /boot/initramfs-$(uname -r).img | grep -o '/kernel/drivers/net/.*xz'
/kernel/drivers/net/ethernet/broadcom/bnx2x/bnx2x.ko.xz
/kernel/drivers/net/ethernet/broadcom/cnic.ko.xz
/kernel/drivers/net/mdio.ko.xz

Support from dracut

In some cases, you may now need to create a new ramdisk manually. For example, if you want it to support new hardware or allow access to a newly encrypted volume, you have no alternative but to create a new initramfs for the current kernel. The easiest way to do this is to use the dracut tool, which is a framework that provides specific functions within an initial ramdisk based on modules. On a Fedora system these modules are located in the /usr/lib/dracut/modules.d/ directory. For Linux veterans, dracut also offers a wrapper named mkinitrd, but it is far less flexible than calling dracut directly. To create a new initramfs archive, just run the following command in the simplest case:

dracut --force /boot/initramfs-$(uname -r).img

The tool uses host-only mode by default and overwrites the existing initramfs file if the --force option is set. In this mode, dracut only uses the modules and drivers needed for the operation of the local system. If you plan to use the hard disk in a new system in the future, disable host-only mode as follows:

dracut --no-hostonly /boot/initramfs-$(uname -r)-new.img

The fact that dracut now writes far more data into the initramfs file is easily seen by comparing the sizes of the two files (Listing 2).

Listing 2

File Size Comparison

ls -ls /boot/initramfs-$(uname -r)*.img
24350 -rw-------. 1 root root 24932655 Apr 16 16:01 /boot/initramfs-4.20.10-200.fc29.x86_64.img
69242 -rw-------. 1 root root 70901695 Apr 16 16:04 /boot/initramfs-4.20.10-200.fc29.x86_64-new.img

The following command shows which modules – and thus functions – dracut provides:

dracut --list-modules

If you want to use a new ramdisk on a system on which the Clevis encryption framework is required to enable access to the root partition, the matching dracut module needs to be included in the initramfs file. The output from dracut --list-modules should first confirm that dracut is familiar with the Clevis module. If this is the case, include the module in the initramfs archive as follows:

dracut --add clevis /boot/initramfs-$(uname -r)-clevis.img

The following call should confirm that the files belonging to the Clevis module are now part of the initramfs:

lsinitrd /boot/initramfs-$(uname -r)-clevis.img|grep clevis

To include a specific kernel driver in the initramfs, you can use the command:

dracut --add-drivers bnx2x /boot/initramfs-$(uname -r)-bnx2x.img

Here, too, the call to lsinitrd should confirm that the drivers are in place in the archive. Which drivers or modules are required, of course, depends on the system on which the initramfs is to be used.

By default, dracut always creates an initramfs archive for the kernel currently in use. In some cases, it may be necessary to create the archive file for a different kernel version. This is easily done if the desired kernel version is specified with the --kver option when calling dracut (Listing 3).

Listing 3

Specify Kernel Version

dracut --kver 3.10.0-957.el7.x86_64 /boot/initramfs-$(uname -r)-other-kernel.img
ls -l /boot/initramfs-3.10.0-957.el7.x86_64.img
-rw-------. 1 root root 22913501 Apr 14 11:00 /boot/initramfs-3.10.0-957.el7.x86_64.img

Troubleshooting the Shell

If the system does not boot as usual and access to the root volume is not possible, dracut provides a shell for troubleshooting, if required. It is a good idea to make the following changes to the bootloader configuration to facilitate troubleshooting. In the bootloader configuration you need to remove the rhgb and quiet entries, if present, to ensure that messages are displayed on the screen when booting.

Additionally, add the rd.shell and rd.debug entries to the kernel line of the bootloader so that dracut starts a corresponding shell in case of an error and outputs further debug messages. The dracut tool also writes the messages to the /run/initramfs/rdsosreport.txt file. Both changes can be made either statically in the bootloader configuration file or by dynamically editing the boot menu entry.

Conclusions

Thanks to dracut, all the major Linux distributions provide a framework for creating an initial ramdisk. The framework is very flexible, supports booting a system from many different sources, and enables block device abstractions like RAID, LVM device mapper, FCoE, iSCSI, NBD, and NFS. Thanks to its modular structure, the tool can be easily combined with other frameworks to enable, say, automatic decryption of LUKS volumes through Clevis integration.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy ADMIN Magazine

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

comments powered by Disqus