2008-02-14

Advanced Grub Notes

I have been doing a lot of hacking with grub and linux bootloading this week, and I wanted to make some notes about some of the more esoteric things in grub, that I feel are rather poorly documented.

First of all, I had a hell of a time getting the 'savedefault' behaviour in grub working. It should work like this when you run grub on the linux commandline:
grub> savedefault --default=2 --once
This means, "next time you boot, use the 2nd boot option, but only once". It does this by recording some information inside /boot/grub/stage_2 or something.

I simply could not get this behaviour to work, and found that this was a 'better' way of doing things introduced by a patch. "grub-0.97-once.patch" is the name. I backed out this patch and rebuilt, which reverted to an older behaviour for saving default state.

The use-case for us is an unattended bios update. Set the system to boot the bios installer just once, so it will reboot, install the bios, reboot, boot linux again.

Now I use this grub config (in menu.lst) to make grub boot an alternate bootloader, just once:
default saved

title Linux
kernel /boot/vmlinuz ...

title Alternate
kernel /boot/memdisk
savedefault 0
State is now no longer saved in some binary format, it is saved in /boot/grub/default. Which is a text file, and on the first line is a number which is the default option to boot. Zero indexed. The format of this file is not documented. There is a standard tool for setting the contents of this file which the patch above removed, called grub-set-default. If you have this executable, you probably don't have the patch applied to your version.

Usage of grub-set-default is trivial:
$ grub-set-default 0
Easy.

Now the next thing I had trouble with was labels. I have a seriously large amount of machines that I maintain and create. One of the scripts that I have has the duty of figuring out what devices (/dev/sda1, etc) the partitions are on, and writing the fstab and grub configurations correctly.

So by using labels, I should be able to avoid having these scripts be dynamic.

First, labelling unlabelled drives, both ext3 and swap:
# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 1.5G 552M 856M 40% /
# cat /proc/swaps
Filename Type Size Used Priority
/dev/sda5 partition 136544 0 -1
# tune2fs -L / /dev/sda1
# swapoff /dev/sda5
# mkswap -L SWAP /dev/sda5
# swapon LABEL=SWAP
Then, in your grub configuration, you need to make your kernel line look like this:
kernel /boot/vmlinuz root=LABEL=/
initrd /boot/initrd.img
The initrd.img is absolutely essental. Without it you will not be able to boot, and you will get the message "VFS: Cannot open root device "LABEL=/" or unknown-block(0,0)". We didn't have an initrd for our kernel, and we were compelled to make one in order to get labels to work.

The last thing is the pesky grub way of saying /dev/sda1. In grubspeak you say (hd0,0). This is supposed to be a magic way of saying "the first harddrive". So you would expect that when you have a recent motherboard where you have a PATA controller that performs better when you add the magic kernel line "hda=none" to make the drives appear as /dev/sda instead of /dev/hda (and incidentally have 8 times the throughput) that grub would automatically figure that out.

But that's wrong. There is a file in /boot/grub/device.map that is specifically placed there to map from hd0 to /dev/hda. And that will screw things around.

The last thing I had to do when setting up grub in my now nearly-totally-static configuration, with a static fstab and static grub configuration, is setup grub like this:
rm /boot/grub/device.map
grub-install --no-floppy
rm /boot/grub/device.map
Running grub-install will automatically detect the devices and put them in those files. By removing the file you can cause grub to automatically detect everything at boot time.

If anyone has easier ways of doing any of the above, or reasons why any of that is totally insane, I'm interested.

No comments: