File 0004-bli-Add-support-for-LoaderConfigTimeout-and-LoaderCo.patch of Package grub2
From 1f32d73ab9374bcc5f8831a4333dc98e38cb2bfb Mon Sep 17 00:00:00 2001
From: Danilo Spinella <danilo.spinella@suse.com>
Date: Wed, 11 Mar 2026 17:55:47 +0100
Subject: [PATCH 4/9] bli: Add support for LoaderConfigTimeout and
LoaderConfigTimeoutOneShot
Add new timeout_style "disabled" to match Boot Loader Interface.
---
grub-core/commands/bli.c | 81 ++++++++++++++++++++++++++++++++++++++++
grub-core/normal/menu.c | 9 +++--
2 files changed, 87 insertions(+), 3 deletions(-)
diff --git a/grub-core/commands/bli.c b/grub-core/commands/bli.c
index 0b4e1259a..d0fde76f0 100644
--- a/grub-core/commands/bli.c
+++ b/grub-core/commands/bli.c
@@ -192,6 +192,86 @@ set_loader_default_entry (void)
}
}
+/* Parse the timeout according to the Boot Loader Interface spec
+ for LoaderConfigTimeout and LoaderConfigTimeoutOneShot.
+ Return true when the timeout has been set. */
+static int
+parse_timeout_bli (const char* config_timeout, bool is_oneshot)
+{
+ unsigned int timeout;
+ /* When the timeout is set to menu-force or LoaderConfigTimeoutOneShot is
+ set to 0, show the menu indefinitely */
+ if (grub_strcmp (config_timeout, "menu-force") == 0
+ || (is_oneshot && grub_strcmp (config_timeout, "0") == 0))
+ {
+ grub_env_unset ("timeout");
+ grub_env_set ("timeout_style", "menu");
+ /* When set to 0 or to menu-hidden, don't show the menu but wait until the
+ timeout expires. Allow the user to interrupt the boot and show the menu */
+ } else if (grub_strcmp (config_timeout, "0") == 0
+ || grub_strcmp (config_timeout, "menu-hidden") == 0)
+ {
+ grub_menu_set_timeout (3);
+ grub_env_set ("timeout_style", "hidden");
+ /* When set to to menu-disabled, don't show the menu and boot the default
+ entry directly. Don't allow the user to interrupt the bootloader. */
+ } else if (grub_strcmp (config_timeout, "menu-disabled") == 0)
+ {
+ grub_env_set ("timeout", "0");
+ grub_env_set ("timeout_style", "disabled");
+ } else {
+ timeout = grub_strtoul (config_timeout, 0, 0);
+ if (grub_errno == GRUB_ERR_NONE)
+ {
+ /* In previous versions of bootctl, timeout is set to GRUB_UINT_MAX
+ instead of menu-force */
+ if (timeout == GRUB_UINT_MAX)
+ {
+ grub_env_unset ("timeout");
+ grub_env_set ("timeout_style", "menu");
+ }
+ else
+ grub_menu_set_timeout (timeout);
+ grub_env_set ("timeout_style", "menu");
+ } else {
+ grub_errno = GRUB_ERR_NONE;
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/* Read LoaderConfigTimeout and LoaderConfigTimeoutOneShot and update
+ timeout accordingly */
+static void
+set_timeout_from_loader_config (void)
+{
+ bool has_oneshot = false;
+ char* config_timeout = get_efivar ("LoaderConfigTimeoutOneShot");
+ if (config_timeout)
+ {
+ /* Remove its value, regardless if it is valid or not */
+ grub_efi_set_variable_to_string ("LoaderConfigTimeoutOneShot",
+ &bli_vendor_guid, "", 0);
+
+ has_oneshot = parse_timeout_bli (config_timeout, true);
+ grub_free (config_timeout);
+ }
+
+ if (has_oneshot)
+ return;
+
+ /* If there was no LoaderConfigTimeoutOneShot value or it was invalid,
+ read LoaderConfigTimeout */
+ config_timeout = get_efivar ("LoaderConfigTimeout");
+ if (!config_timeout)
+ return;
+
+ parse_timeout_bli (config_timeout, false);
+ grub_free (config_timeout);
+}
+
GRUB_MOD_INIT (bli)
{
grub_efi_set_variable_to_string ("LoaderInfo", &bli_vendor_guid, PACKAGE_STRING,
@@ -200,6 +280,7 @@ GRUB_MOD_INIT (bli)
set_loader_device_part_uuid ();
set_loader_active_pcr_banks ();
set_loader_default_entry ();
+ set_timeout_from_loader_config ();
/* No error here is critical, other than being logged */
grub_print_error ();
}
diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c
index 569573011..e9738890a 100644
--- a/grub-core/normal/menu.c
+++ b/grub-core/normal/menu.c
@@ -44,7 +44,8 @@ grub_err_t (*grub_gfxmenu_try_hook) (int entry, grub_menu_t menu,
enum timeout_style {
TIMEOUT_STYLE_MENU,
TIMEOUT_STYLE_COUNTDOWN,
- TIMEOUT_STYLE_HIDDEN
+ TIMEOUT_STYLE_HIDDEN,
+ TIMEOUT_STYLE_DISABLED
};
struct timeout_style_name {
@@ -54,6 +55,7 @@ struct timeout_style_name {
{"menu", TIMEOUT_STYLE_MENU},
{"countdown", TIMEOUT_STYLE_COUNTDOWN},
{"hidden", TIMEOUT_STYLE_HIDDEN},
+ {"disabled", TIMEOUT_STYLE_DISABLED},
{NULL, 0}
};
@@ -672,10 +674,11 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot, int *notify_boot)
}
/* If timeout is 0, drawing is pointless (and ugly). */
- if (timeout == 0)
+ if (timeout == 0 || timeout_style == TIMEOUT_STYLE_DISABLED)
{
*auto_boot = 1;
- *notify_boot = timeout_style != TIMEOUT_STYLE_HIDDEN;
+ *notify_boot = timeout_style != TIMEOUT_STYLE_HIDDEN
+ && timeout_style != TIMEOUT_STYLE_DISABLED;
return default_entry;
}
--
2.53.0