Oracle Linux kernel developer Steve Sistare contributes this article on speeding up kernel reboots for development and for production systems.

Fast reboot with kexec

The kexec command loads a new kernel and jumps directly to it, bypassing firmware and grub. It is most often used as the first step in generating a crash dump, but it can also be used to perform an administrative reboot. The time saved by skipping firmware is substantial on a server with large memory, many CPUS, and many devices. This is particularly useful during kernel development when you frequently rebuild and reboot the kernel.

The kexec options are a bit arcane, so I wrote a script to make it easier to use for basic reboot. You specify the new or old kernel, and new or old or additional kernel command-line parameters. The script loads the new kernel and initramfs using kexec -l, then gracefully stops systemd services and jumps to the new kernel using systemctl kexec. It could save a few more seconds by abruptly killing processes with kexec -e, but I choose the graceful route to mimic a normal reboot as closely as possible. The dramatic time savings come from skipping firmware, rather than skipping systemd shutdown.

Here is the bash script, which I call kboot:

#!/bin/sh

[[ "$1" != '-' ]] && kernel="$1"
shift
if [[ "$1" == '-' ]]; then
    reuse=--reuse-cmdline
    shift
fi
[[ $# == 0 ]] && reuse=--reuse-cmdline
kernel="${kernel:-$(uname -r)}"
kargs="/boot/vmlinuz-$kernel --initrd=/boot/initramfs-$kernel.img"

kexec -l -t bzImage $kargs $reuse --append="$*" && \
    systemctl kexec

 

Usage:

kboot
kboot <kernel> [<params>] …

The first arg (if any) specifies the kernel, where a ‘-‘ means use the current kernel.
If the 2nd arg is ‘-‘ or is omitted, then the existing kernel parameters are appended.
Any remaining args are also appended to the kernel parameters.

 

Examples:

 

  1. Reboot to the same (possibly updated) kernel with same kernel command line.
    # kboot
  2. Reboot to a different kernel with the same kernel command line.
    # kboot 4.20.0-rc5
  3. Reboot to the same kernel with same kernel command line plus additional parameters:
    # kboot - - log_buf_len=16M enforcing=0
  4. Reboot to a different kernel with the same kernel command line plus additional parameters
    # kboot 4.20.0-rc5 - log_buf_len=16M enforcing=0
  5. Reboot to the same kernel with a new command line. Add single quotes around the parameters if they contain shell meta characters.
    # kboot - 'root=/dev/mapper/vg00-lv_root ro crashkernel=auto rd.lvm.lv=vg00/lv_root rd.lvm.lv=vg00/lv_swap console=ttyS0,115200 systemd.log_level=debug'

On an X6-2 test system with 2 sockets * 22 cores and 448 GB of RAM, running Oracle Linux 7.5 with UEK5, a normal reboot takes 184 seconds, as measured from typing reboot to the availability of the sshd port for logging in. kboot takes 30 seconds, a 6X speedup. For my kernel projects, kexec reboot has made the edit-compile-debug cycle a pleasure rather than a punishment!