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
