nalika / rpms / grub2

Forked from rpms/grub2 2 years ago
Clone
5593c8
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
5593c8
From: Hans de Goede <hdegoede@redhat.com>
5593c8
Date: Wed, 6 Jun 2018 08:44:11 +0200
5593c8
Subject: [PATCH] Add auto-hide menu support
5593c8
5593c8
On single-os systems we do not want to show the menu, unless something
5593c8
went wrong with the previous boot, in which case the user may need the
5593c8
menu to debug/fix the problem.
5593c8
5593c8
This commit adds a new grub.d/00_menu_auto_hide file which emits a
5593c8
config snippet implementing this. I've chosen to do this in a separate
5593c8
grub.d file because chances of this going upstream are small and this way
5593c8
it will be easier to rebase.
5593c8
5593c8
Since auto-hiding the menu requires detecting the previous boot was ok,
5593c8
we get fastboot support (where we don't check for a key at all) for free
5593c8
so this commit also adds support for this.
5593c8
5593c8
The new config-file code uses the following variables:
5593c8
5593c8
menu_auto_hide     Set this to "1" to activate the new auto-hide feature
5593c8
                   Set this to "2" to auto-hide the menu even when multiple
5593c8
                   operating systems are installed. Note the menu will still
5593c8
                   auto show after booting an other os as that won't set
5593c8
                   boot_success.
5593c8
menu_show_once     Set this to "1" to force showing the menu once.
5593c8
boot_success       The OS sets this to "1" to indicate a successful boot.
5593c8
boot_indeterminate The OS increments this integer when rebooting after e.g.
5593c8
                   installing updates or a selinux relabel.
5593c8
fastboot           If set to "1" and the conditions for auto-hiding the menu
5593c8
                   are met, the menu is not shown and all checks for keypresses
5593c8
                   are skipped, booting the default immediately.
5593c8
5593c8
30_os-prober.in changes somewhat inspired by:
5593c8
https://git.launchpad.net/~ubuntu-core-dev/grub/+git/ubuntu/tree/debian/patches/quick_boot.patch
5593c8
5593c8
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
5593c8
---
5593c8
Changes in v2:
5593c8
-Drop shutdown_success tests, there is no meaningful way for systemd to set
5593c8
 this flag (by the time it knows all filesystems are unmounted or read-only
5593c8
-Drop fwsetup_once support, systemd already supports booting directly into
5593c8
 the fwsetup by doing "systemctl reboot --firmware"
5593c8
---
5593c8
 Makefile.util.def                |  6 +++++
5593c8
 util/grub.d/01_menu_auto_hide.in | 48 ++++++++++++++++++++++++++++++++++++++++
5593c8
 util/grub.d/30_os-prober.in      | 18 +++++++++++++++
5593c8
 3 files changed, 72 insertions(+)
5593c8
 create mode 100644 util/grub.d/01_menu_auto_hide.in
5593c8
5593c8
diff --git a/Makefile.util.def b/Makefile.util.def
d3c3ab
index 41906486a71..04551e095bd 100644
5593c8
--- a/Makefile.util.def
5593c8
+++ b/Makefile.util.def
5593c8
@@ -458,6 +458,12 @@ script = {
5593c8
   installdir = grubconf;
5593c8
 };
5593c8
 
5593c8
+script = {
5593c8
+  name = '01_menu_auto_hide';
5593c8
+  common = util/grub.d/01_menu_auto_hide.in;
5593c8
+  installdir = grubconf;
5593c8
+};
5593c8
+
5593c8
 script = {
5593c8
   name = '01_users';
5593c8
   common = util/grub.d/01_users.in;
5593c8
diff --git a/util/grub.d/01_menu_auto_hide.in b/util/grub.d/01_menu_auto_hide.in
5593c8
new file mode 100644
d3c3ab
index 00000000000..ad175870a54
5593c8
--- /dev/null
5593c8
+++ b/util/grub.d/01_menu_auto_hide.in
5593c8
@@ -0,0 +1,48 @@
5593c8
+#! /bin/sh
5593c8
+
5593c8
+# Disable / skip generating menu-auto-hide config parts on serial terminals
5593c8
+for x in ${GRUB_TERMINAL_INPUT} ${GRUB_TERMINAL_OUTPUT}; do
5593c8
+  case "$x" in
5593c8
+    serial*)
5593c8
+      exit 0
5593c8
+      ;;
5593c8
+  esac
5593c8
+done
5593c8
+
5593c8
+cat << EOF
5593c8
+if [ "\${boot_success}" = "1" -o "\${boot_indeterminate}" = "1" ]; then
5593c8
+  set last_boot_ok=1
5593c8
+else
5593c8
+  set last_boot_ok=0
5593c8
+fi
5593c8
+
5593c8
+# Reset boot_indeterminate after a successful boot
5593c8
+if [ "\${boot_success}" = "1" ] ; then
5593c8
+  set boot_indeterminate=0
5593c8
+# Avoid boot_indeterminate causing the menu to be hidden more then once
5593c8
+elif [ "\${boot_indeterminate}" = "1" ]; then
5593c8
+  set boot_indeterminate=2
5593c8
+fi
5593c8
+set boot_success=0
5593c8
+save_env boot_success boot_indeterminate
5593c8
+
5593c8
+if [ x\$feature_timeout_style = xy ] ; then
5593c8
+  if [ "\${menu_show_once}" ]; then
5593c8
+    unset menu_show_once
5593c8
+    save_env menu_show_once
5593c8
+    set timeout_style=menu
5593c8
+    set timeout=60
5593c8
+  elif [ "\${menu_auto_hide}" -a "\${last_boot_ok}" = "1" ]; then
5593c8
+    set orig_timeout_style=\${timeout_style}
5593c8
+    set orig_timeout=\${timeout}
5593c8
+    if [ "\${fastboot}" = "1" ]; then
5593c8
+      # timeout_style=menu + timeout=0 avoids the countdown code keypress check
5593c8
+      set timeout_style=menu
5593c8
+      set timeout=0
5593c8
+    else
5593c8
+      set timeout_style=hidden
5593c8
+      set timeout=1
5593c8
+    fi
5593c8
+  fi
5593c8
+fi
5593c8
+EOF
5593c8
diff --git a/util/grub.d/30_os-prober.in b/util/grub.d/30_os-prober.in
d3c3ab
index 4b27bd20153..3c9431cfcfb 100644
5593c8
--- a/util/grub.d/30_os-prober.in
5593c8
+++ b/util/grub.d/30_os-prober.in
5593c8
@@ -42,6 +42,7 @@ if [ -z "${OSPROBED}" ] ; then
5593c8
 fi
5593c8
 
5593c8
 osx_entry() {
5593c8
+    found_other_os=1
5593c8
     # TRANSLATORS: it refers on the OS residing on device %s
5593c8
     onstr="$(gettext_printf "(on %s)" "${DEVICE}")"
5593c8
     hints=""
5593c8
@@ -102,6 +103,7 @@ for OS in ${OSPROBED} ; do
5593c8
 
5593c8
   case ${BOOT} in
5593c8
     chain)
5593c8
+      found_other_os=1
5593c8
 
5593c8
 	  onstr="$(gettext_printf "(on %s)" "${DEVICE}")"
5593c8
       cat << EOF
5593c8
@@ -132,6 +134,7 @@ EOF
5593c8
 EOF
5593c8
     ;;
5593c8
     efi)
5593c8
+      found_other_os=1
5593c8
 
5593c8
 	EFIPATH=${DEVICE#*@}
5593c8
 	DEVICE=${DEVICE%@*}
5593c8
@@ -176,6 +179,7 @@ EOF
5593c8
 	  LINITRD="${LINITRD#/boot}"
5593c8
 	fi
5593c8
 
5593c8
+        found_other_os=1
5593c8
 	onstr="$(gettext_printf "(on %s)" "${DEVICE}")"
5593c8
 	recovery_params="$(echo "${LPARAMS}" | grep single)" || true
5593c8
 	counter=1
5593c8
@@ -257,6 +261,7 @@ EOF
5593c8
       done
5593c8
     ;;
5593c8
     hurd)
5593c8
+      found_other_os=1
5593c8
       onstr="$(gettext_printf "(on %s)" "${DEVICE}")"
5593c8
       cat << EOF
5593c8
 menuentry '$(echo "${LONGNAME} $onstr" | grub_quote)' --class hurd --class gnu --class os \$menuentry_id_option 'osprober-gnuhurd-/boot/gnumach.gz-false-$(grub_get_device_id "${DEVICE}")' {
5593c8
@@ -283,6 +288,7 @@ EOF
5593c8
 EOF
5593c8
     ;;
5593c8
     minix)
5593c8
+      found_other_os=1
5593c8
 	  cat << EOF
5593c8
 menuentry "${LONGNAME} (on ${DEVICE}, Multiboot)" {
5593c8
 EOF
5593c8
@@ -299,3 +305,15 @@ EOF
5593c8
     ;;
5593c8
   esac
5593c8
 done
5593c8
+
5593c8
+# We override the results of the menu_auto_hide code here, this is a bit ugly,
5593c8
+# but grub-mkconfig writes out the file linearly, so this is the only way
5593c8
+if [ "${found_other_os}" = "1" ]; then
5593c8
+  cat << EOF
5593c8
+# Other OS found, undo autohiding of menu unless menu_auto_hide=2
5593c8
+if [ "\${orig_timeout_style}" -a "\${menu_auto_hide}" != "2" ]; then
5593c8
+  set timeout_style=\${orig_timeout_style}
5593c8
+  set timeout=\${orig_timeout}
5593c8
+fi
5593c8
+EOF
5593c8
+fi