October 03, 2013

Enable kexec reboots by default

Kexec allows “live” booting of a new kernel “over” the currently running kernel. kexec skips the bootloader stage (hardware initialization phase by the firmware or BIOS) and directly loads the new kernel into memory, where it starts executing immediately. This avoids the long times associated with a full reboot, and can help systems to meet high-availability requirements by minimizing downtime.

More information about kexec you can find here

Ubuntu

Tested on Ubuntu 13.04 (64bit).

  1. Install kexec-tools

     apt-get install kexec-tools
    
  2. Add to /etc/rc.local

     test -x /sbin/kexec && /sbin/kexec -l --initrd=/boot/initrd.img-$(uname -r) --reuse-cmdline /boot/vmlinuz-$(uname -r)
    
     exit 0
    
  3. Modify do_stop function in /etc/init.d/reboot

do_stop () {
	# Message should end with a newline since kFreeBSD may
	# print more stuff (see #323749)
	log_action_msg "Will now restart"

        # Reboot normally if kexec is not ready
        if [ -x /sbin/kexec ] && [ "x`cat /sys/kernel/kexec_loaded`y" = "x1y" ]; then
            kexec -e
        else
            reboot -d -f -i
        fi
}

For usual (full) “cold” restarts, you will have to unload the current kexec target kernel before the reboot.

# kexec -u
# shutdown -r 0

CentOS/RHEL

Tested on RHEL 6.4 (64bit).

  1. Add to /etc/rc.local
test -x /sbin/kexec && /sbin/kexec -l --initrd=/boot/initramfs-$(uname -r).img --reuse-cmdline /boot/vmlinuz-$(uname -r)
touch /var/lock/subsys/local

That’s all! You don’t need to modify anything else. By default CentOS will try first to run “kexec -e” in order to reboot your kernel.

[root@localhost ~]# find /etc/rc* -ls |grep halt
260917    8 -rwxr-xr-x   1 root     root         5829 Jan  9  2013 /etc/rc.d/init.d/halt
260934    0 lrwxrwxrwx   1 root     root           14 Oct  1 08:07 /etc/rc.d/rc6.d/S01reboot -> ../init.d/halt
260927    0 lrwxrwxrwx   1 root     root           14 Oct  1 08:07 /etc/rc.d/rc0.d/S01halt -> ../init.d/halt

[root@oc1521070317 ~]# grep kexec /etc/init.d/halt
	kexec_command="/sbin/kexec"
   /sbin/halt.local "$message" "$command" "$HALTARGS" "$kexec_command"
# First, try kexec. If that fails, fall back to rebooting the old way.
[ -n "$kexec_command" ] && $kexec_command -e -x >& /dev/null

Extra

You can also use “-p” kexec parameter so that it will load the new kernel for use on panic. Pre.requisite is a crashkernel kernel parameter enabled.

# In case of kernel panic it will reload the kernel. Pre.req. is a crashkernel kernel parameter
test -x /sbin/kexec && /sbin/kexec -p -l --initrd=/boot/initrd.img-$(uname -r) --reuse-cmdline /boot/vmlinuz-$(uname -r)