diff --git a/configure.ac b/configure.ac index d3ca0a1..cc2ef03 100644 --- a/configure.ac +++ b/configure.ac @@ -1915,6 +1915,17 @@ else fi AC_SUBST([QUIET_BOOT]) +AC_ARG_ENABLE([quick-boot], + [AS_HELP_STRING([--enable-quick-boot], + [bypass boot menu if possible (default=no)])], + [], [enable_quick_boot=no]) +if test x"$enable_quick_boot" = xyes ; then + QUICK_BOOT=1 +else + QUICK_BOOT=0 +fi +AC_SUBST([QUICK_BOOT]) + LIBS="" AC_SUBST([FONT_SOURCE]) diff --git a/docs/grub.texi b/docs/grub.texi index f8b4b3b..0b58daf 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -1563,6 +1563,20 @@ This option may be set to a list of GRUB module names separated by spaces. Each module will be loaded as early as possible, at the start of @file{grub.cfg}. +@item GRUB_RECORDFAIL_TIMEOUT +If this option is set, it overrides the default recordfail setting. A +setting of -1 causes GRUB to wait for user input indefinitely. However, a +false positive in the recordfail mechanism may occur if power is lost during +boot before boot success is recorded in userspace. The default setting is +30, which causes GRUB to wait for user input for thirty seconds before +continuing. This default allows interactive users the opportunity to switch +to a different, working kernel, while avoiding a false positive causing the +boot to block indefinitely on headless and appliance systems where access to +a console is restricted or limited. + +This option is only effective when GRUB was configured with the +@option{--enable-quick-boot} option. + @end table The following options are still accepted for compatibility with existing diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c index 338f5a5..101aa80 100644 --- a/grub-core/normal/menu.c +++ b/grub-core/normal/menu.c @@ -603,6 +603,30 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) static struct grub_term_coordinate *pos; int entry = -1; + if (timeout == 0) + { + /* If modifier key statuses can't be detected without a delay, + then a hidden timeout of zero cannot be interrupted in any way, + which is not very helpful. Bump it to three seconds in this + case to give the user a fighting chance. */ + grub_term_input_t term; + int nterms = 0; + int mods_detectable = 1; + + FOR_ACTIVE_TERM_INPUTS(term) + { + if (!term->getkeystatus) + { + mods_detectable = 0; + break; + } + else + nterms++; + } + if (!mods_detectable || !nterms) + timeout = 3; + } + if (timeout_style == TIMEOUT_STYLE_COUNTDOWN && timeout) { pos = grub_term_save_pos (); diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index 17269b3..92e640c 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -253,7 +253,8 @@ export GRUB_DEFAULT \ GRUB_ENABLE_CRYPTODISK \ GRUB_BADRAM \ GRUB_OS_PROBER_SKIP_LIST \ - GRUB_DISABLE_SUBMENU + GRUB_DISABLE_SUBMENU \ + GRUB_RECORDFAIL_TIMEOUT if test "x${grub_cfg}" != "x"; then rm -f "${grub_cfg}.new" diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in index c5955df..d660755 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -21,6 +21,8 @@ prefix="@prefix@" exec_prefix="@exec_prefix@" datarootdir="@datarootdir@" grub_lang=`echo $LANG | cut -d . -f 1` +grubdir="`echo "/@bootdirname@/@grubdirname@" | sed 's,//*,/,g'`" +quick_boot="@QUICK_BOOT@" export TEXTDOMAIN=@PACKAGE@ export TEXTDOMAINDIR="@localedir@" @@ -44,6 +46,7 @@ if [ "x${GRUB_TIMEOUT_BUTTON}" = "x" ] ; then GRUB_TIMEOUT_BUTTON="$GRUB_TIMEOUT cat << EOF if [ -s \$prefix/grubenv ]; then + set have_grubenv=true load_env fi EOF @@ -96,7 +99,50 @@ function savedefault { save_env saved_entry fi } +EOF + +if [ "$quick_boot" = 1 ]; then + cat <