Difference between revisions of "Kexec"

From ArchWiki
Jump to: navigation, search
(Nah, f- it. Let him be the author.)
(Likewise)
Line 102: Line 102:
 
# This script loads a kernel from the GRUB 2 menu and reboots.
 
# This script loads a kernel from the GRUB 2 menu and reboots.
 
# The error checking is very basic.
 
# The error checking is very basic.
# By Přemysl Janouch, 2008
+
# Written by Isaac G, 2010
# Rewritten by Isaac G, 2010
 
 
# Modified by Greg Fitzgerald, 2011
 
# Modified by Greg Fitzgerald, 2011
  

Revision as of 22:57, 13 March 2011

Kexec is a system call that enables you to load and boot into another kernel from the currently running kernel. This is useful for kernel developers or other people who need to reboot very quickly without waiting for the whole BIOS boot process to finish. Note that there may appear some problems and kexec may not work correctly for you because the devices won't fully reinitiate when using this method.

Installation

To install kexec, type:

 pacman -S kexec-tools

Configuration

Arch rc scripts already have kexec support, so it's enough to just call reboot after loading the kernel and it'll get (re)started.

Tips & Tricks

Rebooting your system using kexec

Here is a simple script that reads kernel information from the GRUB menu, loads the kernel using kexec, and then reboots. Save the script as, e.g., /usr/local/sbin/kexec-reboot.sh and make it executable using chmod +x.

Note: The script supports only GRUB Legacy menu files, not grub2.

Script usage

The script takes an item number as its first parameter. E.g., to boot the first item in your GRUB menu, type:

 /usr/local/sbin/kexec-reboot.sh 1

Alternatively, if no number is given, the script will interactively prompt for a number.

Script for Grub 1

#!/bin/bash
# This script loads a kernel from the GRUB menu and reboots.
# The error checking is very basic.
# Written by Isaac G, 2010

die ()
{
   tput setaf 1 # Red text
   echo "Error: $@" >&2
   tput sgr0 # Reset
   exit 1
}
 
(( UID != 0 )) && die "You need to be superuser"
unset number

# Use the first parameter or show a menu if none is specified
if [[ $1 ]] ; then
   # Make sure the selected number is an integer
   [[ $1 = *[^0-9]* ]] && die "The selected parameter is not a number"
   number=$1
else
   # Nothing selected; pull up a list of options from the grub menu
   oldIFS="$IFS"
   IFS=$'\n'

   # Get the titles
   options=( $(awk '$1 == "title" {for (i = 2; i <= NF; i++) printf "%s ", $i; printf "\n";}' /boot/grub/menu.lst ) )

   # Ask the user to select one
   select title in "${options[@]}" ; do
       for ((i = 0; i < ${#options[@]}; i++)); do
           [[ $title == "${options[i]}" ]] && number=$((i + 1)) && break
       done
       [[ $number ]] && break
   done

   IFS="$oldIFS"
fi

unset kernel
unset initrd
unset append
item=0

# Parse the grub menu.lst
while read key val extra; do
   [[ $key = "title" ]] && ((item++)) # Count the number of title's
   (( item == number )) || continue   # Wait until the right number
   [[ $key = "kernel" ]] && kernel="$val" && append="$extra"
   [[ $key = "initrd" ]] && initrd="$val"
done < /boot/grub/menu.lst

[[ $kernel ]] || die "No such kernel with that number"

# Load the kernel
echo kexec -l "$kernel" --initrd="$initrd" --append="$append"

# Sync the disks
sync

# Reboot
kexec -e

Script for Grub 2

#!/bin/bash
# This script loads a kernel from the GRUB 2 menu and reboots.
# The error checking is very basic.
# Written by Isaac G, 2010
# Modified by Greg Fitzgerald, 2011

die ()
{
   tput setaf 1 # Red text
   echo "Error: $@" >&2
   tput sgr0 # Reset
   exit 1
}
 
(( UID != 0 )) && die "You need to be superuser"
unset number

# Use the first parameter or show a menu if none is specified
if [[ $1 ]] ; then
   # Make sure the selected number is an integer
   [[ $1 = *[^0-9]* ]] && die "The selected parameter is not a number"
   number=$1
else
   # Nothing selected; pull up a list of options from the grub menu
   oldIFS="$IFS"
   IFS=$'\n'

   # Get the menuentrys
   options=( $(awk '$1 == "menuentry" {for (i = 2; i <= NF; i++) printf "%s ", $i; printf "\n";}' /boot/grub/grub.cfg ) )

   # Ask the user to select one
   select menuentry in "${options[@]}" ; do
       for ((i = 0; i < ${#options[@]}; i++)); do
           [[ $menuentry == "${options[i]}" ]] && number=$((i + 1)) && break
       done
       [[ $number ]] && break
   done

   IFS="$oldIFS"
fi

unset kernel
unset initrd
unset append
item=0

# Parse the grub grub.cfg 
while read key val extra; do
   [[ $key = "menuentry" ]] && ((item++)) # Count the number of menuentry's
   (( item == number )) || continue   # Wait until the right number
   [[ $key = "linux" ]] && kernel="$val" && append="$extra"
   [[ $key = "initrd" ]] && initrd="$val"
done < /boot/grub/grub.cfg

[[ $kernel ]] || die "No such kernel with that number"

# Load the kernel
kexec -l "/boot$kernel" --initrd="/boot$initrd" --append="$append"

## Sync the disks
sync

## Reboot
kexec -e

More Resources