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])
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
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 ();
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"
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@"
cat << EOF
if [ -s \$prefix/grubenv ]; then
+ set have_grubenv=true
load_env
fi
EOF
save_env saved_entry
fi
}
+EOF
+
+if [ "$quick_boot" = 1 ]; then
+ cat <<EOF
+function recordfail {
+ set recordfail=1
+EOF
+
+ check_writable () {
+ abstractions="$(grub-probe --target=abstraction "${grubdir}")"
+ for abstraction in $abstractions; do
+ case "$abstraction" in
+ diskfilter | lvm)
+ cat <<EOF
+ # GRUB lacks write support for $abstraction, so recordfail support is disabled.
+EOF
+ return
+ ;;
+ esac
+ done
+
+ FS="$(grub-probe --target=fs "${grubdir}")"
+ case "$FS" in
+ btrfs | cpiofs | newc | odc | romfs | squash4 | tarfs | zfs)
+ cat <<EOF
+ # GRUB lacks write support for $FS, so recordfail support is disabled.
+EOF
+ return
+ ;;
+ esac
+
+ cat <<EOF
+ if [ -n "\${have_grubenv}" ]; then if [ -z "\${boot_once}" ]; then save_env recordfail; fi; fi
+EOF
+ }
+
+ check_writable
+ cat <<EOF
+}
+EOF
+fi
+
+cat <<EOF
function load_video {
EOF
if [ -n "${GRUB_VIDEO_BACKEND}" ]; then
make_timeout ()
{
+ cat << EOF
+if [ "\${recordfail}" = 1 ] ; then
+ set timeout=${GRUB_RECORDFAIL_TIMEOUT:-30}
+else
+EOF
if [ "x${3}" != "x" ] ; then
timeout="${2}"
style="${3}"
- elif [ "x${1}" != "x" ] && [ "x${1}" != "x0" ] ; then
+ elif [ "x${1}" != "x" ] && \
+ ([ "$quick_boot" = 1 ] || [ "x${1}" != "x0" ]) ; then
# Handle the deprecated GRUB_HIDDEN_TIMEOUT scheme.
timeout="${1}"
if [ "x${2}" != "x0" ] ; then
style="menu"
fi
cat << EOF
-if [ x\$feature_timeout_style = xy ] ; then
- set timeout_style=${style}
- set timeout=${timeout}
+ if [ x\$feature_timeout_style = xy ] ; then
+ set timeout_style=${style}
+ set timeout=${timeout}
EOF
if [ "x${style}" = "xmenu" ] ; then
cat << EOF
-# Fallback normal timeout code in case the timeout_style feature is
-# unavailable.
-else
- set timeout=${timeout}
+ # Fallback normal timeout code in case the timeout_style feature is
+ # unavailable.
+ else
+ set timeout=${timeout}
EOF
else
cat << EOF
-# Fallback hidden-timeout code in case the timeout_style feature is
-# unavailable.
-elif sleep${verbose} --interruptible ${timeout} ; then
- set timeout=0
+ # Fallback hidden-timeout code in case the timeout_style feature is
+ # unavailable.
+ elif sleep${verbose} --interruptible ${timeout} ; then
+ set timeout=0
EOF
fi
cat << EOF
+ fi
fi
EOF
}
datarootdir="@datarootdir@"
ubuntu_recovery="@UBUNTU_RECOVERY@"
quiet_boot="@QUIET_BOOT@"
+quick_boot="@QUICK_BOOT@"
. "$pkgdatadir/grub-mkconfig_lib"
else
echo "menuentry '$(echo "$os" | grub_quote)' ${CLASS} \$menuentry_id_option 'gnulinux-simple-$boot_device_id' {" | sed "s/^/$submenu_indentation/"
fi
+ if [ "$quick_boot" = 1 ]; then
+ echo " recordfail" | sed "s/^/$submenu_indentation/"
+ fi
if [ x$type != xrecovery ] ; then
save_default_entry | grub_add_tab
fi
prefix="@prefix@"
exec_prefix="@exec_prefix@"
datarootdir="@datarootdir@"
+quick_boot="@QUICK_BOOT@"
export TEXTDOMAIN=@PACKAGE@
export TEXTDOMAINDIR="@localedir@"
. "$pkgdatadir/grub-mkconfig_lib"
+found_other_os=
+
+adjust_timeout () {
+ if [ "$quick_boot" = 1 ] && [ "x${found_other_os}" != "x" ]; then
+ cat << EOF
+set timeout_style=menu
+if [ "\${timeout}" = 0 ]; then
+ set timeout=10
+fi
+EOF
+ fi
+}
+
if [ "x${GRUB_DISABLE_OS_PROBER}" = "xtrue" ]; then
grub_warn "$(gettext_printf "os-prober will not be executed to detect other bootable partitions.\nSystems on them will not be added to the GRUB boot configuration.\nCheck GRUB_DISABLE_OS_PROBER documentation entry.")"
exit 0
fi
osx_entry() {
+ found_other_os=1
if [ x$2 = x32 ]; then
# TRANSLATORS: it refers to kernel architecture (32-bit)
bitstr="$(gettext "(32-bit)")"
;;
esac
+ found_other_os=1
onstr="$(gettext_printf "(on %s)" "${DEVICE}")"
cat << EOF
menuentry '$(echo "${LONGNAME} $onstr" | grub_quote)' $CLASS --class os \$menuentry_id_option 'osprober-chain-$(grub_get_device_id "${DEVICE}")' {
;;
efi)
+ found_other_os=1
EFIPATH=${DEVICE#*@}
DEVICE=${DEVICE%@*}
onstr="$(gettext_printf "(on %s)" "${DEVICE}")"
[ "${prepare_boot_cache}" ] || continue
fi
+ found_other_os=1
onstr="$(gettext_printf "(on %s)" "${DEVICE}")"
recovery_params="$(echo "${LPARAMS}" | grep 'single\|recovery')" || true
counter=1
fi
;;
hurd)
+ found_other_os=1
onstr="$(gettext_printf "(on %s)" "${DEVICE}")"
cat << EOF
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}")' {
;;
esac
done
+
+adjust_timeout