Regards
Vladimir 'phcoder' Serbinenko

Le lun. 23 févr. 2026, 16:46, Avnish Chouhan <[email protected]> a
écrit :

> This patch sets mupltiple NVMe boot-devices for more robust boot.
> Scenario where NVMe multipaths are available, all the available bootpaths
> (Max 5)
> will be added as the boot-device.
>
> Signed-off-by: Avnish Chouhan <[email protected]>
> ---
>  grub-core/osdep/unix/platform.c | 118
> ++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  grub-core/osdep/linux/ofpath.c  |   4 ++--
>  include/grub/util/install.h     |   3 +++
>  include/grub/util/ofpath.h      |   4 ++++
>  4 file changed, 126 insertions(+), 3 deletion(-)
>
> diff --git a/grub-core/osdep/unix/platform.c
> b/grub-core/osdep/unix/platform.c
> index de71221..4632f41 100644
> --- a/grub-core/osdep/unix/platform.c
> +++ b/grub-core/osdep/unix/platform.c
> @@ -28,6 +28,10 @@
>  #include <dirent.h>
>  #include <string.h>
>  #include <errno.h>
> +#include <grub/util/ofpath.h>
> +#include <stdbool.h>
> +
> +#define BOOTDEV_BUFFER  1000
>
>  static char *
>  get_ofpathname (const char *dev)
> @@ -176,6 +180,107 @@ grub_install_register_efi (grub_device_t
> efidir_grub_dev,
>    return ret;
>  }
>
> +
> +char *
> +add_multiple_nvme_bootdevices (const char *install_device)
>
Either make it static or add proper namespacing.

+{
> +  char *sysfs_path, *nvme_ns, *ptr, *non_splitter_path;
> +  unsigned int nsid;
> +  char *multipath_boot, *ofpath, *ext_dir;
> +  struct dirent *ep, *splitter_ep;
> +  DIR *dp, *splitter_dp;
> +  char *cntl_id, *dirR1, *dirR2, *splitter_info_path;
> +  bool is_FC = false, is_splitter = false;
> +
> +  nvme_ns = grub_strstr (install_device, "nvme");
> +  nsid = of_path_get_nvme_nsid (nvme_ns);
> +  if (nsid == 0)
> +    return NULL;
> +
> +  sysfs_path = nvme_get_syspath (nvme_ns);
> +  ofpath = xasprintf ("%s", get_ofpathname (nvme_ns));
>
Use (x)strdup

> +
> +  if (grub_strstr (ofpath, "fibre-channel"))
> +    {
> +      strcat (sysfs_path, "/device");
> +      is_FC = true;
> +    }
> +  else
> +    {
> +      strcat (sysfs_path, "/subsystem");
> +      is_FC = false;
> +    }
>
Where do you ensure sufficient space in sysfs_path?

> +  if (is_FC == false)
> +    {
> +      cntl_id = grub_strstr (nvme_ns, "e");
>
Use strchr

> +      dirR1 = xasprintf ("nvme%c",cntl_id[1]);
> +
> +      splitter_info_path = xasprintf ("/sys/block/%s/device", nvme_ns);
> +      splitter_dp = opendir (splitter_info_path);
> +      if (!splitter_dp)
> +        return NULL;
> +
> +      while ((splitter_ep = readdir (splitter_dp)) != NULL)
> +        {
> +          if (grub_strstr (splitter_ep->d_name, "nvme"))
> +           {
> +             if (grub_strstr (splitter_ep->d_name, dirR1))
> +               continue;
> +
> +              ext_dir = grub_strchr (splitter_ep->d_name, 'e');
> +              if (grub_strchr (ext_dir, 'n') == NULL)
> +               {
> +                  dirR2 = xasprintf("%s", splitter_ep->d_name);
> +                 is_splitter = true;
> +                 break;
> +               }
> +           }
> +        }
> +      closedir (splitter_dp);
> +    }
> +  sysfs_path = xrealpath (sysfs_path);
> +  dp = opendir (sysfs_path);
> +  if (!dp)
> +    return NULL;
> +
> +  ptr = multipath_boot = xmalloc (BOOTDEV_BUFFER);
> +  if (is_splitter == false && is_FC == false)
> +    {
> +      non_splitter_path = xasprintf ("%s/namespace@%x:1 ",
> get_ofpathname (dirR1), nsid);
> +      strncpy (ptr, non_splitter_path, strlen (non_splitter_path));
> +      ptr += strlen (non_splitter_path);
>
Use stpcpy

> +      free (non_splitter_path);
> +    }
> +  else
> +    {
> +      while ((ep = readdir (dp)) != NULL)
> +        {
> +          char *path;
> +
> +          if (grub_strstr (ep->d_name, "nvme") != NULL)
> +            {
> +              if (is_FC == false && grub_strstr (ep->d_name, dirR1) ==
> NULL &&
> +                  grub_strstr (ep->d_name, dirR2) == NULL)
> +                continue;
> +              path = xasprintf ("%s/namespace@%x ", get_ofpathname
> (ep->d_name), nsid);
> +              if ((strlen (multipath_boot) + strlen (path)) >
> BOOTDEV_BUFFER)
> +                {
> +                  grub_util_warn (_("Maximum five entries are allowed in
> the bootlist"));
> +                  free (path);
> +                  break;
> +                }
> +              strncpy (ptr, path, strlen (path));
> +              ptr += strlen (path);
>
Ditto

> +              free (path);
> +            }
> +        }
> +    }
> +  *--ptr = '\0';
> +  closedir (dp);
> +
> +  return multipath_boot;
> +}
> +
>  void
>  grub_install_register_ieee1275 (int is_prep, const char *install_device,
>                                 int partno, const char *relpath)
> @@ -215,8 +320,19 @@ grub_install_register_ieee1275 (int is_prep, const
> char *install_device,
>         }
>        *ptr = '\0';
>      }
> +  else if (grub_strstr (install_device, "nvme"))
> +    {
> +      boot_device = add_multiple_nvme_bootdevices (install_device);
>
What happens if I install via an UUID symlink? What happens if I install on
a file (disk image) named nvme1?

> +    }
>    else
> -    boot_device = get_ofpathname (install_device);
> +    {
> +      boot_device = get_ofpathname (install_device);
> +      if (grub_strstr (boot_device, "nvme-of"))
> +        {
> +          free (boot_device);
> +          boot_device = add_multiple_nvme_bootdevices (install_device);
> +        }
> +    }
>
>    if (grub_util_exec ((const char * []){ "nvsetenv", "boot-device",
>           boot_device, NULL }))
> diff --git a/grub-core/osdep/linux/ofpath.c
> b/grub-core/osdep/linux/ofpath.c
> index 7158c8c..3a778e0 100644
> --- a/grub-core/osdep/linux/ofpath.c
> +++ b/grub-core/osdep/linux/ofpath.c
> @@ -209,7 +209,7 @@ find_obppath (const char *sysfs_path_orig)
>      }
>  }
>
> -static char *
> +char *
>  xrealpath (const char *in)
>
Please add namespacing.

