On Sun, Jul 27, 2025 at 01:54:35AM +0000, Alec Brown wrote:
> From: Robbie Harwood <rharw...@redhat.com>
>
> Irritatingly, BLS defines paths relative to the mountpoint of the
> filesystem which contains its snippets, not / or any other fixed
> location. So grub2-emu needs to know whether /boot is a separate
> filesystem from / and conditionally prepend a path.
>
> Signed-off-by: Robbie Harwood <rharw...@redhat.com>
> Signed-off-by: Alec Brown <alec.r.br...@oracle.com>
> ---
>  grub-core/Makefile.core.def     |  3 ++
>  grub-core/commands/blsuki.c     | 89 ++++++++++++++++++++++++++++++---
>  grub-core/osdep/linux/getroot.c |  8 +++
>  grub-core/osdep/unix/getroot.c  |  4 +-
>  include/grub/emu/misc.h         |  2 +-
>  5 files changed, 97 insertions(+), 9 deletions(-)
>
> diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
> index 996a1c2ae..9488654fb 100644
> --- a/grub-core/Makefile.core.def
> +++ b/grub-core/Makefile.core.def
> @@ -367,6 +367,9 @@ kernel = {
>    emu = kern/emu/cache_s.S;
>    emu = kern/emu/hostdisk.c;
>    emu = osdep/unix/hostdisk.c;
> +  emu = osdep/relpath.c;
> +  emu = osdep/getroot.c;
> +  emu = osdep/unix/getroot.c;
>    emu = osdep/exec.c;
>    extra_dist = osdep/unix/exec.c;
>    emu = osdep/devmapper/hostdisk.c;
> diff --git a/grub-core/commands/blsuki.c b/grub-core/commands/blsuki.c
> index c275dbb92..76615e9bc 100644
> --- a/grub-core/commands/blsuki.c
> +++ b/grub-core/commands/blsuki.c
> @@ -32,6 +32,13 @@
>  #include <grub/lib/envblk.h>
>  #include <filevercmp.h>
>
> +#ifdef GRUB_MACHINE_EMU
> +#include <grub/emu/misc.h>
> +#define GRUB_BOOT_DEVICE "/boot"
> +#else
> +#define GRUB_BOOT_DEVICE ""
> +#endif
> +
>  GRUB_MOD_LICENSE ("GPLv3+");
>
>  #define GRUB_BLS_CONFIG_PATH "/loader/entries/"
> @@ -75,6 +82,40 @@ static grub_blsuki_entry_t *entries;
>
>  #define FOR_BLSUKI_ENTRIES(var) FOR_LIST_ELEMENTS (var, entries)
>
> +#ifdef GRUB_MACHINE_EMU
> +/*
> + * Cache probing in blsuki_update_boot_device().
> + */
> +static int separate_boot = -1;

You can make it a static in the function...

> +#endif
> +
> +/*
> + * BLS appears to make paths relative to the filesystem that snippets are
> + * on, not /. Attempt to cope.
> + */
> +static char *blsuki_update_boot_device (char *tmp)
> +{
> +#ifdef GRUB_MACHINE_EMU
> +  char *ret;
> +
> +  if (separate_boot != -1)
> +    goto probed;
> +
> +  separate_boot = 0;
> +
> +  ret = grub_make_system_path_relative_to_its_root (GRUB_BOOT_DEVICE);
> +
> +  if (ret != NULL && ret[0] == '\0')
> +    separate_boot = 1;
> +
> + probed:
> +  if (!separate_boot)
> +    return tmp;
> +#endif
> +
> +  return grub_stpcpy (tmp, GRUB_BOOT_DEVICE);
> +}

[...]

> -static void
> +static grub_err_t
>  blsuki_find_entry (struct find_entry_info *info, bool enable_fallback)
>  {
>    struct read_entry_info read_entry_info;
> +  char *default_dir = NULL;
> +  char *tmp;
> +  grub_size_t default_size;
>    grub_fs_t dir_fs = NULL;
>    grub_device_t dir_dev = NULL;
>    bool fallback = false;
> @@ -837,7 +888,15 @@ blsuki_find_entry (struct find_entry_info *info, bool 
> enable_fallback)
>         */
>        if (entries == NULL && fallback == false && enable_fallback == true)
>       {
> -       blsuki_set_find_entry_info (info, GRUB_BLS_CONFIG_PATH, NULL);
> +       default_size = sizeof (GRUB_BOOT_DEVICE) + sizeof 
> (GRUB_BLS_CONFIG_PATH) - 2;

s/2/1/?

> +       default_dir = grub_malloc (default_size);
> +       if (default_dir == NULL)
> +         return grub_errno;
> +
> +       tmp = blsuki_update_boot_device (default_dir);
> +       tmp = grub_stpcpy (tmp, GRUB_BLS_CONFIG_PATH);
> +
> +       blsuki_set_find_entry_info (info, default_dir, NULL);
>         grub_dprintf ("blsuki", "Entries weren't found in %s, fallback to 
> %s\n",
>                       read_entry_info.dirname, info->dirname);
>         fallback = true;
> @@ -846,6 +905,9 @@ blsuki_find_entry (struct find_entry_info *info, bool 
> enable_fallback)
>       fallback = false;
>      }
>    while (fallback == true);
> +
> +  grub_free (default_dir);
> +  return GRUB_ERR_NONE;
>  }
>
>  static grub_err_t
> @@ -855,6 +917,9 @@ blsuki_load_entries (char *path, bool enable_fallback)
>    static grub_err_t r;
>    const char *devid = NULL;
>    char *dir = NULL;
> +  char *default_dir = NULL;
> +  char *tmp;
> +  grub_size_t dir_size;
>    struct find_entry_info info = {
>        .dev = NULL,
>        .fs = NULL,
> @@ -896,15 +961,25 @@ blsuki_load_entries (char *path, bool enable_fallback)
>      }
>
>    if (dir == NULL)
> -    dir = (char *) GRUB_BLS_CONFIG_PATH;
> +    {
> +      dir_size = sizeof (GRUB_BOOT_DEVICE) + sizeof (GRUB_BLS_CONFIG_PATH) - 
> 2;
> +      default_dir = grub_malloc (dir_size);
> +      if (default_dir == NULL)
> +     return grub_errno;
> +
> +      tmp = blsuki_update_boot_device (default_dir);
> +      tmp = grub_stpcpy (tmp, GRUB_BLS_CONFIG_PATH);
> +      dir = default_dir;
> +    }
>
>    r = blsuki_set_find_entry_info (&info, dir, devid);
>    if (r == GRUB_ERR_NONE)
> -    blsuki_find_entry (&info, enable_fallback);
> +    r = blsuki_find_entry (&info, enable_fallback);
>
>    if (info.dev != NULL)
>      grub_device_close (info.dev);
>
> +  grub_free (default_dir);
>    return r;
>  }

Daniel

_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to