15a2072
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
15a2072
From: Javier Martinez Canillas <javierm@redhat.com>
15a2072
Date: Sat, 28 Jul 2018 23:57:15 +0200
15a2072
Subject: [PATCH] blscfg: remove logic to read the grubenv file and set the
15a2072
 blsdir variable
15a2072
15a2072
The BLS grub2 support has a blsdir environment variable that can be set by
15a2072
users to override the BLS fragment default path.
15a2072
15a2072
Currently the BLS parsing code reads the grubenv file and sets the blsdir
15a2072
variable, but it shouldn't be the responsability of the blscfg module to
15a2072
do this and instead just use it if the variable has been set (either from
15a2072
the grub.cfg file or the grub shell).
15a2072
15a2072
This makes the find_entry() function much simpler and consistent for EFI,
15a2072
BIOS and grub-emu. It also fixes a bug that caused having menu entries to
15a2072
be repeated for each sub-directory that existed under the /EFI directory.
15a2072
15a2072
So for example having three different operating systems sharing the ESP,
15a2072
would lead to the boot menu entries being repeated three times for grub.
15a2072
15a2072
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
15a2072
---
15a2072
 grub-core/commands/blscfg.c | 179 ++++----------------------------------------
15a2072
 1 file changed, 16 insertions(+), 163 deletions(-)
15a2072
15a2072
diff --git a/grub-core/commands/blscfg.c b/grub-core/commands/blscfg.c
15a2072
index 69bfb5db295..bdb1c5a95aa 100644
15a2072
--- a/grub-core/commands/blscfg.c
15a2072
+++ b/grub-core/commands/blscfg.c
15a2072
@@ -45,13 +45,6 @@ GRUB_MOD_LICENSE ("GPLv3+");
15a2072
 #define GRUB_BOOT_DEVICE "($root)"
15a2072
 #endif
15a2072
 
15a2072
-enum
15a2072
-  {
15a2072
-    PLATFORM_EFI,
15a2072
-    PLATFORM_EMU,
15a2072
-    PLATFORM_BIOS,
15a2072
-  };
15a2072
-
15a2072
 #define grub_free(x) ({grub_dprintf("blscfg", "%s freeing %p\n", __func__, x); grub_free(x); })
15a2072
 
15a2072
 struct keyval
15a2072
@@ -666,137 +659,37 @@ finish:
15a2072
 }
15a2072
 
15a2072
 struct find_entry_info {
15a2072
+	const char *devid;
15a2072
 	grub_device_t dev;
15a2072
 	grub_fs_t fs;
15a2072
 	int platform;
15a2072
 };
15a2072
 
15a2072
 /*
15a2072
- * filename: if the directory is /EFI/something/ , filename is "something"
15a2072
- * info: unused
15a2072
- * data: the filesystem object the file is on.
15a2072
+ * info: the filesystem object the file is on.
15a2072
  */
