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.