Configuring GRUB to boot the right kernel after an upgrade

This is based on a very useful post by a chap named Arie. The credit for much of the following goes to him: I’m just reposting a summary to make it more widely discoverable.

If you upgrade your Linux installation, which on Ubuntu/Debian you might do with something like this:

sudo aptitude update
sudo aptitude safe-upgrade

then you may find that your kernel (linux-image package) and GRUB bootloader configuration have been updated. In particular, it may not now, by default, automatically select the right boot menu option when you next reboot… which you’re probably just about to do because you’ve just upgraded everything. This makes some sense because, if the upgrade failed for some reason, you may want to select a different option from the boot menu and go back to the previous kernel.

Well, it makes sense, unless, of course, you aren’t sitting in front of the machine with a screen and keyboard. If you’re upgrading a remote server, you may find that it doesn’t come back up after your reboot. In my case, the server was very remote, and I was lucky to have someone on site to press the right keys.

So, before you reboot after a new kernel installation, you may want to configure GRUB to try the new kernel automatically, and if it fails, go back to the old one.

GRUB is configured by the file /boot/grub/grub.cfg, but on a modern Ubuntu, rather than editing this big and complex file directly, you edit a few settings in /etc/default/grub, and then run update-grub to rebuild it out of lots of separate bits.

So, look at the variables in /etc/default/grub and make sure the following are set:

GRUB_DEFAULT=saved
GRUB_TIMEOUT=2
GRUB_CMDLINE_LINUX_DEFAULT=”panic=5″

This tells GRUB to use the last-saved selection, to boot it automatically after 2 seconds, and tells all kernels that they should reboot after 5 seconds if they die completely. Then you need to configure which kernel is initially the one that’s ‘saved’. Set it to be the one you know works. e.g.:

sudo grub-set-default "Ubuntu, with Linux 3.2.0-29-generic"

(You can look at the kernel you’re currently running with uname -a and find the label used to select it in /boot/grub/grub.cfg. Try grep menuentry /boot/grub/grub.cfg, for example.)

Then tell GRUB to try the new kernel on the next reboot, e.g.:

sudo grub-reboot ”Ubuntu, with Linux 3.2.0-32-new”

(This doesn’t actually do the reboot)

Then save all of these things using:

sudo update-grub

And try rebooting.

If it works OK and you come up in the new kernel, set that to be the saved default for the future:

sudo grub-set-default "Ubuntu, with Linux 3.2.0-32-new”

Enjoyed this post? Why not sign up to receive Status-Q in your inbox?

5 Comments

I remember doing this circa 1996 with “lilo -R” to reboot into a new “test” kernel without changing the default kernel. Thanks for the hint to do it with grub, Q.

This post most probably just saved me about a day and a half of thrashing. Thank you!

Very useful! Saved me a lot of time. Thank you so much!

This didn’t worked for me (Ubuntu 14.04).

I get following warning when I try to pass the menuentry:

Warning: Please don't use old title `Ubuntu, with Linux 3.18.20-90' for GRUB_DEFAULT, use `Advanced options for Ubuntu>Ubuntu, with Linux 3.18.20-90' (for versions before 2.00) or `gnulinux-advanced-844e3256-3ecf-4ef3-9346-5325b60a43a1>gnulinux-3.18.20-90-advanced-844e3256-3ecf-4ef3-9346-5325b60a43a1' (for 2.00 or later)

You can solve this by taking the menuentry_id_option of the Advanced Options with the menuentry_id_option of the kernel instead of the menuentry alone (cat /boot/grub/grub.cfg | grep menuentry_id_option).

[…] theory: According to this blog post (and other sources) I should be able to choose the kernel for the next reboot, using grub-reboot. […]

Got Something To Say:

Your email address will not be published. Required fields are marked *

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax

*

© Copyright Quentin Stafford-Fraser