15a2072
-static int find_entry (const char *filename,
15a2072
-		       const struct grub_dirhook_info *dirhook_info UNUSED,
15a2072
-		       void *data)
15a2072
+static int find_entry (struct find_entry_info *info)
15a2072
 {
15a2072
-  struct find_entry_info *info = (struct find_entry_info *)data;
15a2072
   struct read_entry_info read_entry_info;
15a2072
-  grub_file_t f = NULL;
15a2072
-  char *grubenv_path = NULL;
15a2072
-  grub_envblk_t env = NULL;
15a2072
-  const char *default_blsdir = NULL;
15a2072
   grub_fs_t blsdir_fs = NULL;
15a2072
   grub_device_t blsdir_dev = NULL;
15a2072
   const char *blsdir = NULL;
15a2072
-  char *saved_env_buf = NULL;
15a2072
   bool use_version = true;
15a2072
   int fallback = 0;
15a2072
   int r = 0;
15a2072
-  const char *devid = grub_env_get ("boot");
15a2072
-
15a2072
-  grub_dprintf("blscfg", "%s got here\n", __func__);
15a2072
-  if (filename && (!grub_strcmp (filename, ".") ||
15a2072
-		   !grub_strcmp (filename, "..")))
15a2072
-    return 0;
15a2072
-
15a2072
-  if (info->platform == PLATFORM_EFI && !grub_strcasecmp (filename, "boot"))
15a2072
-    return 0;
15a2072
-
15a2072
-  saved_env_buf = grub_malloc (512);
15a2072
-
15a2072
-  // set a default blsdir
15a2072
-  if (info->platform == PLATFORM_EMU)
15a2072
-    default_blsdir = GRUB_BOOT_DEVICE GRUB_BLS_CONFIG_PATH;
15a2072
-  else
15a2072
-    default_blsdir = GRUB_BLS_CONFIG_PATH;
15a2072
-
15a2072
-  grub_env_set ("blsdir", default_blsdir);
15a2072
-  grub_dprintf ("blscfg", "default_blsdir: \"%s\"\n", default_blsdir);
15a2072
-
15a2072
-  /*
15a2072
-   * try to load a grubenv from /EFI/wherever/grubenv
15a2072
-   */
15a2072
-  if (info->platform == PLATFORM_EFI)
15a2072
-    grubenv_path = grub_xasprintf ("(%s)/EFI/%s/grubenv", devid, filename);
15a2072
-  else
15a2072
-    grubenv_path = grub_xasprintf ("(%s)/grub2/grubenv", devid);
15a2072
-
15a2072
-  grub_dprintf ("blscfg", "looking for \"%s\"\n", grubenv_path);
15a2072
-  f = grub_file_open (grubenv_path);
15a2072
-
15a2072
-  grub_dprintf ("blscfg", "%s it\n", f ? "found" : "did not find");
15a2072
-  grub_free (grubenv_path);
15a2072
-  if (f)
15a2072
-    {
15a2072
-      grub_off_t sz;
15a2072
-
15a2072
-      grub_dprintf ("blscfg", "getting size\n");
15a2072
-      sz = grub_file_size (f);
15a2072
-      if (sz == GRUB_FILE_SIZE_UNKNOWN || sz > 1024*1024)
15a2072
-	goto finish;
15a2072
-
15a2072
-      grub_dprintf ("blscfg", "reading env\n");
15a2072
-      env = read_envblk_file (f);
15a2072
-      if (!env)
15a2072
-	goto finish;
15a2072
-      grub_dprintf ("blscfg", "read env file\n");
15a2072
-
15a2072
-      grub_memset (saved_env_buf, '#', 512);
15a2072
-      grub_memcpy (saved_env_buf, GRUB_ENVBLK_SIGNATURE,
15a2072
-		   sizeof (GRUB_ENVBLK_SIGNATURE));
15a2072
-      grub_dprintf ("blscfg", "saving env\n");
15a2072
-      saved_env = grub_envblk_open (saved_env_buf, 512);
15a2072
-      if (!saved_env)
15a2072
-	goto finish;
15a2072
-
15a2072
-      // save everything listed in "env" with values from our existing grub env
15a2072
-      grub_envblk_iterate (env, NULL, save_var);
15a2072
-      // set everything from our loaded grubenv into the real grub env
15a2072
-      grub_envblk_iterate (env, NULL, set_var);
15a2072
-    }
15a2072
-  else
15a2072
-    {
15a2072
-      grub_err_t e;
15a2072
-      grub_dprintf ("blscfg", "no such file\n");
15a2072
-      do
15a2072
-	{
15a2072
-	  e = grub_error_pop();
15a2072
-	} while (e);
15a2072
-
15a2072
-    }
15a2072
 
15a2072
   blsdir = grub_env_get ("blsdir");
15a2072
   if (!blsdir)
15a2072
-    goto finish;
15a2072
+    blsdir = GRUB_BLS_CONFIG_PATH;
15a2072
 
15a2072
-  grub_dprintf ("blscfg", "blsdir: \"%s\"\n", blsdir);
15a2072
-  blsdir = grub_strdup (blsdir);
15a2072
-
15a2072
-  if (!blsdir)
15a2072
-    goto finish;
15a2072
-
15a2072
-  grub_dprintf ("blscfg", "blsdir: \"%s\"\n", blsdir);
15a2072
-  if (info->platform == PLATFORM_EFI) {
15a2072
-    read_entry_info.devid = grub_env_get ("root");
15a2072
-    if (!read_entry_info.devid)
15a2072
-      goto finish;
15a2072
-
15a2072
-    blsdir_dev = grub_device_open (read_entry_info.devid);
15a2072
-    if (!blsdir_dev)
15a2072
-      goto finish;
15a2072
-
15a2072
-    blsdir_fs = grub_fs_probe (blsdir_dev);
15a2072
-    if (!blsdir_fs)
15a2072
-      goto finish;
15a2072
-
15a2072
-  } else {
15a2072
-    read_entry_info.devid = devid;
15a2072
-    blsdir_dev = info->dev;
15a2072
-    blsdir_fs = info->fs;
15a2072
-  }
15a2072
   read_entry_info.dirname = blsdir;
15a2072
 
15a2072
+  grub_dprintf ("blscfg", "scanning blsdir: %s\n", GRUB_BLS_CONFIG_PATH);
15a2072
+
15a2072
+  blsdir_dev = info->dev;
15a2072
+  blsdir_fs = info->fs;
15a2072
+  read_entry_info.devid = info->devid;
15a2072
+
15a2072
 read_fallback:
15a2072
   r = blsdir_fs->dir (blsdir_dev, read_entry_info.dirname, read_entry,
15a2072
 		      &read_entry_info);
15a2072
@@ -809,7 +702,7 @@ read_fallback:
15a2072
 	} while (e);
