This situation has became more interesting with the latest release of GRUB.
Latest GRUB release changed the contents of /boot/grub/grub.cfg a bit.
Now they looks like this:
..................................................................
#
# DO NOT EDIT THIS FILE
#
# It is automatically generated by grub-mkconfig using templates
# from /etc/grub.d and settings from /etc/default/grub
#
### BEGIN /etc/grub.d/00_header ###
if [ -s $prefix/grubenv ]; then
set have_grubenv=true
load_env
fi
if [ "${next_entry}" ] ; then
set default="${next_entry}"
set next_entry=
save_env next_entry
set boot_once=true
else
set default="${saved_entry}"
fi
.......
..................................................................
So the "awk '/^set default/ {print $2}'" returns an empty string,
which turns "if [ "$default" = '${saved_entry}' ]" into a dead branch,
so kexec always loads the first kernel in the GRUB list at reboot,
regardless of saved selection.
Modifying this awk expression:
awk '/^set default/ {print $2}'
as something like this:
awk '/set default="\${saved_entry}/ {print $2}'
, is necessary for selecting the correct line.
I'm attaching the full patch that fixes both problems.
--- kexec-load.init.d 2014-11-01 23:24:36.594420837 +0200
+++ kexec-load.init.d_fixed 2014-11-01 23:07:50.984195515 +0200
@@ -38,19 +38,24 @@
mountpoint -q /boot && prefix=/boot || prefix=
data=$(cat /boot/grub/grub.cfg)
- default=$(echo "$data" | awk '/^set default/ {print $2}' | cut -d'"' -f2)
+ default=$(echo "$data" | awk '/set default="\${saved_entry}/ {print $2}' | cut -d'"' -f2)
+
+ # grub entries start with "menuentry" commands. Get the line
+ # numbers that surround the first entry
+ offsets=$(echo "$data" | grep -n '^[[:space:]]*menuentry[[:space:]]' | cut -d: -f1)
+
if [ "$default" = '${saved_entry}' ]; then
- default=$(sed -ne 's/^saved_entry=//p' /boot/grub/grubenv)
+ saved_name=$(sed -ne 's/^saved_entry=//p' /boot/grub/grubenv \
+ | awk -F'>' '{printf $NF}')
+ line_no=$(echo "$data" | grep -n "$saved_name" | cut -d: -f1)
+ default=$(echo "$offsets" | grep -n "$line_no" | cut -d: -f1)
fi
if [ -z "$default" ]; then
- default=0
+ default=1
fi
- start_offset=$((default + 1))
- end_offset=$((default + 2))
+ start_offset=$default
+ end_offset=$((default + 1))
- # grub entries start with "menuentry" commands. Get the line
- # numbers that surround the first entry
- offsets=$(echo "$data" | grep -n '^[[:space:]]*menuentry[[:space:]]' | cut -d: -f1)
begin=$(echo "$offsets" | tail -n+$start_offset | head -n1)
end=$(echo "$offsets" | tail -n+$end_offset | head -n1)