October 16, 2008

Reboot like a racecar with kexec

Author: David Pendell

If you have ever found yourself in the position of having to reboot quickly or several times, you know that it's not a very quick process, particularly if you have SCSI devices or other initialization-intensive system devices. A package called kexec can speed up your reboots -- if you understand the rules.

Kexec was originally intended for use by kernel and system developers who had to reboot several times a day. Soon, system administrators for high-availability servers found use for it as well. As systems get more and more advanced, and boot times get longer, end users can now benefit from it.

The system is simple, and consists of two parts: a kexec-enabled kernel and the kexec-tools package. Most modern kernels already support kexec functionality, but I haven't found a reliable way to test for kexec support in the kernel. My suggestion is to try it -- if it works, you have it. If not, you may have to compile a custom kernel to get it. As for the second part, you can get the kexec-tools software either from your distribution's repositories or from the kexec project page.

Before you can execute the commands, there are a few things you should know. When you load a new kernel by running kexec you are overwriting the existing kernel with the kernel you specify. While this has the effect of rebooting the system quickly, it also skips the process that resets all of your hardware to a "clean" state, which can have some unpredictable consequences depending on the hardware that you use. For example, the video card on my system is an old Nvidia GeForce2 Go, and I had been using the legacy driver from Nvidia for it. After using kexec to reboot, the video never worked correctly. When I switched to the open source driver, the video came up just fine. Outcomes like this may be as varied as the kinds of hardware that exist. You just need to be aware of the possibility of problems in case something happens that you don't expect.

You also need to know that kexec only reboots the kernel -- it does not take care of any cleanup such as shutting down applications or unmounting disks. We are going to set up a script that will take care of the whole process.

I put this script in the /etc/init.d/reboot file in Ubuntu. The best location will vary depending on your distro. I do recommend making this part of your system reboot procedure, however. Running it as a standalone script might have unexpected results. When I first experimented with kexec, I found that running the kexec commands from a command line would produce behavior that was sometimes erratic and sometimes left my system in a temporarily unusable state.

In the following code, the changes that I made to the original reboot file are highlighted.

do_stop () {

UNAMER=`uname -r` # this checks the version of the kernel
#just to save typing

#This just puts all of the parameters for loading in one place

KPARAMS="-l " # tells kexec to load the kernel

# --append tells the kernel all of its parameters
# cat /proc/cmdline gets the current kernel's command line
KPARAMS=$KPARAMS"--append=\"`cat /proc/cmdline`\" "

# this tells the kernel what initrd image to use
KPARAMS=$KPARAMS"--initrd=/boot/initrd.img-$UNAMER "

# this tells the kexec what kernel to load

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

if [ -x `locate kexec | grep sbin` ]; then # check for the kexec executable
kexec $KPARAMS # load the kernel with the correct parameters
sync # sync all of the disks so as not to lose data
umount -a # make sure all disks are unmounted
kexec -e # reboot the kernel

#This next line should never happen.

reboot -d -f -i

I use the UNAMER and KPARAMS variables to make the first kexec line is easier to read. The if statement just checks to make sure that there is a kexec command in the expected place and that it can be executed. Kexec $KPARAMS loads the kernel with the command line for the current kernel, with the matching initrd and vmlinuz files. You want to load the new kernel with the current command line because it is not going to get a command line from a bootloader. Also, you have to use the vmlinuz image because kexec doesn't support compressed images. The sync command simply makes sure that all of the data that might be cached is written to the disk; remember, kexec doesn't care about the state of the disks, but if you boot a new kernel without properly handling the disks, you will run into problems. The umount -a command then makes sure that all of your disks are not open for business, and kexec -e reboots the computer.

Unless you have a driver issue you should be presented with your normal login when the system comes back up. If you aren't, you might be able to log in with SSH or a serial terminal and shut your system down properly. If not, you will probably have to hard boot. When you get control over your computer again, check all of the commands and their syntax -- you may have a typo. If not, you are probably looking at a driver issue. Look at /var/log/messages and the output of the dmesg command; they may give you a clue. You can also search the project's message boards about the hardware and distro that you are using. At last resort, if you have an idea of what hardware the is causing the problem, contact the development team in charge of the driver for that hardware. They might be interested in the problems that you are having, and if so, this would be your chance to contribute.

If you understand the possible problems, kexec has the potential to dramatically speed up reboots. In the world of modern computers, every little bit helps.


  • Tools & Utilities
  • System Administration