Le mar. 25 mars 2025, 10:15, Alec Brown <alec.r.br...@oracle.com> a écrit :

> Irritatingly, BLS defines paths relatives 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     |  4 +++
>  grub-core/commands/blsuki.c     | 54 ++++++++++++++++++++++++++++-----
>  grub-core/osdep/linux/getroot.c |  8 +++++
>  grub-core/osdep/unix/getroot.c  | 10 ++++++
>  include/grub/emu/misc.h         |  2 +-
>  5 files changed, 70 insertions(+), 8 deletions(-)
>
> diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
> index f3b776c0a..9a0e7bc55 100644
> --- a/grub-core/Makefile.core.def
> +++ b/grub-core/Makefile.core.def
> @@ -367,6 +367,10 @@ 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/devmapper/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 0f77fb568..12a9a1ed1 100644
> --- a/grub-core/commands/blsuki.c
> +++ b/grub-core/commands/blsuki.c
> @@ -32,6 +32,13 @@
>  #include <grub/lib/envblk.h>
>  #include <grub/lib/vercmp.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/"
> @@ -53,8 +60,40 @@ struct keyval
>
>  static grub_blsuki_entry_t *entries = NULL;
>
> +/*
> + * Cache probing in blsuki_update_boot_device(). Used for linux entry
> also.
> + */
> +static int separate_boot = -1;
>

On non-emu it's an unused static. It might trigger a warning. I'd prefer
this to be inside ifdef.

