If you have a linux VPS server hosted at a cloud provider you may find that you’re stuck on legacy Grub, and in some cases, may find that update-grub doesn’t properly update when a new kernel is installed. Here you’ll find two solutions, one to get Grub Legacy updating properly, and the second on how to update to Grub 2. This was personally tested on Debian, but the principles should translate to most distros.
PART 1 -- Fixing Grub Legacy
The kernel updating issue is typically caused by Grub Legacy’s inability to realize it’s in a Xen guest environment. This can be solved by using to PvGrub to keep your /boot/grub/grub.conf updated (grub.conf is linked to /boot/grub/menu.lst).
1) Take a look in your /etc/fstab to find the root “/” partition for your VPS (if it lists a separate partition for /boot then use it instead). This will likely be something like “/dev/xvda1” or “/sda/xvda1”
2) Make a backup copy of your current /boot/grub/grub.conf
$ sudo cp /boot/grub/grub.conf /boot/grub/grub.conf.bak
3) Install PVGrub (aka. pvgrub-legacy or pv-grub-menu in Deb). This will remove the grub-legacy package but keep grub-common:
$ sudo apt-get install pv-grub-menu
4) Make sure your /etc/default/grub is configured how you want it, then run PvGrub:
$ sudo update-menu-lst
5) PvGrub should now have updated your /boot/grub/grub.conf with entries for all your kernels, with a structure similar to the example below. Verify that the “root” line lists the root (or boot) partition from step 1. Also verify that the UUID listed in the “kernel” line matches the UUID for your root “/” partition (use “ls -al /dev/disk/by-uuid/” to list UUIDs). Finally, make sure the “default” line lists the kernel you want to boot.
title Debian GNU/Linux, kernel 3.2.0-4-amd64
kernel /boot/vmlinuz-3.2.0-4-amd64 root=UUID=5d83xx6a-7ed6-422a-8579-70a4a6eb3bb3 ro
6) Reboot and confirm you’re running the new kernel (uname -a).
7) If the system won’t reboot then use the recovery console provided by your host to log-in as root, manually mount your root (or boot) filesystem and copy your backup grub.conf back over the new one (or try to fix the errors in the new one).
PART 2 -- Upgrading to Grub 2 (aka. PvGrub 2, aka. Grub 2 Xen)
If, and only if, you have a fully working Grub Legacy that’s booting nicely, then you can proceed to upgrade to Grub 2. The kicker here is that in most cloud VPS environments, you cannot actually overwrite the existing Grub Legacy in the MBR/partition boot sector, so the approach here is to do a one-time tweak of the Grub Legacy install to chainload Grub 2. Once completed, the Grub Legacy config will remain static and all future kernel updates will be maintained using Grub 2 in the normal fashion (i.e. update-grub).
1) Again, make a backup copy of your currently working /boot/grub/grub.conf and /etc/default/grub files.
2) Remove any current grub packages installed on the system (this will only remove the packages, not the existing grub binaries in the boot sector):
apt-get remove pv-grub-menu grub-common grub-legacy grub-pc grub2 grub2-common
3) Install Grub Xen package (Not grub-xen-host!)
apt-get install grub-xen
4) Double check that it installed fully (should have been automagically by APT, but just in case):
$ sudo grub-install --target=x86_64-xen
or if appropriate:
$ sudo grub-install --target=i386-xen
Ignore the junk warnings as long as you see “No error reported”.
Installing for x86_64-xen platform.
grub-install: warning: no hints available for your platform. Expect reduced performance.
grub-install: warning: WARNING: no platform-specific install was performed.
Installation finished. No error reported.
5) You should now have a file /boot/xen/pvboot-x86_64.elf (or pvboot-i386.elf)
6) Configure /etc/default/grub with your preferred settings, then run:
7) Verify that the Grub 2 config file (/boot/grub/grub.cfg, not grub.conf !!) was updated with your kernels and all looks in order (e.g. root partitions, etc).
8) Now setup Grub Legacy to chainload Grub 2. Edit /etc/grub/grub.conf (menu.lst). Set “default 0” and “timeout 1”, then add the following as the first entry in the kernels list (you may want to leave the other kernel entries as backup while testing). Make sure to adjust the “root” and “kernel” path as appropriate.
title Chainload Grub 2
9) If you had “GRUB_DEFAULT=saved” in your /etc/default/grub then remember to run grub-set-default before rebooting. If you make any more changes to /etc/default/grub or the /etc/grub.d/ files, then re-run update-grub.
11) If everything has gone according to plan then your Grub Legacy config never needs touched again. If your VPS host actually supports direct loading of Grub 2 (currently rare), then it may even skip the Grub Legacy config and directly load your Grub 2. Either way, the net effect is essentially the same -- booting for all future kernel updates is now handled directly using your Grub 2 config. There should not be any packages updating your Grub Legacy grub.conf file (update-grub and update-grub2 are just linked commands, both for updating Grub 2’s /boot/grub/grub.cfg config).
Many thanks to Ian Campbell for this post.