Package: kexec-tools
Version: 1:2.0.0-1
Severity: wishlist
Tags: patch
Hello,
It would be nice if the kexec-load init script could parse
/boot/grub/menu.lst to determine the kernel, command-line, and initrd to
load. On systems that use grub, this is more canonical than the
/vmlinuz and /initrd.img links; plus, getting the command-line from
grub's configuration makes the default behavior of "reboot" with
kexec-tools installed more predictable. (Right now, if I change an
append option in menu.lst, I have to remember either to use "reboot -f"
or manually load the kernel with a new --append option.)
The attached patch implements this if there is a "USE_GRUB_CONFIG=true"
line in /etc/default/kexec. If /boot/grub/menu.lst doesn't exist, it
falls back to the previous behavior.
Thanks for considering the patch.
--
John Wright <[email protected]>
diff --git a/debian/kexec-load.init.d b/debian/kexec-load.init.d
index 0312265..f2949ad 100644
--- a/debian/kexec-load.init.d
+++ b/debian/kexec-load.init.d
@@ -16,11 +16,63 @@ PATH=/usr/sbin:/usr/bin:/sbin:/bin
test -r /etc/default/kexec && . /etc/default/kexec
+process_grub_entry() {
+ if awk '{print $2}' /proc/mounts | grep -q '^/boot$'; then
+ BOOT="/boot"
+ else
+ BOOT=
+ fi
+
+ echo INITRD=
+ while read command args; do
+ if [ "$command" = "kernel" ]; then
+ echo "$args" | while read kernel append; do
+ echo KERNEL_IMAGE=\"${BOOT}${kernel}\"
+ echo APPEND=\"${append}\"
+ done
+ elif [ "$command" = "initrd" ]; then
+ echo INITRD=\"${BOOT}${args}\"
+ fi
+done
+}
+
+get_grub_kernel() {
+ test -f /boot/grub/menu.list || return
+ data=$(cat /boot/grub/menu.lst)
+
+ default=$(echo "$data" | awk '/^default/ {print $2}')
+ if [ -z "$default" ]; then
+ default=0
+ elif [ "$default" = "saved" ]; then
+ default=$(cat /boot/grub/default | grep -v ^#)
+ fi
+ start_offset=$((default + 1))
+ end_offset=$((default + 2))
+
+ # grub entries start with "title" commands. Get the line numbers that
+ # surround the first entry.
+ offsets=$(echo "$data" | grep -n ^title | cut -d: -f1)
+ begin=$(echo "$offsets" | tail -n+$start_offset | head -n1)
+ end=$(echo "$offsets" | tail -n+$end_offset | head -n1)
+
+ # If this is the last entry, we need to read to the end of the file
+ if [ -z "$end" ]; then
+ numlines=$(echo "$data" | wc -l)
+ end=$((numlines + 1))
+ fi
+
+ length=$((end - begin))
+ entry=$(echo "$data" | tail -n+$begin | head -n$length)
+ eval $(echo "$entry" | process_grub_entry)
+}
+
do_stop () {
test "$LOAD_KEXEC" = "true" || exit 0
test -x /sbin/kexec || exit 0
test "x`cat /sys/kernel/kexec_loaded`y" = "x1y" && exit 0
+ test "$USE_GRUB_CONFIG" = "true" && get_grub_kernel
+
REAL_APPEND="$APPEND"
test -z "$REAL_APPEND" && REAL_APPEND="`cat /proc/cmdline`"
diff --git a/debian/kexec-tools.postinst b/debian/kexec-tools.postinst
index fbd44e4..cce4116 100644
--- a/debian/kexec-tools.postinst
+++ b/debian/kexec-tools.postinst
@@ -71,6 +71,11 @@ umask 022
# Load a kexec kernel (true/false)
LOAD_KEXEC=true
+# If USE_GRUB_CONFIG is true, and /boot/grub/menu.lst exists, kexec-load use it
+# to determine the kernel to load. Otherwise it will fall back to the options
+# below.
+USE_GRUB_CONFIG=false
+
# Kernel and initrd image
KERNEL_IMAGE="/vmlinuz"
INITRD="/initrd.img"
diff --git a/debian/kexec.default b/debian/kexec.default
index 025637e..628d67b 100644
--- a/debian/kexec.default
+++ b/debian/kexec.default
@@ -4,6 +4,11 @@
# Load a kexec kernel (true/false)
LOAD_KEXEC=true
+# If USE_GRUB_CONFIG is true, and /boot/grub/menu.lst exists, kexec-load use it
+# to determine the kernel to load. Otherwise it will fall back to the options
+# below.
+USE_GRUB_CONFIG=false
+
# Kernel and initrd image
KERNEL_IMAGE="/vmlinuz"
INITRD="/initrd.img"