initrd
A file, key to the successful boot of many a linux system is the initrd image.
It used to be a simple gzipped loop filesystem, unpacked and mounted by commands similar to
gzip -dc initrd.img > initrd_unzipped.img
mount -o loop initrd_unzipped.img temp_dir
Then files can be tweaked inside ‘temp_dir’, the image is then updated by
umount temp_dir
gzip -9c initrd_unzipped.img > initrd.img
These days an initrd image tends to be a gzipped cpio archive, so the commands are a little different…
unpack
cd temp_dir
gzip -dc /boot/initrd.img | cpio -i
… and repack
cd temp_dir
find . | cpio -c -o | gzip -9 > /boot/initrd.img
Why would you want to do this?
Afterall there is a nice little command called mkinitrd which can do all this for you, even if you need extra modules
mkinitrd --preload=another_module_i_need /boot/initrd.img 2.6.18.8-xen
mkinitrd reads through the contents of your /etc/modprobe.conf for any modules that *may* be required at boot and creates an initrd relevant to the kernel you have specified (in my case a build of the 2.6.18 kernel with xen virtualisation support embedded).
Well, there are just some things this automated process cannot handle - the two most recent for me…
- Root filesystem stored on a software raid 10 device
- Xen virtual server with two loop filesystems acting as root on raid 1
These are both limitations to the way raidautorun appears to function, and in both cases I fixed them by using a statically linked version of mdadm
For the first one, raidautorun should be able to find the two (or more) mirror devices that make up each part of the stripe, but it will not do a second run to find the striped device. So unpacking the initrd and editing the init file found within (some older flavours of linux use an linuxrc file instead) to contain the following:
# make relevant md block devices
mknod /dev/md0 b 9 0
mknod /dev/md1 b 9 1
mknod /dev/md2 b 9 2
# assemble raid mirror devices
mdadm -A -f /dev/md0 /dev/sda1 /dev/sdb1
mdadm -A -f /dev/md1 /dev/sdc1 /dev/sdd1
# assemble striped device
mdadm -A /dev/md2 /dev/md0 /dev/md1
This assumes the mirrors are md0 (sda1 and sdb1) and md1 (sdc1 and sdd1)
The second one might seem a little obscure and you might even be wondering why on earth I’d want to do that - better to have the real file system on a mirror so that the VM doesn’t need to do this?
Well, I had some spare space on a non-raid machine - it makes an interesting experimental raid vm. I have two loop files (of the same size) that as far as the virtual machine is concerned are sda1 and sdb1 and are both mirror parts of device md0.
With this setup raidautorun completely misses their existence (maybe because there is no corresponding sda/sdb? I’m not sure) so again mdadm came to the rescue.
Machine virtualisation (xen being the current system I’m using) is a useful place to learn about the process of booting linux- the trials of testing something you are not sure about are so much easier, but it also has its own interesting quirks.