Yesterday I spent a fun couple of hours trying to figure out what kernel support is required for booting with a root=LABEL=xxx kernel command line parameter.
The "standard" way to specify the root partition is passing a kernel command line parameter such as "root=/dev/hda1". RedHat, YellowDog and possibly other distributions switched a few years ago to use "root=LABEL=xxx". Rather than telling the kernel to use e.g. the first partition on the first IDE disk (/dev/hda1), we tell it to use the partition that has a label of 'xxx', regardless of where it's located. How is it implemented, though?
- The kernel starts booting, and loads an initrd (initial ram disk). Normally, no initrd is required for a Linux kernel to boot. However, an initrd *is* required for root=LABEL=xxx support, since as we'll soon see, the initrd is what actually does the work.
- The kernel runs the 'linuxrc' script in the initrd. This script is interpreted by the 'nash' interpreter. One of the stages in the linux script is creation of the root device, via a nash directive.
- When the 'createRootDev' nash directive is called, and the
root=XXX kernel command line parameter starts with LABEL=xxx, nash
builds a translation table of labels to partitions. It does this by
- parsing the output of /proc/partitions to know which partitions are recognized on the machine.
- for each partition in /proc/partitions, open it as a raw device and look for an ext2/3 or xfs file system. If such a file system is found, get the label from the s_volume_name member of the superblock, and add this (label, partition) pair to the translation table.
- Once the table is built, find the (major, minor) pair of the root partition in it based on its label.
- Create a device file with these (major, minor) numbers, and mount it.
- Use pivot_root to make it the current root.
- At this stage the linuxrc ends, and boot continues, with the fs that has the label xxx mounted as the root fs.
At first, I kept looking for the code that deals with LABEL in the RH kernel sources, and couldn't find it. This was particularly annoying since I distinctly remember seeing it a couple of weeks ago. After an hour or so of digging, a light dawned on me, that I'm probably not looking in the right place. I opened up the nash code in emacs, and immediately found the code dealing with labels.