What I needed to do with Grub2 to change my boot disk
On my work machine I have been very slowly migrating away from a
pair of old drives to a pair of new drives. For quite a while the only thing the old drives have been used for
has been booting from and holding
/boot; today I finally removed the
single surviving old disk and moved to booting off the new disks. It
turned out to be somewhat more involved than I expected.
The initial state was
/dev/sda as the old drive with
/boot as a
/dev/sdc as the new drives with
/boot-n (the new version of
/boot) as a mirrored RAID array and
My first step (some time ago actually) was to run
install the boot blocks on
sdc, although I have no idea if
those work). Unfortunately I forgot to save the exact commands I used to
do this. My notes say that I bind-mounted
/boot-n on top of
during this process so that
grub2-install would see the right thing in
the right place but I'm not sure how I handled device mappings.
Today I changed my
/etc/fstab to fix up the mounts (basically
/boot), shut the machine down, pulled the
old drive, shuffled the cables around, and booted up. The machine
started Grub2 but then couldn't boot Linux, ultimately because it
couldn't find the kernel and initramfs. This happened because I
forgot to update grub.cfg to tell it the new location and UUIDs of
/boot. Although Grub2 could find the new
order to load grub.cfg, the various kernel stanzas in grub.cfg
re-specify where to find the kernel and initramfs with boiler plate
set root='hd0,msdos1' if [ x$feature_platform_search_hint = xy ]; then search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1 --hint='hd0,msdos1' bfe06079-ea84-49cb-a028-d5b1ad47cfba else search --no-floppy --fs-uuid --set=root bfe06079-ea84-49cb-a028-d5b1ad47cfba fi linux /vmlinuz-....
(The complexity of a Grub2
grub.cfg is why I'm not really fond
of Grub2. I'm not sure we need a shell script interpreter embedded
in the boot system, and if it has to be fully programmable I wish
they'd used a better language.)
/boot was no longer (MS-DOS) partition 1 or a filesystem with
that UUID, this failed and everything bombed out.
To get the machine booted I dropped into the Grub2 command line and used
ls command to see what was there (per the Fedora page on Grub2). After finding that I wanted
md/13' (I believe) I went back and changed the '
set root=...' line
to specify it, then told Grub2 to try booting. This worked, although
Grub2 warned me that it still couldn't find the particular UUID.
Fixing this permanently required revising
grub.cfg; I actually did
this twice, once the hard way and once the easy way. The hard way is to
blkid to look up the new
/boot's UUID then carefully edit all of
the stanzas to change the
set root=... bit to
md/13 and change the
UUID in the
search lines. While this worked I didn't think that all of
--hint-... bits were correct any more and they made me nervous.
The easy way to fix this is to use
grub2-mkconfig -o /tmp/foo and
then pick through
/tmp/foo for the official and proper way to do
all of this boiler plate. It turned out to be (for me):
search --no-floppy --fs-uuid --set=root --hint='mduuid/<md-uuid>' <fs-uuid>
grub2-mkconfig looked up the UUIDs for itself.)
(The really easy way would be to just use
grub.cfg, but I have an old-style
I happen to like and didn't want to have replaced with the new
grub2-mkconfig version. Also note that the grub.cfg that
grub2-mkconfig creates for you may look nothing like the grub.cfg that
the Fedora installer creates. This is a complete mess and I hope that
Fedora fixes it someday.)
I'm sure that I'm going to need to do this again sometime in the future.
In that future, the smart thing to do will be to update
before the initial reboot (after the final copy from the old
for obvious reasons). I'm not sure if
grub2-mkconfig would give the
right results (even with making the new
/boot the actual
clearly I can just look up the UUIDs by hand.
PS: no, I don't know why Grub2 and
grub.cfg don't have a final
fallback of 'where you got the grub.cfg from'. Probably it's for the
same reason that Grub2 needs a shell script interpreter.