ieee1275/powerpc: implements fibre channel discovery for ofpathname
Resolves: #RHEL-53369 Signed-off-by: Nicolas Frayer <nfrayer@redhat.com>
This commit is contained in:
parent
eb2783a08c
commit
c4ea783e4d
120
0538-ieee1275-powerpc-implements-fibre-channel-discovery-.patch
Normal file
120
0538-ieee1275-powerpc-implements-fibre-channel-discovery-.patch
Normal file
@ -0,0 +1,120 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
Date: Thu, 18 Jun 2026 10:49:54 +0200
|
||||
Subject: [PATCH] ieee1275/powerpc: implements fibre channel discovery for
|
||||
ofpathname
|
||||
|
||||
grub-ofpathname doesn't work with fibre channel because there is no
|
||||
function currently implemented for it.
|
||||
This patch enables it by prividing a function that looks for the port
|
||||
name, building the entire path for OF devices.
|
||||
|
||||
Signed-off-by: Diego Domingos <diegodo@br.ibm.com>
|
||||
Signed-off-by: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
Reviewed-by: Leo Sandoval <lsandova@redhat.com>
|
||||
Reviewed-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Part-of: <https://gitlab.freedesktop.org/gnu-grub/grub/-/merge_requests/146>
|
||||
---
|
||||
grub-core/osdep/linux/ofpath.c | 58 +++++++++++++++++++++---------------------
|
||||
1 file changed, 29 insertions(+), 29 deletions(-)
|
||||
|
||||
diff --git a/grub-core/osdep/linux/ofpath.c b/grub-core/osdep/linux/ofpath.c
|
||||
index cc849d9c94c3..9ba1db74aadf 100644
|
||||
--- a/grub-core/osdep/linux/ofpath.c
|
||||
+++ b/grub-core/osdep/linux/ofpath.c
|
||||
@@ -351,36 +351,36 @@ of_path_of_ide(const char *sys_devname __attribute__((unused)), const char *devi
|
||||
return ret;
|
||||
}
|
||||
|
||||
-
|
||||
+#define BNAME_SIZE 150
|
||||
static void
|
||||
-of_fc_port_name(const char *path, const char *subpath, char *port_name)
|
||||
+of_fc_port_name (const char *path, const char *subpath, char *port_name)
|
||||
{
|
||||
char *bname, *basepath, *p;
|
||||
int fd;
|
||||
|
||||
- bname = xmalloc(sizeof(char)*150);
|
||||
- basepath = xmalloc(strlen(path));
|
||||
+ bname = xmalloc (sizeof (char) * BNAME_SIZE);
|
||||
+ basepath = xmalloc (strlen (path));
|
||||
|
||||
/* Generate the path to get port name information from the drive */
|
||||
- strncpy(basepath,path,subpath-path);
|
||||
- basepath[subpath-path-1] = '\0';
|
||||
- p = get_basename(basepath);
|
||||
- snprintf(bname,sizeof(char)*150,"%s/fc_transport/%s/port_name",basepath,p);
|
||||
+ strncpy (basepath, path, subpath-path);
|
||||
+ basepath[subpath-path - 1] = '\0';
|
||||
+ p = get_basename (basepath);
|
||||
+ snprintf (bname, sizeof (char) * BNAME_SIZE, "%s/fc_transport/%s/port_name", basepath, p);
|
||||
|
||||
/* Read the information from the port name */
|
||||
fd = open (bname, O_RDONLY);
|
||||
if (fd < 0)
|
||||
grub_util_error (_("cannot open `%s': %s"), bname, strerror (errno));
|
||||
|
||||
- if (read(fd,port_name,sizeof(char)*19) < 0)
|
||||
+ if (read (fd, port_name, sizeof (char) *19) < 0)
|
||||
grub_util_error (_("cannot read `%s': %s"), bname, strerror (errno));
|
||||
|
||||
- sscanf(port_name,"0x%s",port_name);
|
||||
-
|
||||
- close(fd);
|
||||
+ sscanf (port_name, "0x%s", port_name);
|
||||
|
||||
- free(bname);
|
||||
- free(basepath);
|
||||
+ close (fd);
|
||||
+
|
||||
+ free (bname);
|
||||
+ free (basepath);
|
||||
}
|
||||
|
||||
#ifdef __sparc__
|
||||
@@ -610,16 +610,16 @@ of_path_of_scsi(const char *sys_devname __attribute__((unused)), const char *dev
|
||||
digit_string = trailing_digits (device);
|
||||
if (strncmp (of_path, "/vdevice/", sizeof ("/vdevice/") - 1) == 0)
|
||||
{
|
||||
- if(strstr(of_path,"vfc-client"))
|
||||
- {
|
||||
- char * port_name = xmalloc(sizeof(char)*17);
|
||||
- of_fc_port_name(sysfs_path, p, port_name);
|
||||
-
|
||||
- snprintf(disk,sizeof(disk),"/%s@%s", disk_name, port_name);
|
||||
- free(port_name);
|
||||
- }
|
||||
+ if (strstr (of_path, "vfc-client"))
|
||||
+ {
|
||||
+ char * port_name = xmalloc (sizeof (char) * 17);
|
||||
+ of_fc_port_name (sysfs_path, p, port_name);
|
||||
+
|
||||
+ snprintf (disk, sizeof (disk), "/%s@%s", disk_name, port_name);
|
||||
+ free (port_name);
|
||||
+ }
|
||||
else
|
||||
- {
|
||||
+ {
|
||||
unsigned long id = 0x8000 | (tgt << 8) | (bus << 5) | lun;
|
||||
if (*digit_string == '\0')
|
||||
{
|
||||
@@ -634,12 +634,12 @@ of_path_of_scsi(const char *sys_devname __attribute__((unused)), const char *dev
|
||||
"/%s@%04lx000000000000:%c", disk_name, id, 'a' + (part - 1));
|
||||
}
|
||||
}
|
||||
- } else if (strstr(of_path,"fibre-channel")||(strstr(of_path,"vfc-client"))){
|
||||
- char * port_name = xmalloc(sizeof(char)*17);
|
||||
- of_fc_port_name(sysfs_path, p, port_name);
|
||||
-
|
||||
- snprintf(disk,sizeof(disk),"/%s@%s", disk_name, port_name);
|
||||
- free(port_name);
|
||||
+ } else if (strstr (of_path, "fibre-channel") || (strstr (of_path, "vfc-client"))){
|
||||
+ char * port_name = xmalloc (sizeof (char) * 17);
|
||||
+ of_fc_port_name (sysfs_path, p, port_name);
|
||||
+
|
||||
+ snprintf (disk, sizeof (disk), "/%s@%s", disk_name, port_name);
|
||||
+ free (port_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
143
0539-ieee1275-implement-FCP-methods-for-WWPN-and-LUNs.patch
Normal file
143
0539-ieee1275-implement-FCP-methods-for-WWPN-and-LUNs.patch
Normal file
@ -0,0 +1,143 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
Date: Mon, 23 Feb 2026 19:14:07 +0530
|
||||
Subject: [PATCH] ieee1275: implement FCP methods for WWPN and LUNs
|
||||
|
||||
This patch enables the fcp-targets and fcp-luns methods which are
|
||||
responsible to get WWPNs and LUNs for fibre channel devices.
|
||||
|
||||
Those methods are specially necessary if the boot directory and grub
|
||||
installation are in different FCP disks, allowing the dev_iterate()
|
||||
to find the WWPNs and LUNs when called by searchfs.uuid tool.
|
||||
|
||||
Signed-off-by: Diego Domingos <diegodo@br.ibm.com>
|
||||
Signed-off-by: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
Reviewed-by: Leo Sandoval <lsandova@redhat.com>
|
||||
Reviewed-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Part-of: <https://gitlab.freedesktop.org/gnu-grub/grub/-/merge_requests/146>
|
||||
---
|
||||
grub-core/disk/ieee1275/ofdisk.c | 111 ++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 110 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c
|
||||
index abb5082cdbfc..a16300a94745 100644
|
||||
--- a/grub-core/disk/ieee1275/ofdisk.c
|
||||
+++ b/grub-core/disk/ieee1275/ofdisk.c
|
||||
@@ -223,7 +223,116 @@ dev_iterate_real (const char *name, const char *path)
|
||||
static void
|
||||
dev_iterate (const struct grub_ieee1275_devalias *alias)
|
||||
{
|
||||
- if (grub_strcmp (alias->type, "vscsi") == 0)
|
||||
+ if (grub_strcmp (alias->type, "fcp") == 0)
|
||||
+ {
|
||||
+ /*
|
||||
+ * If we are dealing with fcp devices, we need
|
||||
+ * to find the WWPNs and LUNs to iterate them
|
||||
+ */
|
||||
+ grub_ieee1275_ihandle_t ihandle;
|
||||
+ grub_uint64_t *ptr_targets, *ptr_luns, k, l;
|
||||
+ unsigned int i, j, pos;
|
||||
+ char *buf, *bufptr;
|
||||
+ struct set_fcp_targets_args
|
||||
+ {
|
||||
+ struct grub_ieee1275_common_hdr common;
|
||||
+ grub_ieee1275_cell_t method;
|
||||
+ grub_ieee1275_cell_t ihandle;
|
||||
+ grub_ieee1275_cell_t catch_result;
|
||||
+ grub_ieee1275_cell_t nentries;
|
||||
+ grub_ieee1275_cell_t table;
|
||||
+ } args_targets;
|
||||
+
|
||||
+ struct set_fcp_luns_args
|
||||
+ {
|
||||
+ struct grub_ieee1275_common_hdr common;
|
||||
+ grub_ieee1275_cell_t method;
|
||||
+ grub_ieee1275_cell_t ihandle;
|
||||
+ grub_ieee1275_cell_t wwpn_h;
|
||||
+ grub_ieee1275_cell_t wwpn_l;
|
||||
+ grub_ieee1275_cell_t catch_result;
|
||||
+ grub_ieee1275_cell_t nentries;
|
||||
+ grub_ieee1275_cell_t table;
|
||||
+ } args_luns;
|
||||
+
|
||||
+ struct args_ret
|
||||
+ {
|
||||
+ grub_uint64_t addr;
|
||||
+ grub_uint64_t len;
|
||||
+ };
|
||||
+
|
||||
+ if (grub_ieee1275_open (alias->path, &ihandle))
|
||||
+ {
|
||||
+ grub_dprintf ("disk", "failed to open the disk while iterating FCP disk path=%s\n", alias->path);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* Setup the fcp-targets method to call via pfw*/
|
||||
+ INIT_IEEE1275_COMMON (&args_targets.common, "call-method", 2, 3);
|
||||
+ args_targets.method = (grub_ieee1275_cell_t) "fcp-targets";
|
||||
+ args_targets.ihandle = ihandle;
|
||||
+
|
||||
+ /* Setup the fcp-luns method to call via pfw */
|
||||
+ INIT_IEEE1275_COMMON (&args_luns.common, "call-method", 4, 3);
|
||||
+ args_luns.method = (grub_ieee1275_cell_t) "fcp-luns";
|
||||
+ args_luns.ihandle = ihandle;
|
||||
+ if (IEEE1275_CALL_ENTRY_FN (&args_targets) == -1)
|
||||
+ {
|
||||
+ grub_dprintf ("disk", "failed to get the targets while iterating FCP disk path=%s\n", alias->path);
|
||||
+ grub_ieee1275_close (ihandle);
|
||||
+ return;
|
||||
+ }
|
||||
+ buf = grub_malloc (grub_strlen (alias->path) + 32 + 32);
|
||||
+ if (!buf)
|
||||
+ {
|
||||
+ grub_ieee1275_close (ihandle);
|
||||
+ return;
|
||||
+ }
|
||||
+ bufptr = grub_stpcpy (buf, alias->path);
|
||||
+
|
||||
+ /*
|
||||
+ * Iterate over entries returned by pfw. Each entry contains a
|
||||
+ * pointer to wwpn table and his length.
|
||||
+ */
|
||||
+ struct args_ret *targets_table = (struct args_ret *) (args_targets.table);
|
||||
+ for (i = 0; i < args_targets.nentries; i++)
|
||||
+ {
|
||||
+ ptr_targets = (grub_uint64_t*) targets_table[i].addr;
|
||||
+ /* Iterate over all wwpns in given table */
|
||||
+ for(k = 0; k < targets_table[i].len; k++)
|
||||
+ {
|
||||
+ args_luns.wwpn_l = (grub_ieee1275_cell_t) (*ptr_targets);
|
||||
+ args_luns.wwpn_h = (grub_ieee1275_cell_t) (*ptr_targets >> 32);
|
||||
+ pos = grub_snprintf (bufptr, 32, "/disk@%" PRIxGRUB_UINT64_T,
|
||||
+ grub_get_unaligned64 (*ptr_targets++));
|
||||
+ /* Get the luns for given wwpn target */
|
||||
+ if (IEEE1275_CALL_ENTRY_FN (&args_luns) == -1)
|
||||
+ {
|
||||
+ grub_dprintf ("disk", "failed to get the LUNS while iterating FCP disk path=%s\n", buf);
|
||||
+ grub_ieee1275_close (ihandle);
|
||||
+ grub_free (buf);
|
||||
+ return;
|
||||
+ }
|
||||
+ struct args_ret *luns_table = (struct args_ret *) (args_luns.table);
|
||||
+
|
||||
+ /* Iterate over all LUNs */
|
||||
+ for(j = 0; j < args_luns.nentries; j++)
|
||||
+ {
|
||||
+ ptr_luns = (grub_uint64_t*) luns_table[j].addr;
|
||||
+ for(l = 0; l < luns_table[j].len; l++)
|
||||
+ {
|
||||
+ grub_snprintf (&bufptr[pos], 30, ",%" PRIxGRUB_UINT64_T,
|
||||
+ grub_get_unaligned64 (*ptr_luns++));
|
||||
+ dev_iterate_real (buf, buf);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ grub_ieee1275_close (ihandle);
|
||||
+ grub_free (buf);
|
||||
+ return;
|
||||
+ }
|
||||
+ else if (grub_strcmp (alias->type, "vscsi") == 0)
|
||||
{
|
||||
static grub_ieee1275_ihandle_t ihandle;
|
||||
struct set_color_args
|
||||
63
0540-ieee1275-change-the-logic-of-ieee1275_get_devargs.patch
Normal file
63
0540-ieee1275-change-the-logic-of-ieee1275_get_devargs.patch
Normal file
@ -0,0 +1,63 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
Date: Mon, 23 Feb 2026 19:14:08 +0530
|
||||
Subject: [PATCH] ieee1275: change the logic of ieee1275_get_devargs()
|
||||
|
||||
Usually grub will parse the PFW arguments by searching for the first occurence of the character ':'.
|
||||
However, we can have this char more than once on NQN.
|
||||
This patch changes the logic to find the last occurence of this char so we can get the proper values
|
||||
for NVMeoFC
|
||||
|
||||
Signed-off-by: Diego Domingos <diegodo@br.ibm.com>
|
||||
Signed-off-by: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
Reviewed-by: Leo Sandoval <lsandova@redhat.com>
|
||||
Reviewed-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Part-of: <https://gitlab.freedesktop.org/gnu-grub/grub/-/merge_requests/146>
|
||||
---
|
||||
grub-core/kern/ieee1275/openfw.c | 19 +++++++++++++++++--
|
||||
1 file changed, 17 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/grub-core/kern/ieee1275/openfw.c b/grub-core/kern/ieee1275/openfw.c
|
||||
index 0278054c61e6..de0b8c299285 100644
|
||||
--- a/grub-core/kern/ieee1275/openfw.c
|
||||
+++ b/grub-core/kern/ieee1275/openfw.c
|
||||
@@ -324,7 +324,7 @@ grub_claimmap (grub_addr_t addr, grub_size_t size)
|
||||
static char *
|
||||
grub_ieee1275_get_devargs (const char *path)
|
||||
{
|
||||
- char *colon = grub_strchr (path, ':');
|
||||
+ char *colon = grub_strrchr (path, ':');
|
||||
|
||||
if (! colon)
|
||||
return 0;
|
||||
@@ -339,6 +339,21 @@ grub_ieee1275_get_devname (const char *path)
|
||||
char *colon = grub_strchr (path, ':');
|
||||
int pathlen = grub_strlen (path);
|
||||
struct grub_ieee1275_devalias curalias;
|
||||
+
|
||||
+ /* Check some special cases */
|
||||
+ if (grub_strstr (path, "nvme-of"))
|
||||
+ {
|
||||
+ char *namespace_split = grub_strstr (path, "/namespace@");
|
||||
+ if (namespace_split)
|
||||
+ {
|
||||
+ colon = grub_strchr (namespace_split, ':');
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ colon = NULL;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (colon)
|
||||
pathlen = (int)(colon - path);
|
||||
|
||||
@@ -579,7 +594,7 @@ grub_ieee1275_get_boot_dev (void)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- bootpath = (char *) grub_malloc ((grub_size_t) bootpath_size + 64);
|
||||
+ bootpath = (char *) grub_malloc ((grub_size_t) bootpath_size + 64 + 256);
|
||||
if (! bootpath)
|
||||
{
|
||||
grub_print_error ();
|
||||
547
0541-ieee1275-ofpath-enable-NVMeoF-logical-device-transla.patch
Normal file
547
0541-ieee1275-ofpath-enable-NVMeoF-logical-device-transla.patch
Normal file
@ -0,0 +1,547 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
Date: Mon, 23 Feb 2026 19:14:10 +0530
|
||||
Subject: [PATCH] ieee1275: ofpath enable NVMeoF logical device translate
|
||||
|
||||
This patch adds code to enable the translation of logical devices to the of NVMeoFC paths.
|
||||
|
||||
Signed-off-by: Diego Domingos <diegodo@br.ibm.com>
|
||||
Signed-off-by: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
Reviewed-by: Leo Sandoval <lsandova@redhat.com>
|
||||
Reviewed-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Part-of: <https://gitlab.freedesktop.org/gnu-grub/grub/-/merge_requests/146>
|
||||
---
|
||||
grub-core/osdep/linux/ofpath.c | 431 ++++++++++++++++++++++++++++++++++++++++-
|
||||
include/grub/util/ofpath.h | 28 +++
|
||||
2 files changed, 450 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/grub-core/osdep/linux/ofpath.c b/grub-core/osdep/linux/ofpath.c
|
||||
index 9ba1db74aadf..54094a87576b 100644
|
||||
--- a/grub-core/osdep/linux/ofpath.c
|
||||
+++ b/grub-core/osdep/linux/ofpath.c
|
||||
@@ -137,7 +137,7 @@ trim_newline (char *path)
|
||||
*end-- = '\0';
|
||||
}
|
||||
|
||||
-#define MAX_DISK_CAT 64
|
||||
+#define MAX_DISK_CAT 512
|
||||
|
||||
static char *
|
||||
find_obppath (const char *sysfs_path_orig)
|
||||
@@ -313,6 +313,91 @@ get_basename(char *p)
|
||||
return ret;
|
||||
}
|
||||
|
||||
+int
|
||||
+add_filename_to_pile (char *filename, struct ofpath_files_list_root* root)
|
||||
+{
|
||||
+ struct ofpath_files_list_node* file;
|
||||
+
|
||||
+ file = malloc (sizeof (struct ofpath_files_list_node));
|
||||
+ if (!file)
|
||||
+ return -1;
|
||||
+
|
||||
+ file->filename = malloc (sizeof (char) * 1024);
|
||||
+ if (!file->filename)
|
||||
+ {
|
||||
+ free (file);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ grub_strcpy (file->filename, filename);
|
||||
+ if (root->first == NULL)
|
||||
+ {
|
||||
+ root->items = 1;
|
||||
+ root->first = file;
|
||||
+ file->next = NULL;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ root->items++;
|
||||
+ file->next = root->first;
|
||||
+ root->first = file;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+find_file (char* filename, char* directory, struct ofpath_files_list_root* root, int max_depth, int depth)
|
||||
+{
|
||||
+ struct dirent *ep;
|
||||
+ struct stat statbuf;
|
||||
+ DIR *dp;
|
||||
+ int ret_val=0;
|
||||
+ char* full_path;
|
||||
+
|
||||
+ if (depth > max_depth)
|
||||
+ {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if ((dp = opendir (directory)) == NULL)
|
||||
+ {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ full_path = malloc (1024 * sizeof (char));
|
||||
+ if (!full_path)
|
||||
+ return;
|
||||
+
|
||||
+ while ((ep = readdir(dp)) != NULL)
|
||||
+ {
|
||||
+ snprintf (full_path, 1024, "%s/%s", directory, ep->d_name);
|
||||
+ lstat (full_path, &statbuf);
|
||||
+
|
||||
+ if (S_ISLNK (statbuf.st_mode))
|
||||
+ {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (!strcmp (ep->d_name, ".") || !strcmp(ep->d_name, ".."))
|
||||
+ {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (!strcmp (ep->d_name, filename))
|
||||
+ {
|
||||
+ ret_val = add_filename_to_pile (full_path, root);
|
||||
+ if (ret_val == -1)
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ find_file (filename, full_path, root, max_depth, depth+1);
|
||||
+ }
|
||||
+
|
||||
+ free (full_path);
|
||||
+ closedir (dp);
|
||||
+}
|
||||
+
|
||||
static char *
|
||||
of_path_of_vdisk(const char *sys_devname __attribute__((unused)),
|
||||
const char *device,
|
||||
@@ -383,7 +468,257 @@ of_fc_port_name (const char *path, const char *subpath, char *port_name)
|
||||
free (basepath);
|
||||
}
|
||||
|
||||
-#ifdef __sparc__
|
||||
+void
|
||||
+free_ofpath_files_list (struct ofpath_files_list_root* root)
|
||||
+{
|
||||
+ struct ofpath_files_list_node* node = root->first;
|
||||
+ struct ofpath_files_list_node* next;
|
||||
+
|
||||
+ while (node!=NULL)
|
||||
+ {
|
||||
+ next = node->next;
|
||||
+ free (node->filename);
|
||||
+ free (node);
|
||||
+ node = next;
|
||||
+ }
|
||||
+
|
||||
+ free (root);
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+char*
|
||||
+of_find_fc_host (char* host_wwpn)
|
||||
+{
|
||||
+ FILE* fp;
|
||||
+ char *buf;
|
||||
+ char *ret_val;
|
||||
+ char portname_filename[sizeof ("port_name")] = "port_name";
|
||||
+ char devices_path[sizeof ("/sys/devices")] = "/sys/devices";
|
||||
+ struct ofpath_files_list_root* portnames_file_list;
|
||||
+ struct ofpath_files_list_node* node;
|
||||
+
|
||||
+ ret_val = malloc (sizeof (char) * 1024);
|
||||
+ if (!ret_val)
|
||||
+ return NULL;
|
||||
+
|
||||
+ portnames_file_list = malloc (sizeof (struct ofpath_files_list_root));
|
||||
+ if (!portnames_file_list)
|
||||
+ {
|
||||
+ free (ret_val);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ portnames_file_list->items = 0;
|
||||
+ portnames_file_list->first = NULL;
|
||||
+ find_file (portname_filename, devices_path, portnames_file_list, 10, 0);
|
||||
+ node = portnames_file_list->first;
|
||||
+
|
||||
+ while (node != NULL)
|
||||
+ {
|
||||
+ fp = fopen(node->filename, "r");
|
||||
+ if (!fp)
|
||||
+ {
|
||||
+ node = node->next;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ buf = malloc (sizeof (char) * 512);
|
||||
+ if (!buf)
|
||||
+ break;
|
||||
+
|
||||
+ fscanf (fp, "%s", buf);
|
||||
+ fclose (fp);
|
||||
+
|
||||
+ if ((strcmp (buf, host_wwpn) == 0) && grub_strstr (node->filename, "fc_host"))
|
||||
+ {
|
||||
+ free (buf);
|
||||
+ grub_strcpy (ret_val, node->filename);
|
||||
+ free_ofpath_files_list (portnames_file_list);
|
||||
+ return ret_val;
|
||||
+ }
|
||||
+
|
||||
+ node = node->next;
|
||||
+ free (buf);
|
||||
+ }
|
||||
+ free_ofpath_files_list (portnames_file_list);
|
||||
+ free (ret_val);
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+of_path_get_nvmeof_adapter_info (char* sysfs_path,
|
||||
+ struct ofpath_nvmeof_info* nvmeof_info)
|
||||
+{
|
||||
+ FILE *fp;
|
||||
+ char *buf, *buf2, *buf3;
|
||||
+
|
||||
+ nvmeof_info->host_wwpn = malloc (sizeof (char) * 256);
|
||||
+ nvmeof_info->target_wwpn = malloc (sizeof (char) * 256);
|
||||
+ nvmeof_info->nqn = malloc (sizeof (char) * 256);
|
||||
+
|
||||
+ if (nvmeof_info->host_wwpn == NULL || nvmeof_info->target_wwpn == NULL || nvmeof_info->nqn == NULL)
|
||||
+ {
|
||||
+ free (nvmeof_info->host_wwpn);
|
||||
+ free (nvmeof_info->target_wwpn);
|
||||
+ free (nvmeof_info->nqn);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ buf = malloc (sizeof (char) * 512);
|
||||
+ if (!buf)
|
||||
+ {
|
||||
+ free (nvmeof_info->host_wwpn);
|
||||
+ free (nvmeof_info->target_wwpn);
|
||||
+ free (nvmeof_info->nqn);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ snprintf (buf, 512, "%s/subsysnqn", sysfs_path);
|
||||
+ if (! (fp = fopen (buf, "r")) ||
|
||||
+ fscanf (fp, "%s", nvmeof_info->nqn) != 1)
|
||||
+ {
|
||||
+ if (fp)
|
||||
+ fclose (fp);
|
||||
+ free (nvmeof_info->host_wwpn);
|
||||
+ free (nvmeof_info->target_wwpn);
|
||||
+ free (nvmeof_info->nqn);
|
||||
+ free (buf);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ fclose (fp);
|
||||
+
|
||||
+ snprintf (buf, 512, "%s/cntlid", sysfs_path);
|
||||
+ if (! (fp = fopen (buf, "r")) ||
|
||||
+ fscanf (fp, "%u", &(nvmeof_info->cntlid)) != 1)
|
||||
+ {
|
||||
+ if (fp)
|
||||
+ fclose (fp);
|
||||
+ free (nvmeof_info->host_wwpn);
|
||||
+ free (nvmeof_info->target_wwpn);
|
||||
+ free (nvmeof_info->nqn);
|
||||
+ free (buf);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ fclose (fp);
|
||||
+
|
||||
+ snprintf (buf, 512, "%s/address", sysfs_path);
|
||||
+ buf2 = NULL;
|
||||
+ fp = NULL;
|
||||
+ if (! (buf2 = malloc (sizeof (char) * 512)) ||
|
||||
+ ! (fp = fopen (buf, "r")) ||
|
||||
+ fscanf (fp, "%s", buf2) != 1)
|
||||
+ {
|
||||
+ if (fp)
|
||||
+ fclose (fp);
|
||||
+ free (nvmeof_info->host_wwpn);
|
||||
+ free (nvmeof_info->target_wwpn);
|
||||
+ free (nvmeof_info->nqn);
|
||||
+ free (buf);
|
||||
+ free (buf2);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ fclose (fp);
|
||||
+
|
||||
+ if (! (buf3 = strrchr (buf2, '-')))
|
||||
+ {
|
||||
+ free (nvmeof_info->host_wwpn);
|
||||
+ free (nvmeof_info->target_wwpn);
|
||||
+ free (nvmeof_info->nqn);
|
||||
+ free (buf);
|
||||
+ free (buf2);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ grub_memcpy (nvmeof_info->host_wwpn, buf3 + 1, 256);
|
||||
+ if (! (buf3 = strchr (buf2, '-')) ||
|
||||
+ ! (buf3 = strchr (buf3 + 1, '-')) ||
|
||||
+ ! (buf3 = strchr (buf3 + 1, 'x')))
|
||||
+ {
|
||||
+ free (nvmeof_info->host_wwpn);
|
||||
+ free (nvmeof_info->target_wwpn);
|
||||
+ free (nvmeof_info->nqn);
|
||||
+ free (buf);
|
||||
+ free (buf2);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ grub_memcpy (nvmeof_info->target_wwpn, buf3 + 1, 256);
|
||||
+ buf3 = strchr (nvmeof_info->target_wwpn, ',');
|
||||
+ if (buf3)
|
||||
+ *buf3 = '\0';
|
||||
+ free (buf);
|
||||
+ free (buf2);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#define OFPATH_MAX_UINT_HEX_DIGITS 8
|
||||
+#define OFPATH_MAX_INT_DIGITS 10
|
||||
+
|
||||
+static char *
|
||||
+of_path_get_nvme_controller_name_node (const char* devname)
|
||||
+{
|
||||
+ char *controller_node, *end;
|
||||
+
|
||||
+ controller_node = xstrdup (devname);
|
||||
+ end = grub_strchr (controller_node + 1, 'n');
|
||||
+ if (end != NULL)
|
||||
+ {
|
||||
+ *end = '\0';
|
||||
+ }
|
||||
+
|
||||
+ return controller_node;
|
||||
+}
|
||||
+
|
||||
+unsigned int
|
||||
+of_path_get_nvme_nsid (const char* devname)
|
||||
+{
|
||||
+ unsigned int nsid;
|
||||
+ char *sysfs_path, *buf;
|
||||
+ FILE *fp;
|
||||
+
|
||||
+ buf = malloc (sizeof(char) * 512);
|
||||
+ if (!buf)
|
||||
+ return 0;
|
||||
+
|
||||
+ sysfs_path = block_device_get_sysfs_path_and_link (devname);
|
||||
+ snprintf (buf, 512, "%s/%s/nsid", sysfs_path, devname);
|
||||
+ fp = fopen(buf, "r");
|
||||
+ if (!fp)
|
||||
+ {
|
||||
+ free (sysfs_path);
|
||||
+ free (buf);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ fscanf (fp, "%u", &(nsid));
|
||||
+ fclose (fp);
|
||||
+
|
||||
+ free (sysfs_path);
|
||||
+ free (buf);
|
||||
+ return nsid;
|
||||
+}
|
||||
+
|
||||
+static char *
|
||||
+nvme_get_syspath (const char *nvmedev)
|
||||
+{
|
||||
+ char *sysfs_path;
|
||||
+
|
||||
+ sysfs_path = block_device_get_sysfs_path_and_link (nvmedev);
|
||||
+ if (strstr (sysfs_path, "nvme-subsystem"))
|
||||
+ {
|
||||
+ char *controller_node = of_path_get_nvme_controller_name_node (nvmedev);
|
||||
+ char *buf = xmalloc (strlen (sysfs_path) + strlen ("/") + strlen (controller_node) + 1);
|
||||
+ strcpy (buf, sysfs_path);
|
||||
+ strcat (buf, "/");
|
||||
+ strcat (buf, controller_node);
|
||||
+ free (sysfs_path);
|
||||
+ free (controller_node);
|
||||
+ sysfs_path = xrealpath (buf);
|
||||
+ free (buf);
|
||||
+ }
|
||||
+
|
||||
+ return sysfs_path;
|
||||
+}
|
||||
+
|
||||
static char *
|
||||
of_path_of_nvme(const char *sys_devname __attribute__((unused)),
|
||||
const char *device,
|
||||
@@ -392,6 +727,8 @@ of_path_of_nvme(const char *sys_devname __attribute__((unused)),
|
||||
{
|
||||
char *sysfs_path, *of_path, disk[MAX_DISK_CAT];
|
||||
const char *digit_string, *part_end;
|
||||
+ int chars_written, ret_val;
|
||||
+ struct ofpath_nvmeof_info* nvmeof_info;
|
||||
|
||||
digit_string = trailing_digits (device);
|
||||
part_end = devicenode + strlen (devicenode) - 1;
|
||||
@@ -411,15 +748,94 @@ of_path_of_nvme(const char *sys_devname __attribute__((unused)),
|
||||
/* Remove the p. */
|
||||
*end = '\0';
|
||||
sscanf (digit_string, "%d", &part);
|
||||
- snprintf (disk, sizeof (disk), "/disk@1:%c", 'a' + (part - 1));
|
||||
- sysfs_path = block_device_get_sysfs_path_and_link (nvmedev);
|
||||
+ sysfs_path = nvme_get_syspath (nvmedev);
|
||||
+
|
||||
+ /* If is a NVMeoF */
|
||||
+ if (strstr (sysfs_path, "nvme-fabrics"))
|
||||
+ {
|
||||
+ nvmeof_info = malloc (sizeof (struct ofpath_nvmeof_info));
|
||||
+ if (!nvmeof_info)
|
||||
+ {
|
||||
+ free (nvmedev);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ ret_val = of_path_get_nvmeof_adapter_info (sysfs_path, nvmeof_info);
|
||||
+ if (ret_val == -1)
|
||||
+ {
|
||||
+ free (nvmedev);
|
||||
+ free (nvmeof_info);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ free (sysfs_path);
|
||||
+ sysfs_path = of_find_fc_host (nvmeof_info->host_wwpn);
|
||||
+ if (!sysfs_path)
|
||||
+ {
|
||||
+ free (nvmedev);
|
||||
+ free (nvmeof_info->host_wwpn);
|
||||
+ free (nvmeof_info->target_wwpn);
|
||||
+ free (nvmeof_info->nqn);
|
||||
+ free (nvmeof_info);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ chars_written = snprintf (disk,sizeof(disk), "/nvme-of/controller@%s,%x:nqn=%s",
|
||||
+ nvmeof_info->target_wwpn,0xffff,
|
||||
+ nvmeof_info->nqn);
|
||||
+ unsigned int nsid = of_path_get_nvme_nsid (nvmedev);
|
||||
+ if (nsid)
|
||||
+ {
|
||||
+ snprintf (disk+chars_written, sizeof("/namespace@") + OFPATH_MAX_UINT_HEX_DIGITS + OFPATH_MAX_INT_DIGITS,
|
||||
+ "/namespace@%x:%d", nsid, part);
|
||||
+ }
|
||||
+ free (nvmeof_info);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ snprintf (disk, sizeof (disk), "/disk@1:%c", 'a' + (part - 1));
|
||||
+ }
|
||||
free (nvmedev);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We do not have the parition. */
|
||||
- snprintf (disk, sizeof (disk), "/disk@1");
|
||||
- sysfs_path = block_device_get_sysfs_path_and_link (device);
|
||||
+ sysfs_path = nvme_get_syspath (device);
|
||||
+ if (strstr (sysfs_path, "nvme-fabrics"))
|
||||
+ {
|
||||
+ nvmeof_info = malloc (sizeof (struct ofpath_nvmeof_info));
|
||||
+ if (!nvmeof_info)
|
||||
+ return NULL;
|
||||
+
|
||||
+ ret_val = of_path_get_nvmeof_adapter_info (sysfs_path, nvmeof_info);
|
||||
+ if (ret_val == -1)
|
||||
+ {
|
||||
+ free (nvmeof_info);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ sysfs_path = of_find_fc_host (nvmeof_info->host_wwpn);
|
||||
+ if (!sysfs_path)
|
||||
+ {
|
||||
+ free (nvmeof_info);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ chars_written = snprintf (disk,sizeof(disk), "/nvme-of/controller@%s,%x:nqn=%s",
|
||||
+ nvmeof_info->target_wwpn, 0xffff,
|
||||
+ nvmeof_info->nqn);
|
||||
+ unsigned int nsid = of_path_get_nvme_nsid (device);
|
||||
+ if (nsid)
|
||||
+ {
|
||||
+ snprintf (disk+chars_written,sizeof("/namespace@") + sizeof(char) * OFPATH_MAX_UINT_HEX_DIGITS,
|
||||
+ "/namespace@%x", nsid);
|
||||
+ }
|
||||
+ free (nvmeof_info);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ snprintf (disk, sizeof (disk), "/disk@1");
|
||||
+ }
|
||||
}
|
||||
|
||||
of_path = find_obppath (sysfs_path);
|
||||
@@ -430,7 +846,6 @@ of_path_of_nvme(const char *sys_devname __attribute__((unused)),
|
||||
free (sysfs_path);
|
||||
return of_path;
|
||||
}
|
||||
-#endif
|
||||
|
||||
static int
|
||||
vendor_is_ATA(const char *path)
|
||||
@@ -841,11 +1256,9 @@ grub_util_devname_to_ofpath (const char *sys_devname)
|
||||
/* All the models I've seen have a devalias "floppy".
|
||||
New models have no floppy at all. */
|
||||
ofpath = xstrdup ("floppy");
|
||||
-#ifdef __sparc__
|
||||
else if (device[0] == 'n' && device[1] == 'v' && device[2] == 'm'
|
||||
&& device[3] == 'e')
|
||||
ofpath = of_path_of_nvme (name_buf, device, devnode, devicenode);
|
||||
-#endif
|
||||
else
|
||||
{
|
||||
grub_util_warn (_("unknown device type %s"), device);
|
||||
diff --git a/include/grub/util/ofpath.h b/include/grub/util/ofpath.h
|
||||
index b43c523cb267..7ab377c7cc43 100644
|
||||
--- a/include/grub/util/ofpath.h
|
||||
+++ b/include/grub/util/ofpath.h
|
||||
@@ -3,4 +3,32 @@
|
||||
|
||||
char *grub_util_devname_to_ofpath (const char *devname);
|
||||
|
||||
+struct ofpath_files_list_node
|
||||
+{
|
||||
+ char* filename;
|
||||
+ struct ofpath_files_list_node* next;
|
||||
+};
|
||||
+
|
||||
+struct ofpath_files_list_root
|
||||
+{
|
||||
+ int items;
|
||||
+ struct ofpath_files_list_node* first;
|
||||
+};
|
||||
+
|
||||
+struct ofpath_nvmeof_info
|
||||
+{
|
||||
+ char* host_wwpn;
|
||||
+ char* target_wwpn;
|
||||
+ char* nqn;
|
||||
+ int cntlid;
|
||||
+ int nsid;
|
||||
+};
|
||||
+
|
||||
+int of_path_get_nvmeof_adapter_info (char* sysfs_path, struct ofpath_nvmeof_info* nvmeof_info);
|
||||
+unsigned int of_path_get_nvme_nsid (const char* devname);
|
||||
+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);
|
||||
+
|
||||
#endif /* ! GRUB_OFPATH_MACHINE_UTIL_HEADER */
|
||||
218
0542-ieee1275-support-added-for-multiple-nvme-bootpaths.patch
Normal file
218
0542-ieee1275-support-added-for-multiple-nvme-bootpaths.patch
Normal file
@ -0,0 +1,218 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
Date: Mon, 23 Feb 2026 19:14:11 +0530
|
||||
Subject: [PATCH] ieee1275: support added for multiple nvme bootpaths
|
||||
|
||||
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>
|
||||
Reviewed-by: Leo Sandoval <lsandova@redhat.com>
|
||||
Reviewed-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Part-of: <https://gitlab.freedesktop.org/gnu-grub/grub/-/merge_requests/146>
|
||||
---
|
||||
grub-core/osdep/linux/ofpath.c | 4 +-
|
||||
grub-core/osdep/unix/platform.c | 122 +++++++++++++++++++++++++++++++++++++++-
|
||||
include/grub/util/install.h | 3 +
|
||||
include/grub/util/ofpath.h | 4 ++
|
||||
4 files changed, 130 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/grub-core/osdep/linux/ofpath.c b/grub-core/osdep/linux/ofpath.c
|
||||
index 54094a87576b..46b23820c8b8 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;
|
||||
@@ -697,7 +697,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/grub-core/osdep/unix/platform.c b/grub-core/osdep/unix/platform.c
|
||||
index 55b8f4016248..8ca94e3ee0fe 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,111 @@ 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"))
|
||||
+ {
|
||||
+ char *tmp = xasprintf ("%s/device", sysfs_path);
|
||||
+ free (sysfs_path);
|
||||
+ sysfs_path = tmp;
|
||||
+ is_FC = true;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ char *tmp = xasprintf ("%s/subsystem", sysfs_path);
|
||||
+ free (sysfs_path);
|
||||
+ sysfs_path = tmp;
|
||||
+ 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 +324,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/include/grub/util/install.h b/include/grub/util/install.h
|
||||
index ccf799ff7169..5b4513904889 100644
|
||||
--- a/include/grub/util/install.h
|
||||
+++ b/include/grub/util/install.h
|
||||
@@ -238,6 +238,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 7ab377c7cc43..9f9a753dcebb 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 */
|
||||
457
0543-ieee1275-add-support-for-NVMeoFC.patch
Normal file
457
0543-ieee1275-add-support-for-NVMeoFC.patch
Normal file
@ -0,0 +1,457 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
Date: Mon, 23 Feb 2026 19:14:09 +0530
|
||||
Subject: [PATCH] ieee1275: add support for NVMeoFC
|
||||
|
||||
This patch implements the functions to scan and discovery of NVMeoFC.
|
||||
|
||||
Signed-off-by: Diego Domingos <diegodo@br.ibm.com>
|
||||
Signed-off-by: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
Reviewed-by: Leo Sandoval <lsandova@redhat.com>
|
||||
Reviewed-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Part-of: <https://gitlab.freedesktop.org/gnu-grub/grub/-/merge_requests/146>
|
||||
---
|
||||
grub-core/disk/ieee1275/ofdisk.c | 418 +++++++++++++++++++++++++++++----------
|
||||
1 file changed, 312 insertions(+), 106 deletions(-)
|
||||
|
||||
diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c
|
||||
index a16300a94745..cf0f003f90da 100644
|
||||
--- a/grub-core/disk/ieee1275/ofdisk.c
|
||||
+++ b/grub-core/disk/ieee1275/ofdisk.c
|
||||
@@ -26,6 +26,10 @@
|
||||
#include <grub/time.h>
|
||||
#include <grub/safemath.h>
|
||||
|
||||
+#define EXTEND_PATH_64 64
|
||||
+#define EXTEND_PATH_512 512
|
||||
+#define TABLE_SIZE 256
|
||||
+
|
||||
static char *last_devpath;
|
||||
static grub_ieee1275_ihandle_t last_ihandle;
|
||||
|
||||
@@ -220,117 +224,319 @@ dev_iterate_real (const char *name, const char *path)
|
||||
return;
|
||||
}
|
||||
|
||||
+static void
|
||||
+dev_iterate_fcp_disks (const struct grub_ieee1275_devalias *alias)
|
||||
+ {
|
||||
+ /*
|
||||
+ * If we are dealing with fcp devices, we need
|
||||
+ * to find the WWPNs and LUNs to iterate them
|
||||
+ */
|
||||
+ grub_ieee1275_ihandle_t ihandle;
|
||||
+ grub_uint64_t *ptr_targets, *ptr_luns, k, l;
|
||||
+ unsigned int i, j, pos;
|
||||
+ char *buf, *bufptr;
|
||||
+ struct set_fcp_targets_args
|
||||
+ {
|
||||
+ struct grub_ieee1275_common_hdr common;
|
||||
+ grub_ieee1275_cell_t method;
|
||||
+ grub_ieee1275_cell_t ihandle;
|
||||
+ grub_ieee1275_cell_t catch_result;
|
||||
+ grub_ieee1275_cell_t nentries;
|
||||
+ grub_ieee1275_cell_t table;
|
||||
+ } args_targets;
|
||||
+
|
||||
+ struct set_fcp_luns_args
|
||||
+ {
|
||||
+ struct grub_ieee1275_common_hdr common;
|
||||
+ grub_ieee1275_cell_t method;
|
||||
+ grub_ieee1275_cell_t ihandle;
|
||||
+ grub_ieee1275_cell_t wwpn_h;
|
||||
+ grub_ieee1275_cell_t wwpn_l;
|
||||
+ grub_ieee1275_cell_t catch_result;
|
||||
+ grub_ieee1275_cell_t nentries;
|
||||
+ grub_ieee1275_cell_t table;
|
||||
+ } args_luns;
|
||||
+
|
||||
+ struct args_ret
|
||||
+ {
|
||||
+ grub_uint64_t addr;
|
||||
+ grub_uint64_t len;
|
||||
+ };
|
||||
+ struct args_ret *targets_table;
|
||||
+ struct args_ret *luns_table;
|
||||
+
|
||||
+ if (grub_ieee1275_open (alias->path, &ihandle))
|
||||
+ {
|
||||
+ grub_dprintf ("disk", "failed to open the disk while iterating FCP disk path=%s\n", alias->path);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* Setup the fcp-targets method to call via pfw*/
|
||||
+ INIT_IEEE1275_COMMON (&args_targets.common, "call-method", 2, 3);
|
||||
+ args_targets.method = (grub_ieee1275_cell_t) "fcp-targets";
|
||||
+ args_targets.ihandle = ihandle;
|
||||
+
|
||||
+ /* Setup the fcp-luns method to call via pfw */
|
||||
+ INIT_IEEE1275_COMMON (&args_luns.common, "call-method", 4, 3);
|
||||
+ args_luns.method = (grub_ieee1275_cell_t) "fcp-luns";
|
||||
+ args_luns.ihandle = ihandle;
|
||||
+ if (IEEE1275_CALL_ENTRY_FN (&args_targets) == -1)
|
||||
+ {
|
||||
+ grub_dprintf ("disk", "failed to get the targets while iterating FCP disk path=%s\n", alias->path);
|
||||
+ grub_ieee1275_close (ihandle);
|
||||
+ return;
|
||||
+ }
|
||||
+ /* Allocate memory for building the path */
|
||||
+ buf = grub_malloc (grub_strlen (alias->path) + EXTEND_PATH_64);
|
||||
+ if (!buf)
|
||||
+ {
|
||||
+ grub_ieee1275_close (ihandle);
|
||||
+ return;
|
||||
+ }
|
||||
+ bufptr = grub_stpcpy (buf, alias->path);
|
||||
+
|
||||
+ /*
|
||||
+ * Iterate over entries returned by pfw. Each entry contains a
|
||||
+ * pointer to wwpn table and his length.
|
||||
+ */
|
||||
+ targets_table = (struct args_ret *) (args_targets.table);
|
||||
+ for (i = 0; i < args_targets.nentries; i++)
|
||||
+ {
|
||||
+ ptr_targets = (grub_uint64_t*) (grub_addr_t) targets_table[i].addr;
|
||||
+ /* Iterate over all wwpns in given table */
|
||||
+ for (k = 0; k < targets_table[i].len; k++)
|
||||
+ {
|
||||
+ args_luns.wwpn_l = (grub_ieee1275_cell_t) (*ptr_targets);
|
||||
+ args_luns.wwpn_h = (grub_ieee1275_cell_t) (*ptr_targets >> 32);
|
||||
+ pos = grub_snprintf (bufptr, 32, "/disk@%" PRIxGRUB_UINT64_T,
|
||||
+ grub_get_unaligned64 ((const void *) ptr_targets));
|
||||
+ ptr_targets++;
|
||||
+ /* Get the luns for given wwpn target */
|
||||
+ if (IEEE1275_CALL_ENTRY_FN (&args_luns) == -1)
|
||||
+ {
|
||||
+ grub_dprintf ("disk", "failed to get the LUNS while iterating FCP disk path=%s\n", buf);
|
||||
+ grub_ieee1275_close (ihandle);
|
||||
+ grub_free (buf);
|
||||
+ return;
|
||||
+ }
|
||||
+ luns_table = (struct args_ret *) (args_luns.table);
|
||||
+
|
||||
+ /* Iterate over all LUNs */
|
||||
+ for (j = 0; j < args_luns.nentries; j++)
|
||||
+ {
|
||||
+ ptr_luns = (grub_uint64_t*) (grub_addr_t) luns_table[j].addr;
|
||||
+ for (l = 0; l < luns_table[j].len; l++)
|
||||
+ {
|
||||
+ grub_snprintf (&bufptr[pos], 30, ",%" PRIxGRUB_UINT64_T,
|
||||
+ grub_get_unaligned64 ((const void *) ptr_luns));
|
||||
+ ptr_luns++;
|
||||
+ dev_iterate_real (buf, buf);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ grub_ieee1275_close (ihandle);
|
||||
+ grub_free (buf);
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+dev_iterate_fcp_nvmeof (const struct grub_ieee1275_devalias *alias)
|
||||
+{
|
||||
+ char *bufptr;
|
||||
+ grub_ieee1275_ihandle_t ihandle;
|
||||
+
|
||||
+ /* Create the structs for the parameters passing to PFW */
|
||||
+ struct nvme_args
|
||||
+ {
|
||||
+ struct grub_ieee1275_common_hdr common;
|
||||
+ grub_ieee1275_cell_t method;
|
||||
+ grub_ieee1275_cell_t ihandle;
|
||||
+ grub_ieee1275_cell_t catch_result;
|
||||
+ grub_ieee1275_cell_t nentries;
|
||||
+ grub_ieee1275_cell_t table;
|
||||
+ } nvme_discovery_controllers_args, nvme_controllers_args, nvme_namespaces_args;
|
||||
+
|
||||
+ /* Create the structs for the results from PFW */
|
||||
+ struct discovery_controllers_table_struct
|
||||
+ {
|
||||
+ grub_uint64_t table[TABLE_SIZE];
|
||||
+ grub_uint32_t len;
|
||||
+ } discovery_controllers_table;
|
||||
+
|
||||
+ /*
|
||||
+ * struct nvme_controllers_table_entry
|
||||
+ * this the return of nvme-controllers method tables, containing:
|
||||
+ * - 2-byte controller ID
|
||||
+ * - 256-byte transport address string
|
||||
+ * - 256-byte field containing null-terminated NVM subsystem NQN string up to 223 characters
|
||||
+ */
|
||||
+ struct nvme_controllers_table_entry
|
||||
+ {
|
||||
+ grub_uint16_t id;
|
||||
+ char wwpn[TABLE_SIZE];
|
||||
+ char nqn[TABLE_SIZE];
|
||||
+ };
|
||||
+
|
||||
+ struct nvme_controllers_table_entry_real
|
||||
+ {
|
||||
+ grub_uint16_t id;
|
||||
+ char wwpn[TABLE_SIZE];
|
||||
+ char nqn[TABLE_SIZE];
|
||||
+ };
|
||||
+
|
||||
+ struct nvme_controllers_table_entry* nvme_controllers_table;
|
||||
+ grub_uint32_t nvme_controllers_table_entries;
|
||||
+ char *buf;
|
||||
+ unsigned int i = 0;
|
||||
+ int current_buffer_index;
|
||||
+ int nvme_controller_index;
|
||||
+ int bufptr_pos2;
|
||||
+ grub_uint32_t namespace_index = 0;
|
||||
+ struct nvme_controllers_table_entry* nvme_controllers_table_buf;
|
||||
+
|
||||
+ nvme_controllers_table = grub_malloc (sizeof (struct nvme_controllers_table_entry) * TABLE_SIZE);
|
||||
+ /* Allocate memory for building the NVMeoF path */
|
||||
+ buf = grub_malloc (grub_strlen (alias->path) + EXTEND_PATH_512);
|
||||
+
|
||||
+ if (!buf || !nvme_controllers_table)
|
||||
+ {
|
||||
+ grub_free (nvme_controllers_table);
|
||||
+ grub_free (buf);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* Copy the alias->path to buf so we can work with */
|
||||
+ bufptr = grub_stpcpy (buf, alias->path);
|
||||
+ grub_snprintf (bufptr, 32, "/nvme-of");
|
||||
+
|
||||
+ /*
|
||||
+ * Open the nvme-of layer
|
||||
+ * Ex. /pci@bus/fibre-channel@@dev,func/nvme-of
|
||||
+ */
|
||||
+ if (grub_ieee1275_open (buf, &ihandle))
|
||||
+ {
|
||||
+ grub_dprintf ("disk", "failed to open the disk while iterating FCP disk path=%s\n", buf);
|
||||
+ grub_free (nvme_controllers_table);
|
||||
+ grub_free (buf);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Call to nvme-discovery-controllers method from the nvme-of layer
|
||||
+ * to get a list of the NVMe discovery controllers per the binding
|
||||
+ */
|
||||
+ INIT_IEEE1275_COMMON (&nvme_discovery_controllers_args.common, "call-method", 2, 2);
|
||||
+ nvme_discovery_controllers_args.method = (grub_ieee1275_cell_t) "nvme-discovery-controllers";
|
||||
+ nvme_discovery_controllers_args.ihandle = ihandle;
|
||||
+ if (IEEE1275_CALL_ENTRY_FN (&nvme_discovery_controllers_args) == -1)
|
||||
+ {
|
||||
+ grub_dprintf ("disk", "failed to get the targets while iterating FCP disk path=%s\n", buf);
|
||||
+ grub_free (nvme_controllers_table);
|
||||
+ grub_free (buf);
|
||||
+ grub_ieee1275_close (ihandle);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* After closing the device, the info is lost. So lets copy each buffer in the buffers table */
|
||||
+ discovery_controllers_table.len = (grub_uint32_t) nvme_discovery_controllers_args.nentries;
|
||||
+
|
||||
+ for (i = 0; i < discovery_controllers_table.len; i++)
|
||||
+ {
|
||||
+ discovery_controllers_table.table[i] = ((grub_uint64_t*) nvme_discovery_controllers_args.table)[i];
|
||||
+ }
|
||||
+ grub_ieee1275_close (ihandle);
|
||||
+ grub_dprintf ("ofdisk","NVMeoF: Found %d discovery controllers\n", discovery_controllers_table.len);
|
||||
+
|
||||
+ /* For each nvme discovery controller */
|
||||
+ for (current_buffer_index = 0; current_buffer_index < (int) discovery_controllers_table.len; current_buffer_index++)
|
||||
+ {
|
||||
+ grub_snprintf (bufptr, 64, "/nvme-of/controller@%" PRIxGRUB_UINT64_T ",ffff",
|
||||
+ discovery_controllers_table.table[current_buffer_index]);
|
||||
+ grub_dprintf ("ofdisk", "nvmeof controller=%s\n", buf);
|
||||
+ if (grub_ieee1275_open (buf, &ihandle))
|
||||
+ {
|
||||
+ grub_dprintf ("ofdisk", "failed to open the disk while getting nvme-controllers path=%s\n", buf);
|
||||
+ continue;
|
||||
+ }
|
||||
+ INIT_IEEE1275_COMMON (&nvme_controllers_args.common, "call-method", 2, 2);
|
||||
+ nvme_controllers_args.method = (grub_ieee1275_cell_t) "nvme-controllers";
|
||||
+ nvme_controllers_args.ihandle = ihandle;
|
||||
+ nvme_controllers_args.catch_result = 0;
|
||||
+
|
||||
+ if (IEEE1275_CALL_ENTRY_FN (&nvme_controllers_args) == -1)
|
||||
+ {
|
||||
+ grub_dprintf ("ofdisk", "failed to get the nvme-controllers while iterating FCP disk path\n");
|
||||
+ grub_ieee1275_close (ihandle);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ /* Copy the buffer list to nvme_controllers_table */
|
||||
+ nvme_controllers_table_entries = ((grub_uint32_t) nvme_controllers_args.nentries);
|
||||
+ nvme_controllers_table_buf = (struct nvme_controllers_table_entry*) nvme_controllers_args.table;
|
||||
+ for (i = 0; i < nvme_controllers_table_entries; i++)
|
||||
+ {
|
||||
+ nvme_controllers_table[i].id = (grub_uint16_t) nvme_controllers_table_buf[i].id;
|
||||
+ grub_strcpy (nvme_controllers_table[i].wwpn, nvme_controllers_table_buf[i].wwpn);
|
||||
+ grub_strcpy (nvme_controllers_table[i].nqn, nvme_controllers_table_buf[i].nqn);
|
||||
+ }
|
||||
+ grub_ieee1275_close (ihandle);
|
||||
+ grub_dprintf ("ofdisk", "NVMeoF: found %d nvme controllers\n", (int) nvme_controllers_args.nentries);
|
||||
+
|
||||
+ /* For each nvme controller */
|
||||
+ for (nvme_controller_index = 0; nvme_controller_index < (int) nvme_controllers_args.nentries; nvme_controller_index++)
|
||||
+ {
|
||||
+ /*
|
||||
+ * Open the nvme controller
|
||||
+ * /pci@bus/fibre-channel@dev,func/nvme-of/controller@transport-addr,ctlr-id:nqn=tgt-subsystem-nqn
|
||||
+ */
|
||||
+ bufptr_pos2 = grub_snprintf (bufptr, 512, "/nvme-of/controller@%s,ffff:nqn=%s",
|
||||
+ nvme_controllers_table[nvme_controller_index].wwpn,
|
||||
+ nvme_controllers_table[nvme_controller_index].nqn);
|
||||
+ grub_dprintf ("ofdisk", "NVMeoF: nvmeof controller=%s\n", buf);
|
||||
+ if (grub_ieee1275_open (buf, &ihandle))
|
||||
+ {
|
||||
+ grub_dprintf ("ofdisk", "failed to open the path=%s\n", buf);
|
||||
+ continue;
|
||||
+ }
|
||||
+ INIT_IEEE1275_COMMON (&nvme_namespaces_args.common, "call-method", 2, 2);
|
||||
+ nvme_namespaces_args.method = (grub_ieee1275_cell_t) "get-namespace-list";
|
||||
+ nvme_namespaces_args.ihandle = ihandle;
|
||||
+ nvme_namespaces_args.catch_result = 0;
|
||||
+
|
||||
+ if (IEEE1275_CALL_ENTRY_FN (&nvme_namespaces_args) == -1)
|
||||
+ {
|
||||
+ grub_dprintf ("ofdisk", "failed to get the nvme-namespace-list while iterating FCP disk path\n");
|
||||
+ grub_ieee1275_close (ihandle);
|
||||
+ continue;
|
||||
+ }
|
||||
+ grub_uint32_t *namespaces = (grub_uint32_t*) nvme_namespaces_args.table;
|
||||
+ grub_dprintf ("ofdisk", "NVMeoF: found %d namespaces\n", (int)nvme_namespaces_args.nentries);
|
||||
+ grub_ieee1275_close (ihandle);
|
||||
+ namespace_index = 0;
|
||||
+ for (namespace_index=0; namespace_index < nvme_namespaces_args.nentries; namespace_index++)
|
||||
+ {
|
||||
+ grub_snprintf (bufptr+bufptr_pos2, 512, "/namespace@%"PRIxGRUB_UINT32_T, namespaces[namespace_index]);
|
||||
+ grub_dprintf ("ofdisk", "NVMeoF: namespace=%s\n", buf);
|
||||
+ dev_iterate_real (buf, buf);
|
||||
+ }
|
||||
+ dev_iterate_real (buf, buf);
|
||||
+ }
|
||||
+ }
|
||||
+ grub_free (buf);
|
||||
+ grub_free (nvme_controllers_table);
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
static void
|
||||
dev_iterate (const struct grub_ieee1275_devalias *alias)
|
||||
{
|
||||
if (grub_strcmp (alias->type, "fcp") == 0)
|
||||
{
|
||||
- /*
|
||||
- * If we are dealing with fcp devices, we need
|
||||
- * to find the WWPNs and LUNs to iterate them
|
||||
- */
|
||||
- grub_ieee1275_ihandle_t ihandle;
|
||||
- grub_uint64_t *ptr_targets, *ptr_luns, k, l;
|
||||
- unsigned int i, j, pos;
|
||||
- char *buf, *bufptr;
|
||||
- struct set_fcp_targets_args
|
||||
- {
|
||||
- struct grub_ieee1275_common_hdr common;
|
||||
- grub_ieee1275_cell_t method;
|
||||
- grub_ieee1275_cell_t ihandle;
|
||||
- grub_ieee1275_cell_t catch_result;
|
||||
- grub_ieee1275_cell_t nentries;
|
||||
- grub_ieee1275_cell_t table;
|
||||
- } args_targets;
|
||||
-
|
||||
- struct set_fcp_luns_args
|
||||
- {
|
||||
- struct grub_ieee1275_common_hdr common;
|
||||
- grub_ieee1275_cell_t method;
|
||||
- grub_ieee1275_cell_t ihandle;
|
||||
- grub_ieee1275_cell_t wwpn_h;
|
||||
- grub_ieee1275_cell_t wwpn_l;
|
||||
- grub_ieee1275_cell_t catch_result;
|
||||
- grub_ieee1275_cell_t nentries;
|
||||
- grub_ieee1275_cell_t table;
|
||||
- } args_luns;
|
||||
-
|
||||
- struct args_ret
|
||||
- {
|
||||
- grub_uint64_t addr;
|
||||
- grub_uint64_t len;
|
||||
- };
|
||||
-
|
||||
- if (grub_ieee1275_open (alias->path, &ihandle))
|
||||
- {
|
||||
- grub_dprintf ("disk", "failed to open the disk while iterating FCP disk path=%s\n", alias->path);
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- /* Setup the fcp-targets method to call via pfw*/
|
||||
- INIT_IEEE1275_COMMON (&args_targets.common, "call-method", 2, 3);
|
||||
- args_targets.method = (grub_ieee1275_cell_t) "fcp-targets";
|
||||
- args_targets.ihandle = ihandle;
|
||||
-
|
||||
- /* Setup the fcp-luns method to call via pfw */
|
||||
- INIT_IEEE1275_COMMON (&args_luns.common, "call-method", 4, 3);
|
||||
- args_luns.method = (grub_ieee1275_cell_t) "fcp-luns";
|
||||
- args_luns.ihandle = ihandle;
|
||||
- if (IEEE1275_CALL_ENTRY_FN (&args_targets) == -1)
|
||||
- {
|
||||
- grub_dprintf ("disk", "failed to get the targets while iterating FCP disk path=%s\n", alias->path);
|
||||
- grub_ieee1275_close (ihandle);
|
||||
- return;
|
||||
- }
|
||||
- buf = grub_malloc (grub_strlen (alias->path) + 32 + 32);
|
||||
- if (!buf)
|
||||
- {
|
||||
- grub_ieee1275_close (ihandle);
|
||||
- return;
|
||||
- }
|
||||
- bufptr = grub_stpcpy (buf, alias->path);
|
||||
-
|
||||
- /*
|
||||
- * Iterate over entries returned by pfw. Each entry contains a
|
||||
- * pointer to wwpn table and his length.
|
||||
- */
|
||||
- struct args_ret *targets_table = (struct args_ret *) (args_targets.table);
|
||||
- for (i = 0; i < args_targets.nentries; i++)
|
||||
- {
|
||||
- ptr_targets = (grub_uint64_t*) targets_table[i].addr;
|
||||
- /* Iterate over all wwpns in given table */
|
||||
- for(k = 0; k < targets_table[i].len; k++)
|
||||
- {
|
||||
- args_luns.wwpn_l = (grub_ieee1275_cell_t) (*ptr_targets);
|
||||
- args_luns.wwpn_h = (grub_ieee1275_cell_t) (*ptr_targets >> 32);
|
||||
- pos = grub_snprintf (bufptr, 32, "/disk@%" PRIxGRUB_UINT64_T,
|
||||
- grub_get_unaligned64 (*ptr_targets++));
|
||||
- /* Get the luns for given wwpn target */
|
||||
- if (IEEE1275_CALL_ENTRY_FN (&args_luns) == -1)
|
||||
- {
|
||||
- grub_dprintf ("disk", "failed to get the LUNS while iterating FCP disk path=%s\n", buf);
|
||||
- grub_ieee1275_close (ihandle);
|
||||
- grub_free (buf);
|
||||
- return;
|
||||
- }
|
||||
- struct args_ret *luns_table = (struct args_ret *) (args_luns.table);
|
||||
-
|
||||
- /* Iterate over all LUNs */
|
||||
- for(j = 0; j < args_luns.nentries; j++)
|
||||
- {
|
||||
- ptr_luns = (grub_uint64_t*) luns_table[j].addr;
|
||||
- for(l = 0; l < luns_table[j].len; l++)
|
||||
- {
|
||||
- grub_snprintf (&bufptr[pos], 30, ",%" PRIxGRUB_UINT64_T,
|
||||
- grub_get_unaligned64 (*ptr_luns++));
|
||||
- dev_iterate_real (buf, buf);
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
- grub_ieee1275_close (ihandle);
|
||||
- grub_free (buf);
|
||||
- return;
|
||||
+ /* Iterate disks */
|
||||
+ dev_iterate_fcp_disks (alias);
|
||||
+ /* Iterate NVMeoF */
|
||||
+ dev_iterate_fcp_nvmeof (alias);
|
||||
}
|
||||
else if (grub_strcmp (alias->type, "vscsi") == 0)
|
||||
{
|
||||
@ -534,3 +534,9 @@ Patch0534: 0534-util-grub-mkimagexx-Stop-generating-unaligned-append.patch
|
||||
Patch0535: 0535-grub-mkimage-Do-not-generate-empty-SBAT-metadata.patch
|
||||
Patch0536: 0536-kern-efi-mm-Change-grub_efi_mm_add_regions-to-keep-t.patch
|
||||
Patch0537: 0537-Change-login-error-message.patch
|
||||
Patch0538: 0538-ieee1275-powerpc-implements-fibre-channel-discovery-.patch
|
||||
Patch0539: 0539-ieee1275-implement-FCP-methods-for-WWPN-and-LUNs.patch
|
||||
Patch0540: 0540-ieee1275-change-the-logic-of-ieee1275_get_devargs.patch
|
||||
Patch0541: 0541-ieee1275-ofpath-enable-NVMeoF-logical-device-transla.patch
|
||||
Patch0542: 0542-ieee1275-support-added-for-multiple-nvme-bootpaths.patch
|
||||
Patch0543: 0543-ieee1275-add-support-for-NVMeoFC.patch
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
Name: grub2
|
||||
Epoch: 1
|
||||
Version: 2.06
|
||||
Release: 128%{?dist}
|
||||
Release: 129%{?dist}
|
||||
Summary: Bootloader with support for Linux, Multiboot and more
|
||||
License: GPLv3+
|
||||
URL: http://www.gnu.org/software/grub/
|
||||
@ -543,6 +543,10 @@ fi
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Thu Jun 18 2026 Nicolas Frayer <nfrayer@redhat.com> 2.06-129
|
||||
- ieee1275/powerpc: implements fibre channel discovery for ofpathname
|
||||
- Resolves: #RHEL-53369
|
||||
|
||||
* Fri Jun 05 2026 Nicolas Frayer <nfrayer@redhat.com> 2.06-128
|
||||
- CentOS: Sign grub with 802
|
||||
- Resolves: #RHEL-182487
|
||||
|
||||
Loading…
Reference in New Issue
Block a user