grub-devel.gnu.org archive mirror
 help / color / mirror / Atom feed
From: Avnish Chouhan <avnish@linux.ibm.com>
To: grub-devel@gnu.org
Cc: daniel.kiper@oracle.com, brking@linux.ibm.com,
	meghanaprakash@in.ibm.com,  mchang@suse.com,
	Avnish Chouhan <avnish@linux.ibm.com>
Subject: [PATCH v6 6/6] ieee1275: support added for multiple nvme bootpaths
Date: Wed, 30 Jul 2025 11:04:05 +0530	[thread overview]
Message-ID: <20250730053405.41417-7-avnish@linux.ibm.com> (raw)
In-Reply-To: <20250730053405.41417-1-avnish@linux.ibm.com>

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 <avnish@linux.ibm.com>
---
 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)
+{
+  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));
+
+  if (grub_strstr (ofpath, "fibre-channel"))
+    {
+      strcat (sysfs_path, "/device");
+      is_FC = true;
+    }
+  else
+    {
+      strcat (sysfs_path, "/subsystem");
+      is_FC = false;
+    }
+  if (is_FC == false)
+    {
+      cntl_id = grub_strstr (nvme_ns, "e");
+      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);
+      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);
+              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);
+    }
   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)
 {
   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)
 {
   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.43.0


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

      parent reply	other threads:[~2025-07-30  5:37 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-07-30  5:33 [PATCH v6 0/6] NVMeoFC support on Grub Avnish Chouhan
2025-07-30  5:34 ` [PATCH v6 1/6] ieee1275/powerpc: implements fibre channel discovery for ofpathname Avnish Chouhan
2025-07-30  5:34 ` [PATCH v6 2/6] ieee1275: implement FCP methods for WWPN and LUNs Avnish Chouhan
2025-07-30  5:34 ` [PATCH v6 3/6] ieee1275: change the logic of ieee1275_get_devargs() Avnish Chouhan
2025-07-30  5:34 ` [PATCH v6 4/6] ieee1275: add support for NVMeoFC Avnish Chouhan
2025-07-30  5:34 ` [PATCH v6 5/6] ieee1275: ofpath enable NVMeoF logical device translate Avnish Chouhan
2025-07-30  5:34 ` Avnish Chouhan [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250730053405.41417-7-avnish@linux.ibm.com \
    --to=avnish@linux.ibm.com \
    --cc=brking@linux.ibm.com \
    --cc=daniel.kiper@oracle.com \
    --cc=grub-devel@gnu.org \
    --cc=mchang@suse.com \
    --cc=meghanaprakash@in.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).