Upgrade your Debian Kernel on Digital Ocean

Digital Ocean doesn’t let you run your own kernels via their control panel, but there is a workaround.

kexec via sudo apt-get install kexec-tools

kexec lets you boot a new kernel from the command line. With a little shell magic (shell magic is what I call my nasty hack), we can interrupt the normal boot part way through, and reboot into our preferred kernel.

First, the magic, don’t uninstall any kernels, but install the kernel you want to boot. At the time of writing, I chose linux-image-3.13-1-amd64, and I have two symlinks

chesty@indifferent:~$ ls -l /vmlinuz /initrd.img
lrwxrwxrwx 1 root root 29 Mar  5 21:24 /initrd.img -> /boot/initrd.img-3.13-1-amd64
lrwxrwxrwx 1 root root 25 Mar  5 21:24 /vmlinuz -> boot/vmlinuz-3.13-1-amd64

create a file in /etc/init.d, call it something like localkexec

chesty@indifferent:~$ cat /etc/init.d/localkexec 
#!/bin/sh
### BEGIN INIT INFO
# Provides:          localkexec
# Required-Start:    
# Required-Stop:
# Should-Start:      
# Default-Start:     S
# Default-Stop:
# X-Interactive:     true
# Short-Description: kexec
### END INIT INFO

case "$1" in
  start|"")
        if grep -q kexecDO /proc/cmdline; then
                exit 0
        fi
        /sbin/kexec -l /vmlinuz --append="`cat /proc/cmdline` kexecDO" --initrd=/initrd.img
        /sbin/kexec -e
        ;;
  restart|reload|force-reload)
        echo "Error: argument '$1' not supported" >&2
        exit 3
        ;;
  stop)
        # No-op
        ;;
  *)
        echo "Usage: $0 [start|stop]" >&2
        exit 3
        ;;
esac

What happens is, if the word kexecDO doesn’t appear in /proc/cmdline, then reboot into our new kernel. The new kernel will have the same /proc/cmdline as the previous Digital Ocean kernel, with the added word kexecDO. This stops boot loops. Also we need /proc/cmdline, so we have to run this script after /proc is mounted. On my system, /proc is mounted by
/etc/rcS.d/S01mountkernfs.sh so /etc/rcS.d/S02localkexec will work OK.

cd /etc/rcS.d
ln -s ../init.d/localkexec S02localkexec

You should test kexec first manually from the command like before installing the init script in /etc/rcS.d, sudo /etc/init.d/localkexec will reboot you into your new kernel. After that, install the symlink in /etc/rcS.d and type reboot. Done.

2 thoughts on “Upgrade your Debian Kernel on Digital Ocean”

Comments are closed.