>  {
>    char *out;
> @@ -684,7 +684,7 @@ of_path_get_nvme_nsid (const char* devname)
>    return nsid;
>  }
>
> -static char *
> +char *
>  nvme_get_syspath (const char *nvmedev)
>
Ditto

>  {
>    char *sysfs_path;
> diff --git a/include/grub/util/install.h b/include/grub/util/install.h
> index 51f3b13..a67e225 100644
> --- a/include/grub/util/install.h
> +++ b/include/grub/util/install.h
> @@ -235,6 +235,9 @@ grub_install_register_efi (grub_device_t
> efidir_grub_dev,
>                            const char *efifile_path,
>                            const char *efi_distributor);
>
> +char *
> +add_multiple_nvme_bootdevices (const char *install_device);
> +
>  void
>  grub_install_register_ieee1275 (int is_prep, const char *install_device,
>                                 int partno, const char *relpath);
> diff --git a/include/grub/util/ofpath.h b/include/grub/util/ofpath.h
> index 5962322..78e78e7 100644
> --- a/include/grub/util/ofpath.h
> +++ b/include/grub/util/ofpath.h
> @@ -30,5 +30,9 @@ int add_filename_to_pile (char *filename, struct
> ofpath_files_list_root* root);
>  void find_file (char* filename, char* directory, struct
> ofpath_files_list_root* root, int max_depth, int depth);
>  char* of_find_fc_host (char* host_wwpn);
>  void free_ofpath_files_list (struct ofpath_files_list_root* root);
> +char* nvme_get_syspath (const char *nvmedev);
> +unsigned int of_path_get_nvme_nsid (const char* devname);
> +char* xrealpath (const char *in);
> +
>
>  #endif /* ! GRUB_OFPATH_MACHINE_UTIL_HEADER */
> --
> 2.50.1 (Apple Git-155)
>
>
> _______________________________________________
> Grub-devel mailing list
> [email protected]
> https://lists.gnu.org/mailman/listinfo/grub-devel
>
_______________________________________________
Grub-devel mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to