Dan Callaghan

Generating initramfs images for Linux

The general consensus seems to be that a separate /usr volume is no longer a supported configuration on modern Linux. I’ve always done it that way, and with my peculiar disk configuration it really makes the most sense, but it does cause problems (like when I broke my Exherbo installation by linking grep against libpcre). And I’ve been keen to try systemd as an init replacement, but it links against all sorts of things like libdbus, which live under /usr. Add to that the fact that in-kernel md array autodetection is no longer supported, and I decided it was time to bite the bullet and set up initramfs.

I tried Dracut, which seemed very promising, but all I got was cryptic errors when I booted with the initramfs image it generated for me. I started digging in, to try and figure out what was going wrong, but there is a lot of code in Dracut. Eventually I decided it would be simpler to write my own script, since I knew my requirements were straightforward (assemble md arrays, activate lvm volumes, mount root and /usr).

I followed a similar pattern to Dracut in my own script: it copies the files for the image from the live filesystem, and then drops in an /init script to do all the work. Along the way I discovered how little I knew about udev (I cribbed most of the /dev manipulation bits from Dracut). But after a night of hacking (and far too many reboots) I finally have a happily booting initramfs.

I’ve published the script as mkinitrd (there are about a million packages named mkinitrd floating around, I figured another wouldn’t hurt). If you happen to need an initramfs image for mounting lvm on md, give it a go!


Edit: It turns out I had my terminology confused: initrd (“initial ramdisk”) is an obsolete kernel feature where the init filesystem is mounted from an in-memory block device, whereas its successor initramfs (“initial ramfs”) unpacks a gzipped cpio archive into a tmpfs mount and uses that for initialisation. Where previously I had said initrd, I meant initramfs. And of course mkinitrd is not really an accurate name for my script, but I’m too lazy to change it.