All of lore.kernel.org
 help / color / mirror / Atom feed
From: Avnish Chouhan <avnish@linux.ibm.com>
To: grub-devel@gnu.org
Cc: brking@linux.ibm.com, meghanaprakash@in.ibm.com,
	Avnish Chouhan <avnish@linux.ibm.com>
Subject: [PATCH v2] ieee1275: support added for multiple nvme bootpaths
Date: Mon, 19 May 2025 16:34:34 +0530	[thread overview]
Message-ID: <20250519110434.28686-1-avnish@linux.ibm.com> (raw)

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 | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 grub-core/osdep/linux/ofpath.c  |   6 +++---
 include/grub/util/install.h     |   3 +++
 include/grub/util/ofpath.h      |   4 ++++
 4 files changed, 123 insertions(+), 4 deletion(-)

diff --git a/grub-core/osdep/unix/platform.c b/grub-core/osdep/unix/platform.c
index 55b8f40..124e0ed 100644
--- a/grub-core/osdep/unix/platform.c
+++ b/grub-core/osdep/unix/platform.c
@@ -28,6 +28,8 @@
 #include <dirent.h>
 #include <string.h>
 #include <errno.h>
+#include <grub/util/ofpath.h>
+#define BOOTDEV_BUFFER  1000
 
 static char *
 get_ofpathname (const char *dev)
@@ -176,6 +178,105 @@ 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;
+  int is_FC = 0, is_splitter = 0;
+
+  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 = 1;
+    }
+  else
+    {
+      strcat (sysfs_path, "/subsystem");
+      is_FC = 0;
+    }
+  if (is_FC == 0)
+    {
+      cntl_id = grub_strstr (nvme_ns, "e");
+      dirR1 = xasprintf ("nvme%c",cntl_id[1]);
+
+      splitter_info_path = xasprintf ("%s%s%s", "/sys/block/", nvme_ns, "/device");
+      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_strstr (splitter_ep->d_name, "e");
+              if (!(grub_strstr (ext_dir, "n")))
+	         {
+                  dirR2 = xasprintf("%s", splitter_ep->d_name);
+	           is_splitter = 1;
+	           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 == 0 && is_FC == 0)
+    {
+      non_splitter_path = xasprintf ("%s%s%x:1 ", get_ofpathname (dirR1), "/namespace@", 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"))
+            {
+              if (is_FC == 0 && !grub_strstr (ep->d_name, dirR1) && !grub_strstr (ep->d_name, dirR2))
+                continue;
+              path = xasprintf ("%s%s%x ", get_ofpathname (ep->d_name), "/namespace@", 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 +316,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..48f11c9 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;
@@ -224,7 +224,7 @@ xrealpath (const char *in)
   return out;
 }

-static char *
+char *
 block_device_get_sysfs_path_and_link(const char *devicenode)
 {
   char *rpath;
@@ -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);
+char* block_device_get_sysfs_path_and_link (const char *devicenode);
+char* xrealpath (const char *in);
+unsigned int of_path_get_nvme_nsid (const char* devname);
 
 #endif /* ! GRUB_OFPATH_MACHINE_UTIL_HEADER */
-- 
2.39.3


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

             reply	other threads:[~2025-05-19 11:05 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-05-19 11:04 Avnish Chouhan [this message]
2025-05-26 19:30 ` [PATCH v2] ieee1275: support added for multiple nvme bootpaths Daniel Kiper
2025-05-28 11:20   ` Avnish Chouhan
2025-05-28 17:56     ` Daniel Kiper
2025-05-29  6:29       ` Avnish Chouhan
2025-05-29 16:22         ` Daniel Kiper
2025-06-03  6:03           ` Avnish Chouhan

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=20250519110434.28686-1-avnish@linux.ibm.com \
    --to=avnish@linux.ibm.com \
    --cc=brking@linux.ibm.com \
    --cc=grub-devel@gnu.org \
    --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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.