|
|
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)
|