+
>  #define FOR_BLSUKI_ENTRIES(var) FOR_LIST_ELEMENTS (var, entries)
>
> +/*
> + * 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)
> +    separate_boot = 1;
>
Are you sure that != NULL is the right check? It looks like it should be
strcmp with "/". How do you get a NULL here? Shouldn't happen if the path
exists.

> +
> + probed:
> +  if (!separate_boot)
> +    return grub_stpcpy (tmp, " ");
> +#endif
> +
> +  return grub_stpcpy (tmp, " " GRUB_BOOT_DEVICE);
> +}
> +
>  static grub_err_t
>  blsuki_add_keyval (grub_blsuki_entry_t *entry, char *key, char *val)
>  {
> @@ -645,7 +684,7 @@ bls_create_entry (grub_blsuki_entry_t *entry)
>
>        for (i = 0; early_initrds != NULL && early_initrds[i] != NULL; i++)
>         {
> -         if (grub_add (initrd_size, sizeof (" "), &initrd_size) ||
> +         if (grub_add (initrd_size, sizeof (" " GRUB_BOOT_DEVICE),
> &initrd_size) ||
>               grub_add (initrd_size, grub_strlen (initrd_prefix),
> &initrd_size) ||
>               grub_add (initrd_size, grub_strlen (early_initrds[i]),
> &initrd_size) ||
>               grub_add (initrd_size, 1, &initrd_size))
> @@ -657,7 +696,7 @@ bls_create_entry (grub_blsuki_entry_t *entry)
>
>        for (i = 0; initrds != NULL && initrds[i] != NULL; i++)
>         {
> -         if (grub_add (initrd_size, sizeof (" "), &initrd_size) ||
> +         if (grub_add (initrd_size, sizeof (" " GRUB_BOOT_DEVICE),
> &initrd_size) ||
>               grub_add (initrd_size, grub_strlen (initrds[i]),
> &initrd_size) ||
>               grub_add (initrd_size, 1, &initrd_size))
>             {
> @@ -683,7 +722,7 @@ bls_create_entry (grub_blsuki_entry_t *entry)
>        for (i = 0; early_initrds != NULL && early_initrds[i] != NULL; i++)
>         {
>           grub_dprintf ("blsuki", "adding early initrd %s\n",
> early_initrds[i]);
> -         tmp = grub_stpcpy (tmp, " ");
> +         tmp = blsuki_update_boot_device (tmp);
>           tmp = grub_stpcpy (tmp, initrd_prefix);
>           tmp = grub_stpcpy (tmp, early_initrds[i]);
>           grub_free (early_initrds[i]);
> @@ -692,7 +731,7 @@ bls_create_entry (grub_blsuki_entry_t *entry)
>        for (i = 0; initrds != NULL && initrds[i] != NULL; i++)
>         {
>           grub_dprintf ("blsuki", "adding initrd %s\n", initrds[i]);
> -         tmp = grub_stpcpy (tmp, " ");
> +         tmp = blsuki_update_boot_device (tmp);
>           tmp = grub_stpcpy (tmp, initrds[i]);
>         }
>        tmp = grub_stpcpy (tmp, "\n");
> @@ -711,7 +750,7 @@ bls_create_entry (grub_blsuki_entry_t *entry)
>             }
>         }
>
> -      if (grub_add (sizeof ("devicetree "), grub_strlen (devicetree),
> &dt_size) ||
> +      if (grub_add (sizeof ("devicetree " GRUB_BOOT_DEVICE), grub_strlen
> (devicetree), &dt_size) ||
>           grub_add (dt_size, 1, &dt_size))
>         {
>           grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow detected
> calculating device tree buffer size");
> @@ -735,7 +774,7 @@ bls_create_entry (grub_blsuki_entry_t *entry)
>         }
>        tmp = dt;
>        tmp = grub_stpcpy (dt, "devicetree");
> -      tmp = grub_stpcpy (tmp, " ");
> +      tmp = blsuki_update_boot_device (tmp);
>        if (add_dt_prefix == true)
>         tmp = grub_stpcpy (tmp, prefix);
>        tmp = grub_stpcpy (tmp, devicetree);
> @@ -748,9 +787,10 @@ bls_create_entry (grub_blsuki_entry_t *entry)
>
>    sdval = grub_env_get ("save_default");
>    savedefault = ((NULL != sdval) && (grub_strcmp (sdval, "true") == 0));
> -  src = grub_xasprintf ("%slinux %s%s%s\n"
> +  src = grub_xasprintf ("%slinux %s%s%s%s\n"
>                         "%s%s",
>                         savedefault ? "savedefault\n" : "",
> +                       separate_boot ? GRUB_BOOT_DEVICE : "",
>                         clinux, options ? " " : "", options ? options : "",
>                         initrd ? initrd : "", dt ? dt : "");
>
> diff --git a/grub-core/osdep/linux/getroot.c
> b/grub-core/osdep/linux/getroot.c
> index 527d4f0c5..2fc212276 100644
> --- a/grub-core/osdep/linux/getroot.c
> +++ b/grub-core/osdep/linux/getroot.c
> @@ -131,6 +131,7 @@ struct mountinfo_entry
>    char fstype[ESCAPED_PATH_MAX + 1], device[ESCAPED_PATH_MAX + 1];
>  };
>
> +#ifdef GRUB_UTIL
>  static char **
>  grub_util_raid_getmembers (const char *name, int bootable)
>  {
> @@ -191,6 +192,7 @@ grub_util_raid_getmembers (const char *name, int
> bootable)
>
>    return devicelist;
>  }
> +#endif
>
>  /* Statting something on a btrfs filesystem always returns a virtual
> device
>     major/minor pair rather than the real underlying device, because btrfs
> @@ -579,6 +581,7 @@ out:
>    return ret;
>  }
>
> +#ifdef GRUB_UTIL
>  static char *
>  get_mdadm_uuid (const char *os_dev)
>  {
> @@ -636,6 +639,7 @@ out:
>
>    return name;
>  }
> +#endif
>
>  static int
>  grub_util_is_imsm (const char *os_dev)
> @@ -968,6 +972,7 @@ grub_util_part_to_disk (const char *os_dev, struct
> stat *st,
>    return path;
>  }
>
> +#ifdef GRUB_UTIL
>  static char *
>  grub_util_get_raid_grub_dev (const char *os_dev)
>  {
> @@ -1070,6 +1075,7 @@ grub_util_get_raid_grub_dev (const char *os_dev)
>    }
>    return grub_dev;
>  }
> +#endif
>
>  enum grub_dev_abstraction_types
>  grub_util_get_dev_abstraction_os (const char *os_dev)
> @@ -1086,6 +1092,7 @@ grub_util_get_dev_abstraction_os (const char *os_dev)
>    return GRUB_DEV_ABSTRACTION_NONE;
>  }
>
> +#ifdef GRUB_UTIL
>  int
>  grub_util_pull_device_os (const char *os_dev,
>                           enum grub_dev_abstraction_types ab)
> @@ -1142,6 +1149,7 @@ grub_util_get_grub_dev_os (const char *os_dev)
>
>    return grub_dev;
>  }
> +#endif
>
>  char *
>  grub_make_system_path_relative_to_its_root_os (const char *path)
> diff --git a/grub-core/osdep/unix/getroot.c
> b/grub-core/osdep/unix/getroot.c
> index c7aa202ab..1380638d3 100644
> --- a/grub-core/osdep/unix/getroot.c
> +++ b/grub-core/osdep/unix/getroot.c
> @@ -17,6 +17,14 @@
>   */
>
>  #include <config.h>
> +#undef _GL_INLINE_HEADER_BEGIN
> +#undef _GL_INLINE_HEADER_END
> +#undef _GL_GNUC_PREREQ
> +#undef _GL_ATTRIBUTE_COLD
> +#undef _GL_ATTRIBUTE_CONST
> +#undef _GL_ATTRIBUTE_DEALLOC
> +#undef _GL_ATTRIBUTE_FALLTHROUGH
> +#undef _GL_ATTRIBUTE_MALLOC
>  #include <config-util.h>
>
>  #include <sys/stat.h>
> @@ -566,6 +574,7 @@ grub_guess_root_devices (const char *dir_in)
>
>  #endif
>
> +#ifdef GRUB_UTIL
>  void
>  grub_util_pull_lvm_by_command (const char *os_dev)
>  {
> @@ -662,6 +671,7 @@ out:
>    free (buf);
>    free (vgid);
>  }
> +#endif
>
>  /* ZFS has similar problems to those of btrfs (see above).  */
>  void
> diff --git a/include/grub/emu/misc.h b/include/grub/emu/misc.h
> index fefbec499..542f4c18d 100644
> --- a/include/grub/emu/misc.h
> +++ b/include/grub/emu/misc.h
> @@ -39,7 +39,7 @@ void grub_fini_all (void);
>  void grub_find_zpool_from_dir (const char *dir,
>                                char **poolname, char **poolfs);
>
> -char *grub_make_system_path_relative_to_its_root (const char *path)
> +char * EXPORT_FUNC(grub_make_system_path_relative_to_its_root) (const
> char *path)
>   WARN_UNUSED_RESULT;
>  int
>  grub_util_device_is_mapped (const char *dev);
> --
> 2.27.0
>
>
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to