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)
 

Reply via email to