File 0004-menu-Add-support-for-LoaderConfigTimeout-and-LoaderC.patch of Package grub2

From 98814c858df0fc3d5ea1d4c421c12b719fc02b57 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/7] menu: Add support for LoaderConfigTimeout and
 LoaderConfigTimeoutOneShot

Add new timeout_style "disabled" to match Boot Loader Interface.
---
 grub-core/commands/bli.c | 71 ++++++++++++++++++++++++++++++++++++++++
 grub-core/normal/menu.c  |  9 +++--
 2 files changed, 77 insertions(+), 3 deletions(-)

diff --git a/grub-core/commands/bli.c b/grub-core/commands/bli.c
index 0b4e1259a..60d219f91 100644
--- a/grub-core/commands/bli.c
+++ b/grub-core/commands/bli.c
@@ -192,6 +192,76 @@ set_loader_default_entry (void)
     }
 }
 
+/* Read LoaderConfigTimeout and LoaderConfigTimeoutOneShot and update
+   timeout accordingly */
+static void
+set_timeout_from_loader_config (void)
+{
+  unsigned long timeout_oneshot, timeout;
+  bool has_oneshot = false;
+  char* config_timeout;
+  char* config_timeout_oneshot = get_efivar ("LoaderConfigTimeoutOneShot");
+  if (config_timeout_oneshot)
+  {
+    /* Remove its value, regardless if it is valid or not */
+    grub_efi_set_variable_to_string ("LoaderConfigTimeoutOneShot",
+	    &bli_vendor_guid, "", 0);
+
+    timeout_oneshot = grub_strtoul (config_timeout_oneshot, 0, 0);
+    if (grub_errno != GRUB_ERR_NONE)
+      grub_errno = GRUB_ERR_NONE;
+    /* We have a valid value */
+    else
+      {
+	/* when timeout_oneshot is set to 0, wait indefinitely */
+	if (timeout_oneshot == 0)
+	  grub_env_unset ("timeout");
+	else
+	  grub_menu_set_timeout (timeout_oneshot);
+	has_oneshot = true;
+	grub_env_set("timeout_style", "menu");
+      }
+    grub_free(config_timeout_oneshot);
+  }
+
+  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;
+
+  if (grub_strcmp (config_timeout, "menu-force") == 0)
+    {
+      grub_env_unset ("timeout");
+      grub_env_set ("timeout_style", "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");
+    } 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)
+	{
+	  if (timeout == GRUB_UINT_MAX)
+	    grub_env_unset ("timeout");
+	  else
+	    grub_menu_set_timeout (timeout);
+	  grub_env_set ("timeout_style", "menu");
+	} else {
+	  grub_errno = GRUB_ERR_NONE;
+	}
+    }
+  grub_free(config_timeout);
+}
+
 GRUB_MOD_INIT (bli)
 {
   grub_efi_set_variable_to_string ("LoaderInfo", &bli_vendor_guid, PACKAGE_STRING,
@@ -200,6 +270,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 c2a1b4442..4a78df3b1 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

openSUSE Build Service is sponsored by