15a2072
   }
15a2072
 
15a2072
-  if (!nentries && !fallback && info->platform != PLATFORM_EMU) {
15a2072
+  if (!nentries && !fallback) {
15a2072
     read_entry_info.dirname = "/boot" GRUB_BLS_CONFIG_PATH;
15a2072
     grub_dprintf ("blscfg", "Entries weren't found in %s, fallback to %s\n",
15a2072
 		  blsdir, read_entry_info.dirname);
15a2072
@@ -832,41 +725,12 @@ read_fallback:
15a2072
 
15a2072
   for (r = 0; r < nentries; r++)
15a2072
       bls_free_entry (entries[r]);
15a2072
-finish:
15a2072
-  if (info->platform == PLATFORM_EFI && blsdir_dev)
15a2072
-    grub_device_close (blsdir_dev);
15a2072
 
15a2072
   nentries = 0;
15a2072
 
15a2072
   grub_free (entries);
15a2072
   entries = NULL;
15a2072
 
15a2072
-  grub_free ((char *)blsdir);
15a2072
-
15a2072
-  grub_env_unset ("blsdir");
15a2072
-
15a2072
-  if (saved_env)
15a2072
-    {
15a2072
-      // remove everything from the real environment that's defined in env
15a2072
-      grub_envblk_iterate (env, NULL, unset_var);
15a2072
-
15a2072
-      // re-set the things from our original environment
15a2072
-      grub_envblk_iterate (saved_env, NULL, set_var);
15a2072
-      grub_envblk_close (saved_env);
15a2072
-      saved_env = NULL;
15a2072
-    }
15a2072
-  else if (saved_env_buf)
15a2072
-    {
15a2072
-      // if we have a saved environment, grub_envblk_close() freed this.
15a2072
-      grub_free (saved_env_buf);
15a2072
-    }
15a2072
-
15a2072
-  if (env)
15a2072
-    grub_envblk_close (env);
15a2072
-
15a2072
-  if (f)
15a2072
-    grub_file_close (f);
15a2072
-
15a2072
   return 0;
15a2072
 }
15a2072
 
15a2072
@@ -883,7 +747,6 @@ grub_cmd_blscfg (grub_extcmd_context_t ctxt UNUSED,
15a2072
     {
15a2072
       .dev = NULL,
15a2072
       .fs = NULL,
15a2072
-      .platform = PLATFORM_BIOS,
15a2072
     };
15a2072
 
15a2072
 
15a2072
@@ -891,13 +754,14 @@ grub_cmd_blscfg (grub_extcmd_context_t ctxt UNUSED,
15a2072
 
15a2072
 #ifdef GRUB_MACHINE_EMU
15a2072
   devid = "host";
15a2072
-  grub_env_set ("boot", devid);
15a2072
+#elif defined(GRUB_MACHINE_EFI)
15a2072
+  devid = grub_env_get ("root");
15a2072
 #else
15a2072
   devid = grub_env_get ("boot");
15a2072
+#endif
15a2072
   if (!devid)
15a2072
     return grub_error (GRUB_ERR_FILE_NOT_FOUND,
15a2072
 		       N_("variable `%s' isn't set"), "boot");
15a2072
-#endif
15a2072
 
15a2072
   grub_dprintf ("blscfg", "opening %s\n", devid);
15a2072
   dev = grub_device_open (devid);
15a2072
@@ -912,21 +776,10 @@ grub_cmd_blscfg (grub_extcmd_context_t ctxt UNUSED,
15a2072
       goto finish;
15a2072
     }
15a2072
 
15a2072
+  info.devid = devid;
15a2072
   info.dev = dev;
15a2072
   info.fs = fs;
15a2072
-#ifdef GRUB_MACHINE_EFI
15a2072
-  info.platform = PLATFORM_EFI;
15a2072
-  grub_dprintf ("blscfg", "scanning /EFI/\n");
15a2072
-  r = fs->dir (dev, "/EFI/", find_entry, &info;;
15a2072
-#elif defined(GRUB_MACHINE_EMU)
15a2072
-  info.platform = PLATFORM_EMU;
15a2072
-  grub_dprintf ("blscfg", "scanning %s%s\n", GRUB_BOOT_DEVICE,
15a2072
-		GRUB_BLS_CONFIG_PATH);
15a2072
-  find_entry(NULL, NULL, &info;;
15a2072
-#else
15a2072
-  grub_dprintf ("blscfg", "scanning %s\n", GRUB_BLS_CONFIG_PATH);
15a2072
-  find_entry(NULL, NULL, &info;;
15a2072
-#endif
15a2072
+  find_entry(&info;;
15a2072
 
15a2072
 finish:
15a2072
   if (dev)