dcavalca / rpms / grub2

Forked from rpms/grub2 3 years ago
Clone

Blame SOURCES/0212-blscfg-remove-logic-to-read-the-grubenv-file-and-set.patch

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