1f9e807
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
1f9e807
From: Javier Martinez Canillas <javierm@redhat.com>
1f9e807
Date: Mon, 30 Aug 2021 12:31:18 +0200
1f9e807
Subject: [PATCH] normal/main: Discover the device to read the config from as a
1f9e807
 fallback
1f9e807
1f9e807
The GRUB core.img is generated locally, when this is done the grub2-probe
1f9e807
tool figures out the device and partition that needs to be read to parse
1f9e807
the GRUB configuration file.
1f9e807
1f9e807
But in some cases the core.img can't be generated on the host and instead
1f9e807
has to be done at package build time. For example, if needs to get signed
1f9e807
with a key that's only available on the package building infrastructure.
1f9e807
1f9e807
If that's the case, the prefix variable won't have a device and partition
1f9e807
but only a directory path. So there's no way for GRUB to know from which
1f9e807
device has to read the configuration file.
1f9e807
1f9e807
To allow GRUB to continue working on that scenario, fallback to iterating
1f9e807
over all the available devices, if reading the config failed when using
1f9e807
the prefix and fw_path variables.
1f9e807
1f9e807
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
1f9e807
---
1f9e807
 grub-core/normal/main.c | 58 +++++++++++++++++++++++++++++++++++++++++++------
1f9e807
 1 file changed, 51 insertions(+), 7 deletions(-)
1f9e807
1f9e807
diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c
e622855
index 7de9e4c36d..8f5fd81003 100644
1f9e807
--- a/grub-core/normal/main.c
1f9e807
+++ b/grub-core/normal/main.c
9fdaa79
@@ -337,18 +337,13 @@ grub_enter_normal_mode (const char *config)
1f9e807
 }
1f9e807
 
1f9e807
 static grub_err_t
1f9e807
-grub_try_normal (const char *variable)
1f9e807
+grub_try_normal_prefix (const char *prefix)
1f9e807
 {
1f9e807
     char *config;
1f9e807
-    const char *prefix;
1f9e807
     grub_err_t err = GRUB_ERR_FILE_NOT_FOUND;
1f9e807
     const char *net_search_cfg;
1f9e807
     int disable_net_search = 0;
1f9e807
 
1f9e807
-    prefix = grub_env_get (variable);
1f9e807
-    if (!prefix)
1f9e807
-      return GRUB_ERR_FILE_NOT_FOUND;
1f9e807
-
1f9e807
     net_search_cfg = grub_env_get ("feature_net_search_cfg");
1f9e807
     if (net_search_cfg && net_search_cfg[0] == 'n')
1f9e807
       disable_net_search = 1;
9fdaa79
@@ -362,7 +357,7 @@ grub_try_normal (const char *variable)
1f9e807
        config = grub_malloc (config_len);
1f9e807
 
1f9e807
        if (! config)
1f9e807
-         return GRUB_ERR_FILE_NOT_FOUND;
1f9e807
+         return err;
1f9e807
 
1f9e807
        grub_snprintf (config, config_len, "%s/grub.cfg", prefix);
1f9e807
        err = grub_net_search_config_file (config);
9fdaa79
@@ -391,6 +386,53 @@ grub_try_normal (const char *variable)
1f9e807
     return err;
1f9e807
 }
1f9e807
 
1f9e807
+static int
1f9e807
+grub_try_normal_dev (const char *name, void *data)
1f9e807
+{
1f9e807
+  grub_err_t err;
1f9e807
+  const char *prefix = grub_xasprintf ("(%s)%s", name, (char *)data);
1f9e807
+
1f9e807
+  if (!prefix)
1f9e807
+    return 0;
1f9e807
+
1f9e807
+  err = grub_try_normal_prefix (prefix);
1f9e807
+  if (err == GRUB_ERR_NONE)
1f9e807
+    return 1;
1f9e807
+
1f9e807
+  return 0;
1f9e807
+}
1f9e807
+
1f9e807
+static grub_err_t
1f9e807
+grub_try_normal_discover (void)
1f9e807
+{
1f9e807
+  char *prefix = grub_env_get ("prefix");
1f9e807
+  grub_err_t err = GRUB_ERR_FILE_NOT_FOUND;
1f9e807
+
1f9e807
+  if (!prefix)
1f9e807
+    return err;
1f9e807
+
1f9e807
+  if (grub_device_iterate (grub_try_normal_dev, (void *)prefix))
1f9e807
+    return GRUB_ERR_NONE;
1f9e807
+
1f9e807
+  return err;
1f9e807
+}
1f9e807
+
1f9e807
+static grub_err_t
1f9e807
+grub_try_normal (const char *variable)
1f9e807
+{
1f9e807
+  grub_err_t err = GRUB_ERR_FILE_NOT_FOUND;
1f9e807
+  const char *prefix;
1f9e807
+
1f9e807
+  if (!variable)
1f9e807
+    return err;
1f9e807
+
1f9e807
+  prefix = grub_env_get (variable);
1f9e807
+  if (!prefix)
1f9e807
+    return err;
1f9e807
+
1f9e807
+  return grub_try_normal_prefix (prefix);
1f9e807
+}
1f9e807
+
1f9e807
 /* Enter normal mode from rescue mode.  */
1f9e807
 static grub_err_t
1f9e807
 grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)),
9fdaa79
@@ -405,6 +447,8 @@ grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)),
1f9e807
       err = grub_try_normal ("fw_path");
1f9e807
       if (err == GRUB_ERR_FILE_NOT_FOUND)
1f9e807
         err = grub_try_normal ("prefix");
1f9e807
+      if (err == GRUB_ERR_FILE_NOT_FOUND)
1f9e807
+        err = grub_try_normal_discover ();
1f9e807
       if (err == GRUB_ERR_FILE_NOT_FOUND)
1f9e807
         grub_enter_normal_mode (0);
1f9e807
     }