/dev/sd#
were shuffled around and the kernel was no longer able to find its root partition on the expected device. Of course, having Linux failing to boot just because you happened to plug an extra drive sucks big time, so we want to fix that.The well known solution of course it to use UUIDs or labels, since these are fixed. However, while recent versions of LILO are supposed to support root partitions that are identified by UUID/Label, in practice, this doesn't work UNLESS you are using an initrd disk. I'm not sure who of LILO or the kernel is responsible for this new layer of "suck" (I'd assume the kernel, since the expectation is that LILO is using the dev mappings that are being fed by the kernel), but I can only say that there really are some areas of Linux that could still benefit from long awaited improvements...
Thus, to be able to use UUIDs or labels for your root partition in LILO, you must boot using an initrd. Worse, as previously documented, you will most likely need to compile a new kernel that embeds the initrd, lest you want to run into the following issue while running LILO:
Warning: The initial RAM disk is too big to fit between the kernel and the 15M-16M memory hole.
In practice (as also illustrated by this post), this means you will need to:
- Create an initrd cpio image that can be embedded into a kernel with:
cd /boot mkinitrd -c cd initrd-tree find . | cpio -H newc -o > ../initrd.cpio
- Recompile a kernel, while making sure that you have the
General Setup → Initial RAM filesystem and RAM disk (initramfd/initrd) support
selected, and then setGeneral Setup → Initramfs source file(s)
to/boot/initrd.cpio
.
- Edit your
/etc/lilo.conf
and add anappend = "root=UUID=<YOUR-DISK-GUID>"
to your Linux boot entry. An example of a workinglilo.conf
is provided below. Note that you probably also want to use a fixed IDs forboot=
, so that running LILO is also not dependent on the current /dev/sd# organization..
- Run LILO, plug drives around and watch in amazement as your system still boots the Linux partition regardless of how the drives are assigned
lilo.conf
:# Start LILO global section boot = /dev/disk/by-id/ata-ST3320620AS_ABCD1234 compact lba32 # LILO doesn't like same volume IDs of RAID 1 disk = /dev/sdb inaccessible default = Windows bitmap = /boot/slack.bmp bmp-colors = 255,0,255,0,255,0 bmp-table = 60,6,1,16 bmp-timer = 65,27,0,255 # Append any additional kernel parameters: append=" vt.default_utf8=1" prompt timeout = 35 # End LILO global section image = /boot/vmlinuz append = "root=UUID=2cc11aaf-f838-4474-9d9a-f3881569f97c" label = Linux read-only image = /boot/vmlinuz.rescue append = "root=UUID=2cc11aaf-f838-4474-9d9a-f3881569f97c" label = Rescue read-only other = /dev/sda # Windows doesn't go to S3 sleep and has issues with backup, # unless it sees its disk as first in BIOS... boot-as = 0x80 label = Windows other = /dev/disk/by-id/ata-ST3320620AS_ABCD1234-part4 label = OSXOh, and of course, don't forget to edit your
/etc/fstab
as required, if you still use /dev/sdX#
entries there.
I just did some experiments on this which hopefully sheds some light:
ReplyDelete- I normally build self-contained kernels which do not require an initrd
- using LABEL= in lilo.conf caused a panic as discussed above
- using LABEL= worked fine with a new initrd.gz created by "mkinitrd -c" and containing no modules at all
- using LABEL= worked fine on an older kernel with the above initrd.gz. Some complaints about "no modules" flashed by
The above were 64-bit kernels. Booting a 32-bit kernel revealed:
- using LABEL= with a 32-bit kernel failed with the 64-bit initrd.gz above. The panic message said
no working init found
So it seems that the LABEL= or UUID= functionality is relying on init (in the initrd) to mount the root partition
Have a fuller explanation now:
ReplyDeleteThe kernel doesn't understand LABEL or UUID, so init has to implement those.
But the kernel *does* understand PartUUID (partition UUID, as returned by blkid).
LILO doesn't know about PartUUID yet, so you have to use append, but I am now booting without an initrd using
append="apm=off root=PARTUUID=0aaac04b-04"
Definitive documentation at init/do_mounts.c lines 182 - 208 in the kernel source tree (line numbers as of 4.10.12)