* [PATCH v3 1/6] ieee1275/powerpc: implements fibre channel discovery for ofpathname
2024-06-06 12:37 [PATCH v3 0/6] NVMeoFC support on Grub Avnish Chouhan
@ 2024-06-06 12:37 ` Avnish Chouhan
2024-06-26 10:17 ` Michael Chang via Grub-devel
2024-06-06 12:37 ` [PATCH v3 2/6] ieee1275/powerpc: enables device mapper discovery Avnish Chouhan
` (4 subsequent siblings)
5 siblings, 1 reply; 13+ messages in thread
From: Avnish Chouhan @ 2024-06-06 12:37 UTC (permalink / raw)
To: grub-devel
Cc: daniel.kiper, brking, meghanaprakash, Avnish Chouhan,
Diego Domingos
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>
---
grub-core/osdep/linux/ofpath.c | 49 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 49 insertions(+)
diff --git a/grub-core/osdep/linux/ofpath.c b/grub-core/osdep/linux/ofpath.c
index a6153d35954..0f5d54e9f2d 100644
--- a/grub-core/osdep/linux/ofpath.c
+++ b/grub-core/osdep/linux/ofpath.c
@@ -350,6 +350,38 @@ of_path_of_ide(const char *sys_devname __attribute__((unused)), const char *devi
return ret;
}
+
+static void
+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));
+
+ /* 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);
+
+ /* 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)
+ grub_util_error (_("cannot read `%s': %s"), bname, strerror (errno));
+
+ sscanf (port_name, "0x%s", port_name);
+
+ close (fd);
+
+ free (bname);
+ free (basepath);
+}
+
#ifdef __sparc__
static char *
of_path_of_nvme(const char *sys_devname __attribute__((unused)),
@@ -577,6 +609,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);
+ }
+ else
+ {
unsigned long id = 0x8000 | (tgt << 8) | (bus << 5) | lun;
if (*digit_string == '\0')
{
@@ -590,6 +632,13 @@ of_path_of_scsi(const char *sys_devname __attribute__((unused)), const char *dev
snprintf(disk, sizeof (disk),
"/%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
{
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [PATCH v3 1/6] ieee1275/powerpc: implements fibre channel discovery for ofpathname
2024-06-06 12:37 ` [PATCH v3 1/6] ieee1275/powerpc: implements fibre channel discovery for ofpathname Avnish Chouhan
@ 2024-06-26 10:17 ` Michael Chang via Grub-devel
0 siblings, 0 replies; 13+ messages in thread
From: Michael Chang via Grub-devel @ 2024-06-26 10:17 UTC (permalink / raw)
To: The development of GNU GRUB
Cc: Michael Chang, daniel.kiper, brking, meghanaprakash,
Avnish Chouhan, Diego Domingos
On Thu, Jun 06, 2024 at 06:07:22PM GMT, Avnish Chouhan wrote:
> 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>
> ---
> grub-core/osdep/linux/ofpath.c | 49 ++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 49 insertions(+)
>
> diff --git a/grub-core/osdep/linux/ofpath.c b/grub-core/osdep/linux/ofpath.c
> index a6153d35954..0f5d54e9f2d 100644
> --- a/grub-core/osdep/linux/ofpath.c
> +++ b/grub-core/osdep/linux/ofpath.c
> @@ -350,6 +350,38 @@ of_path_of_ide(const char *sys_devname __attribute__((unused)), const char *devi
> return ret;
> }
>
> +
> +static void
> +of_fc_port_name (const char *path, const char *subpath, char *port_name)
> +{
> + char *bname, *basepath, *p;
> + int fd;
> +
> + bname = xmalloc (sizeof (char) * 150);
Why not `char bname[150]` for simplicty ? Is there any reason behind the magic number
150?
> + 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';
I think it can be replaced by `strndup()` for simplicity.
> + p = get_basename (basepath);
> + snprintf (bname, sizeof (char) * 150, "%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)
> + grub_util_error (_("cannot read `%s': %s"), bname, strerror (errno));
The caller has the port_name's size set to `sizeof (char) * 17`, the
read() may really be overreading, and overflowing port_name.
Moreover the function didn't have a way to check to size of port_name.
> +
> + sscanf (port_name, "0x%s", port_name);
> +
> + close (fd);
> +
> + free (bname);
> + free (basepath);
> +}
> +
> #ifdef __sparc__
> static char *
> of_path_of_nvme(const char *sys_devname __attribute__((unused)),
> @@ -577,6 +609,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);
Again why not `char port_name[17]` ? And lacking of description for
magic number 17.
> + of_fc_port_name (sysfs_path, p, port_name);
Please add an argument, port_name_size, for boundary checking in
of_fc_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')
> {
> @@ -590,6 +632,13 @@ of_path_of_scsi(const char *sys_devname __attribute__((unused)), const char *dev
> snprintf(disk, sizeof (disk),
> "/%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);
Ditto.
Thanks,
Michael
> }
> else
> {
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> https://lists.gnu.org/mailman/listinfo/grub-devel
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v3 2/6] ieee1275/powerpc: enables device mapper discovery
2024-06-06 12:37 [PATCH v3 0/6] NVMeoFC support on Grub Avnish Chouhan
2024-06-06 12:37 ` [PATCH v3 1/6] ieee1275/powerpc: implements fibre channel discovery for ofpathname Avnish Chouhan
@ 2024-06-06 12:37 ` Avnish Chouhan
2024-06-06 15:34 ` Vladimir 'phcoder' Serbinenko
2024-06-06 12:37 ` [PATCH v3 3/6] ieee1275: implement FCP methods for WWPN and LUNs Avnish Chouhan
` (3 subsequent siblings)
5 siblings, 1 reply; 13+ messages in thread
From: Avnish Chouhan @ 2024-06-06 12:37 UTC (permalink / raw)
To: grub-devel
Cc: daniel.kiper, brking, meghanaprakash, Avnish Chouhan,
Diego Domingos
This patch enables the device mapper discovery on ofpath.c. Currently,
when we are dealing with a device like /dev/dm-* the ofpath returns null
since there is no function implemented to handle this case.
This patch implements a function that will look into /sys/block/dm-*
devices and search recursively inside slaves directory to find the root
disk.
Signed-off-by: Diego Domingos <diegodo@br.ibm.com>
Signed-off-by: Avnish Chouhan <avnish@linux.ibm.com>
---
grub-core/osdep/linux/ofpath.c | 64 +++++++++++++++++++++++++++++++++++++++++-
1 file changed, 63 insertions(+), 1 deletion(-)
diff --git a/grub-core/osdep/linux/ofpath.c b/grub-core/osdep/linux/ofpath.c
index 0f5d54e9f2d..cc849d9c94c 100644
--- a/grub-core/osdep/linux/ofpath.c
+++ b/grub-core/osdep/linux/ofpath.c
@@ -37,6 +37,7 @@
#include <fcntl.h>
#include <errno.h>
#include <ctype.h>
+#include <dirent.h>
#ifdef __sparc__
typedef enum
@@ -755,13 +756,74 @@ strip_trailing_digits (const char *p)
return new;
}
+static char *
+get_slave_from_dm (const char * device)
+{
+ char *curr_device, *tmp;
+ char *directory;
+ char *ret = NULL;
+ directory = grub_strdup (device);
+ tmp = get_basename (directory);
+ curr_device = grub_strdup (tmp);
+ *tmp = '\0';
+
+ /* Recursively check for slaves devices so we can find the root device */
+ while ((curr_device[0] == 'd') && (curr_device[1] == 'm') && (curr_device[2] == '-'))
+ {
+ DIR *dp;
+ struct dirent *ep;
+ char* device_path;
+ device_path = grub_xasprintf ("/sys/block/%s/slaves", curr_device);
+ dp = opendir (device_path);
+
+ if (dp != NULL)
+ {
+ ep = readdir (dp);
+
+ while (ep != NULL)
+ {
+ /* avoid some system directories */
+ if (!strcmp(ep->d_name,"."))
+ goto next_dir;
+ if (!strcmp(ep->d_name,".."))
+ goto next_dir;
+
+ free (curr_device);
+ free (ret);
+ curr_device = grub_strdup (ep->d_name);
+ ret = grub_xasprintf ("%s%s", directory, curr_device);
+ break;
+
+ next_dir:
+ ep = readdir (dp);
+ continue;
+ }
+ closedir (dp);
+ }
+ else
+ grub_util_warn (_("cannot open directory `%s'"), device_path);
+ free (device_path);
+ }
+ free (directory);
+ free (curr_device);
+
+ return ret;
+}
+
char *
grub_util_devname_to_ofpath (const char *sys_devname)
{
- char *name_buf, *device, *devnode, *devicenode, *ofpath;
+ char *name_buf, *device, *devnode, *devicenode, *ofpath, *realname;
name_buf = xrealpath (sys_devname);
+ realname = get_slave_from_dm (name_buf);
+ if (realname)
+ {
+ free (name_buf);
+ name_buf = realname;
+ }
+
device = get_basename (name_buf);
devnode = strip_trailing_digits (name_buf);
devicenode = strip_trailing_digits (device);
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [PATCH v3 2/6] ieee1275/powerpc: enables device mapper discovery
2024-06-06 12:37 ` [PATCH v3 2/6] ieee1275/powerpc: enables device mapper discovery Avnish Chouhan
@ 2024-06-06 15:34 ` Vladimir 'phcoder' Serbinenko
2024-06-07 8:34 ` avnish
0 siblings, 1 reply; 13+ messages in thread
From: Vladimir 'phcoder' Serbinenko @ 2024-06-06 15:34 UTC (permalink / raw)
To: The development of GNU GRUB
Cc: Daniel Kiper, brking, meghanaprakash, Avnish Chouhan,
Diego Domingos
[-- Attachment #1.1: Type: text/plain, Size: 3723 bytes --]
2 problems:
* How does dm device ends up on ofpathname? It should be handled by grub
internal logic in most cases and not end up in of-specific paths
* Why not use existing devmapper functions already present in codebase?
Le jeu. 6 juin 2024, 14:40, Avnish Chouhan <avnish@linux.ibm.com> a écrit :
> This patch enables the device mapper discovery on ofpath.c. Currently,
> when we are dealing with a device like /dev/dm-* the ofpath returns null
> since there is no function implemented to handle this case.
>
> This patch implements a function that will look into /sys/block/dm-*
> devices and search recursively inside slaves directory to find the root
> disk.
>
> Signed-off-by: Diego Domingos <diegodo@br.ibm.com>
> Signed-off-by: Avnish Chouhan <avnish@linux.ibm.com>
> ---
> grub-core/osdep/linux/ofpath.c | 64
> +++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 63 insertions(+), 1 deletion(-)
>
> diff --git a/grub-core/osdep/linux/ofpath.c
> b/grub-core/osdep/linux/ofpath.c
> index 0f5d54e9f2d..cc849d9c94c 100644
> --- a/grub-core/osdep/linux/ofpath.c
> +++ b/grub-core/osdep/linux/ofpath.c
> @@ -37,6 +37,7 @@
> #include <fcntl.h>
> #include <errno.h>
> #include <ctype.h>
> +#include <dirent.h>
>
> #ifdef __sparc__
> typedef enum
> @@ -755,13 +756,74 @@ strip_trailing_digits (const char *p)
> return new;
> }
>
> +static char *
> +get_slave_from_dm (const char * device)
> +{
> + char *curr_device, *tmp;
> + char *directory;
> + char *ret = NULL;
> + directory = grub_strdup (device);
> + tmp = get_basename (directory);
> + curr_device = grub_strdup (tmp);
> + *tmp = '\0';
> +
> + /* Recursively check for slaves devices so we can find the root device
> */
> + while ((curr_device[0] == 'd') && (curr_device[1] == 'm') &&
> (curr_device[2] == '-'))
> + {
> + DIR *dp;
> + struct dirent *ep;
> + char* device_path;
> + device_path = grub_xasprintf ("/sys/block/%s/slaves", curr_device);
> + dp = opendir (device_path);
> +
> + if (dp != NULL)
> + {
> + ep = readdir (dp);
> +
> + while (ep != NULL)
> + {
> + /* avoid some system directories */
> + if (!strcmp(ep->d_name,"."))
> + goto next_dir;
> + if (!strcmp(ep->d_name,".."))
> + goto next_dir;
> +
> + free (curr_device);
> + free (ret);
> + curr_device = grub_strdup (ep->d_name);
> + ret = grub_xasprintf ("%s%s", directory, curr_device);
> + break;
> +
> + next_dir:
> + ep = readdir (dp);
> + continue;
> + }
> + closedir (dp);
> + }
> + else
> + grub_util_warn (_("cannot open directory `%s'"), device_path);
> + free (device_path);
> + }
> + free (directory);
> + free (curr_device);
> +
> + return ret;
> +}
> +
> char *
> grub_util_devname_to_ofpath (const char *sys_devname)
> {
> - char *name_buf, *device, *devnode, *devicenode, *ofpath;
> + char *name_buf, *device, *devnode, *devicenode, *ofpath, *realname;
>
> name_buf = xrealpath (sys_devname);
>
> + realname = get_slave_from_dm (name_buf);
> + if (realname)
> + {
> + free (name_buf);
> + name_buf = realname;
> + }
> +
> device = get_basename (name_buf);
> devnode = strip_trailing_digits (name_buf);
> devicenode = strip_trailing_digits (device);
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> https://lists.gnu.org/mailman/listinfo/grub-devel
>
[-- Attachment #1.2: Type: text/html, Size: 4911 bytes --]
[-- Attachment #2: Type: text/plain, Size: 141 bytes --]
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH v3 2/6] ieee1275/powerpc: enables device mapper discovery
2024-06-06 15:34 ` Vladimir 'phcoder' Serbinenko
@ 2024-06-07 8:34 ` avnish
2024-06-07 9:34 ` Vladimir 'phcoder' Serbinenko
0 siblings, 1 reply; 13+ messages in thread
From: avnish @ 2024-06-07 8:34 UTC (permalink / raw)
To: Vladimir 'phcoder' Serbinenko
Cc: The development of GNU GRUB, Daniel Kiper, brking, meghanaprakash,
Diego Domingos
On 2024-06-06 21:04, Vladimir 'phcoder' Serbinenko wrote:
> 2 problems: * How does dm device ends up on ofpathname? It should be
> handled by grub internal logic in most cases and not end up in
> of-specific paths * Why not use existing devmapper functions already
> present in codebase? Le jeu. 6 juin 2024,
> ZjQcmQRYFpfptBannerStart
>
> This Message Is From an External Sender
> This message came from outside your organization.
>
> Report Suspicious
>
> ZjQcmQRYFpfptBannerEnd
> 2 problems:
> * How does dm device ends up on ofpathname? It should be handled by
> grub internal logic in most cases and not end up in of-specific paths
> * Why not use existing devmapper functions already present in
> codebase?
>
Hi Vladimir,
Thank you so much for your response!
We have observed that whenever we are dealing with the devices like
"/dev/dm-*", the ofpath returns null.
To resolve this, as no such required functions has been implemented to
handle this kind of case. We have done changes based on the requirement
that will look into /sys/block/dm-* devices and search slave
devices recursively inside slaves directory to find the root disk.
Regards,
Avnish Chouhan
> Le jeu. 6 juin 2024, 14:40, Avnish Chouhan <avnish@linux.ibm.com> a
> écrit :
>
>> This patch enables the device mapper discovery on ofpath.c.
>> Currently,
>> when we are dealing with a device like /dev/dm-* the ofpath returns
>> null
>> since there is no function implemented to handle this case.
>>
>> This patch implements a function that will look into /sys/block/dm-*
>> devices and search recursively inside slaves directory to find the
>> root
>> disk.
>>
>> Signed-off-by: Diego Domingos <diegodo@br.ibm.com>
>> Signed-off-by: Avnish Chouhan <avnish@linux.ibm.com>
>> ---
>> grub-core/osdep/linux/ofpath.c | 64
>> +++++++++++++++++++++++++++++++++++++++++-
>> 1 file changed, 63 insertions(+), 1 deletion(-)
>>
>> diff --git a/grub-core/osdep/linux/ofpath.c
>> b/grub-core/osdep/linux/ofpath.c
>> index 0f5d54e9f2d..cc849d9c94c 100644
>> --- a/grub-core/osdep/linux/ofpath.c
>> +++ b/grub-core/osdep/linux/ofpath.c
>> @@ -37,6 +37,7 @@
>> #include <fcntl.h>
>> #include <errno.h>
>> #include <ctype.h>
>> +#include <dirent.h>
>>
>> #ifdef __sparc__
>> typedef enum
>> @@ -755,13 +756,74 @@ strip_trailing_digits (const char *p)
>> return new;
>> }
>>
>> +static char *
>> +get_slave_from_dm (const char * device)
>> +{
>> + char *curr_device, *tmp;
>> + char *directory;
>> + char *ret = NULL;
>> + directory = grub_strdup (device);
>> + tmp = get_basename (directory);
>> + curr_device = grub_strdup (tmp);
>> + *tmp = '\0';
>> +
>> + /* Recursively check for slaves devices so we can find the root
>> device */
>> + while ((curr_device[0] == 'd') && (curr_device[1] == 'm') &&
>> (curr_device[2] == '-'))
>> + {
>> + DIR *dp;
>> + struct dirent *ep;
>> + char* device_path;
>> + device_path = grub_xasprintf ("/sys/block/%s/slaves",
>> curr_device);
>> + dp = opendir (device_path);
>> +
>> + if (dp != NULL)
>> + {
>> + ep = readdir (dp);
>> +
>> + while (ep != NULL)
>> + {
>> + /* avoid some system directories */
>> + if (!strcmp(ep->d_name,"."))
>> + goto next_dir;
>> + if (!strcmp(ep->d_name,".."))
>> + goto next_dir;
>> +
>> + free (curr_device);
>> + free (ret);
>> + curr_device = grub_strdup (ep->d_name);
>> + ret = grub_xasprintf ("%s%s", directory,
>> curr_device);
>> + break;
>> +
>> + next_dir:
>> + ep = readdir (dp);
>> + continue;
>> + }
>> + closedir (dp);
>> + }
>> + else
>> + grub_util_warn (_("cannot open directory `%s'"),
>> device_path);
>> + free (device_path);
>> + }
>> + free (directory);
>> + free (curr_device);
>> +
>> + return ret;
>> +}
>> +
>> char *
>> grub_util_devname_to_ofpath (const char *sys_devname)
>> {
>> - char *name_buf, *device, *devnode, *devicenode, *ofpath;
>> + char *name_buf, *device, *devnode, *devicenode, *ofpath,
>> *realname;
>>
>> name_buf = xrealpath (sys_devname);
>>
>> + realname = get_slave_from_dm (name_buf);
>> + if (realname)
>> + {
>> + free (name_buf);
>> + name_buf = realname;
>> + }
>> +
>> device = get_basename (name_buf);
>> devnode = strip_trailing_digits (name_buf);
>> devicenode = strip_trailing_digits (device);
>>
>> _______________________________________________
>> Grub-devel mailing list
>> Grub-devel@gnu.org
>> https://lists.gnu.org/mailman/listinfo/grub-devel
>
>
> Links:
> ------
> [1]
> https://us-phishalarm-ewt.proofpoint.com/EWT/v1/AdhS1Rd-!-XFVHHiYfI50ul9XDgoDMf5HTGn83xsPPR4XT9wPzmu8earnN0GgLmGjgJ1wrY0OEeVCDtYQvZuy51BEuwbJ2Q36rjgqhgETNXQL18Hn2QOfpE6f2H9XOn8Mici5$
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH v3 2/6] ieee1275/powerpc: enables device mapper discovery
2024-06-07 8:34 ` avnish
@ 2024-06-07 9:34 ` Vladimir 'phcoder' Serbinenko
0 siblings, 0 replies; 13+ messages in thread
From: Vladimir 'phcoder' Serbinenko @ 2024-06-07 9:34 UTC (permalink / raw)
To: avnish
Cc: The development of GNU GRUB, Daniel Kiper, brking, meghanaprakash,
Diego Domingos
[-- Attachment #1.1: Type: text/plain, Size: 5732 bytes --]
Le ven. 7 juin 2024, 10:34, avnish <avnish@imap.linux.ibm.com> a écrit :
> On 2024-06-06 21:04, Vladimir 'phcoder' Serbinenko wrote:
> > 2 problems: * How does dm device ends up on ofpathname? It should be
> > handled by grub internal logic in most cases and not end up in
> > of-specific paths * Why not use existing devmapper functions already
> > present in codebase? Le jeu. 6 juin 2024,
> > ZjQcmQRYFpfptBannerStart
> >
> > This Message Is From an External Sender
> > This message came from outside your organization.
> >
> > Report Suspicious
> >
> > ZjQcmQRYFpfptBannerEnd
> > 2 problems:
> > * How does dm device ends up on ofpathname? It should be handled by
> > grub internal logic in most cases and not end up in of-specific paths
> > * Why not use existing devmapper functions already present in
> > codebase?
> >
>
> Hi Vladimir,
> Thank you so much for your response!
>
> We have observed that whenever we are dealing with the devices like
> "/dev/dm-*", the ofpath returns null.
>
It's expected behavior
> To resolve this, as no such required functions has been implemented to
> handle this kind of case. We have done changes based on the requirement
> that will look into /sys/block/dm-* devices and search slave
> devices recursively inside slaves directory to find the root disk.
Installing on e.g. LVM is invalid. Only 3 cases can your approach work:
1) multipath
2) maybe RAID1 as well in some cases
3) if ofw assembles raid somehow
Which one do you have? We need more details.
This patch enables invalid configs like installing on LVM
>
> Regards,
> Avnish Chouhan
>
> > Le jeu. 6 juin 2024, 14:40, Avnish Chouhan <avnish@linux.ibm.com> a
> > écrit :
> >
> >> This patch enables the device mapper discovery on ofpath.c.
> >> Currently,
> >> when we are dealing with a device like /dev/dm-* the ofpath returns
> >> null
> >> since there is no function implemented to handle this case.
> >>
> >> This patch implements a function that will look into /sys/block/dm-*
> >> devices and search recursively inside slaves directory to find the
> >> root
> >> disk.
> >>
> >> Signed-off-by: Diego Domingos <diegodo@br.ibm.com>
> >> Signed-off-by: Avnish Chouhan <avnish@linux.ibm.com>
> >> ---
> >> grub-core/osdep/linux/ofpath.c | 64
> >> +++++++++++++++++++++++++++++++++++++++++-
> >> 1 file changed, 63 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/grub-core/osdep/linux/ofpath.c
> >> b/grub-core/osdep/linux/ofpath.c
> >> index 0f5d54e9f2d..cc849d9c94c 100644
> >> --- a/grub-core/osdep/linux/ofpath.c
> >> +++ b/grub-core/osdep/linux/ofpath.c
> >> @@ -37,6 +37,7 @@
> >> #include <fcntl.h>
> >> #include <errno.h>
> >> #include <ctype.h>
> >> +#include <dirent.h>
> >>
> >> #ifdef __sparc__
> >> typedef enum
> >> @@ -755,13 +756,74 @@ strip_trailing_digits (const char *p)
> >> return new;
> >> }
> >>
> >> +static char *
> >> +get_slave_from_dm (const char * device)
> >> +{
> >> + char *curr_device, *tmp;
> >> + char *directory;
> >> + char *ret = NULL;
> >> + directory = grub_strdup (device);
> >> + tmp = get_basename (directory);
> >> + curr_device = grub_strdup (tmp);
> >> + *tmp = '\0';
> >> +
> >> + /* Recursively check for slaves devices so we can find the root
> >> device */
> >> + while ((curr_device[0] == 'd') && (curr_device[1] == 'm') &&
> >> (curr_device[2] == '-'))
> >> + {
> >> + DIR *dp;
> >> + struct dirent *ep;
> >> + char* device_path;
> >> + device_path = grub_xasprintf ("/sys/block/%s/slaves",
> >> curr_device);
> >> + dp = opendir (device_path);
> >> +
> >> + if (dp != NULL)
> >> + {
> >> + ep = readdir (dp);
> >> +
> >> + while (ep != NULL)
> >> + {
> >> + /* avoid some system directories */
> >> + if (!strcmp(ep->d_name,"."))
> >> + goto next_dir;
> >> + if (!strcmp(ep->d_name,".."))
> >> + goto next_dir;
> >> +
> >> + free (curr_device);
> >> + free (ret);
> >> + curr_device = grub_strdup (ep->d_name);
> >> + ret = grub_xasprintf ("%s%s", directory,
> >> curr_device);
> >> + break;
> >> +
> >> + next_dir:
> >> + ep = readdir (dp);
> >> + continue;
> >> + }
> >> + closedir (dp);
> >> + }
> >> + else
> >> + grub_util_warn (_("cannot open directory `%s'"),
> >> device_path);
> >> + free (device_path);
> >> + }
> >> + free (directory);
> >> + free (curr_device);
> >> +
> >> + return ret;
> >> +}
> >> +
> >> char *
> >> grub_util_devname_to_ofpath (const char *sys_devname)
> >> {
> >> - char *name_buf, *device, *devnode, *devicenode, *ofpath;
> >> + char *name_buf, *device, *devnode, *devicenode, *ofpath,
> >> *realname;
> >>
> >> name_buf = xrealpath (sys_devname);
> >>
> >> + realname = get_slave_from_dm (name_buf);
> >> + if (realname)
> >> + {
> >> + free (name_buf);
> >> + name_buf = realname;
> >> + }
> >> +
> >> device = get_basename (name_buf);
> >> devnode = strip_trailing_digits (name_buf);
> >> devicenode = strip_trailing_digits (device);
> >>
> >> _______________________________________________
> >> Grub-devel mailing list
> >> Grub-devel@gnu.org
> >> https://lists.gnu.org/mailman/listinfo/grub-devel
> >
> >
> > Links:
> > ------
> > [1]
> >
> https://us-phishalarm-ewt.proofpoint.com/EWT/v1/AdhS1Rd-!-XFVHHiYfI50ul9XDgoDMf5HTGn83xsPPR4XT9wPzmu8earnN0GgLmGjgJ1wrY0OEeVCDtYQvZuy51BEuwbJ2Q36rjgqhgETNXQL18Hn2QOfpE6f2H9XOn8Mici5$
>
[-- Attachment #1.2: Type: text/html, Size: 8636 bytes --]
[-- Attachment #2: Type: text/plain, Size: 141 bytes --]
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v3 3/6] ieee1275: implement FCP methods for WWPN and LUNs
2024-06-06 12:37 [PATCH v3 0/6] NVMeoFC support on Grub Avnish Chouhan
2024-06-06 12:37 ` [PATCH v3 1/6] ieee1275/powerpc: implements fibre channel discovery for ofpathname Avnish Chouhan
2024-06-06 12:37 ` [PATCH v3 2/6] ieee1275/powerpc: enables device mapper discovery Avnish Chouhan
@ 2024-06-06 12:37 ` Avnish Chouhan
2024-07-01 7:34 ` Michael Chang via Grub-devel
2024-06-06 12:37 ` [PATCH v3 4/6] ieee1275: change the logic of ieee1275_get_devargs() Avnish Chouhan
` (2 subsequent siblings)
5 siblings, 1 reply; 13+ messages in thread
From: Avnish Chouhan @ 2024-06-06 12:37 UTC (permalink / raw)
To: grub-devel
Cc: daniel.kiper, brking, meghanaprakash, Avnish Chouhan,
Diego Domingos
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>
---
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 5534684..5958e5e 100644
--- a/grub-core/disk/ieee1275/ofdisk.c
+++ b/grub-core/disk/ieee1275/ofdisk.c
@@ -209,7 +209,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*) (grub_uint32_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,
+ *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*) (grub_uint32_t) luns_table[j].addr;
+ for(l = 0; l < luns_table[j].len; l++)
+ {
+ grub_snprintf (&bufptr[pos], 30, ",%" PRIxGRUB_UINT64_T,
+ *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
--
2.31.1
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [PATCH v3 3/6] ieee1275: implement FCP methods for WWPN and LUNs
2024-06-06 12:37 ` [PATCH v3 3/6] ieee1275: implement FCP methods for WWPN and LUNs Avnish Chouhan
@ 2024-07-01 7:34 ` Michael Chang via Grub-devel
2024-07-01 10:40 ` avnish
0 siblings, 1 reply; 13+ messages in thread
From: Michael Chang via Grub-devel @ 2024-07-01 7:34 UTC (permalink / raw)
To: The development of GNU GRUB
Cc: Michael Chang, daniel.kiper, brking, meghanaprakash,
Avnish Chouhan, Diego Domingos
On Thu, Jun 06, 2024 at 06:07:24PM GMT, Avnish Chouhan wrote:
> 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>
> ---
> 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 5534684..5958e5e 100644
> --- a/grub-core/disk/ieee1275/ofdisk.c
> +++ b/grub-core/disk/ieee1275/ofdisk.c
> @@ -209,7 +209,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*) (grub_uint32_t) targets_table[i].addr;
I believe a comment is needed here to explain why it is necessary to
truncate the 64-bit address into 32-bit. It appears that losing the
higher 32 bits is intentional.
> + /* 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,
> + *ptr_targets++);
As long as ptr_targets holds a pointer external to grub, the alignment
is neither validated nor guaranteed. IMHO it is safer to use
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*) (grub_uint32_t) luns_table[j].addr;
Ditto
> + for(l = 0; l < luns_table[j].len; l++)
> + {
> + grub_snprintf (&bufptr[pos], 30, ",%" PRIxGRUB_UINT64_T,
> + *ptr_luns++);
Ditto
Thanks,
Michael
> + 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
> --
> 2.31.1
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> https://lists.gnu.org/mailman/listinfo/grub-devel
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH v3 3/6] ieee1275: implement FCP methods for WWPN and LUNs
2024-07-01 7:34 ` Michael Chang via Grub-devel
@ 2024-07-01 10:40 ` avnish
0 siblings, 0 replies; 13+ messages in thread
From: avnish @ 2024-07-01 10:40 UTC (permalink / raw)
To: Michael Chang
Cc: The development of GNU GRUB, daniel.kiper, brking, meghanaprakash,
Avnish Chouhan, Diego Domingos
On 2024-07-01 13:04, Michael Chang wrote:
> On Thu, Jun 06, 2024 at 06:07:24PM GMT, Avnish Chouhan wrote:
>> 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>
>> ---
>> 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 5534684..5958e5e 100644
>> --- a/grub-core/disk/ieee1275/ofdisk.c
>> +++ b/grub-core/disk/ieee1275/ofdisk.c
>> @@ -209,7 +209,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*) (grub_uint32_t)
>> targets_table[i].addr;
>
> I believe a comment is needed here to explain why it is necessary to
> truncate the 64-bit address into 32-bit. It appears that losing the
> higher 32 bits is intentional.
>
Hi Michael,
Thank you so much for your reviews!
Sure, we'll add a comment here.
>> + /* 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,
>> + *ptr_targets++);
>
> As long as ptr_targets holds a pointer external to grub, the alignment
> is neither validated nor guaranteed. IMHO it is safer to use
> grub_get_unaligned64(ptr_targets++).
>
Sure, we can change this as suggested.
Regards,
Avnish Chouhan
>> + /* 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*) (grub_uint32_t)
>> luns_table[j].addr;
>
> Ditto
>
>> + for(l = 0; l < luns_table[j].len; l++)
>> + {
>> + grub_snprintf (&bufptr[pos], 30, ",%"
>> PRIxGRUB_UINT64_T,
>> + *ptr_luns++);
>
> Ditto
>
> Thanks,
> Michael
>
>> + 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
>> --
>> 2.31.1
>>
>>
>> _______________________________________________
>> Grub-devel mailing list
>> Grub-devel@gnu.org
>> https://lists.gnu.org/mailman/listinfo/grub-devel
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v3 4/6] ieee1275: change the logic of ieee1275_get_devargs()
2024-06-06 12:37 [PATCH v3 0/6] NVMeoFC support on Grub Avnish Chouhan
` (2 preceding siblings ...)
2024-06-06 12:37 ` [PATCH v3 3/6] ieee1275: implement FCP methods for WWPN and LUNs Avnish Chouhan
@ 2024-06-06 12:37 ` Avnish Chouhan
2024-06-06 12:37 ` [PATCH v3 5/6] ieee1275: add support for NVMeoFC Avnish Chouhan
2024-06-06 12:37 ` [PATCH v3 6/6] ieee1275: ofpath enable NVMeoF logical device translate Avnish Chouhan
5 siblings, 0 replies; 13+ messages in thread
From: Avnish Chouhan @ 2024-06-06 12:37 UTC (permalink / raw)
To: grub-devel
Cc: daniel.kiper, brking, meghanaprakash, Avnish Chouhan,
Diego Domingos
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>
---
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 0278054..b97104c 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 ();
--
2.31.1
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v3 5/6] ieee1275: add support for NVMeoFC
2024-06-06 12:37 [PATCH v3 0/6] NVMeoFC support on Grub Avnish Chouhan
` (3 preceding siblings ...)
2024-06-06 12:37 ` [PATCH v3 4/6] ieee1275: change the logic of ieee1275_get_devargs() Avnish Chouhan
@ 2024-06-06 12:37 ` Avnish Chouhan
2024-06-06 12:37 ` [PATCH v3 6/6] ieee1275: ofpath enable NVMeoF logical device translate Avnish Chouhan
5 siblings, 0 replies; 13+ messages in thread
From: Avnish Chouhan @ 2024-06-06 12:37 UTC (permalink / raw)
To: grub-devel
Cc: daniel.kiper, brking, meghanaprakash, Avnish Chouhan,
Diego Domingos
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>
---
grub-core/disk/ieee1275/ofdisk.c | 390 +++++++++++++++++++++++++++++++++++++++++--------------
1 file changed, 296 insertions(+), 94 deletions(-)
diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c
index afdc272..cea10e1 100644
--- a/grub-core/disk/ieee1275/ofdisk.c
+++ b/grub-core/disk/ieee1275/ofdisk.c
@@ -24,6 +24,8 @@
#include <grub/ieee1275/ofdisk.h>
#include <grub/i18n.h>
#include <grub/time.h>
+#define EXTEND_PATH_64 64
+#define EXTEND_PATH_512 512
static char *last_devpath;
static grub_ieee1275_ihandle_t last_ihandle;
@@ -207,116 +209,316 @@ dev_iterate_real (const char *name, const char *path)
}
static void
-dev_iterate (const struct grub_ieee1275_devalias *alias)
+dev_iterate_fcp_disks (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;
+ };
+ struct args_ret *targets_table;
+ struct args_ret *luns_table;
+
+ if (grub_ieee1275_open (alias->path, &ihandle))
{
- /*
- * 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;
- };
+ 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;
- if (grub_ieee1275_open (alias->path, &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*) targets_table[i].addr;
+ /* Iterate over all wwpns in given table */
+ for (k = 0; k < targets_table[i].len; k++)
{
- grub_dprintf ("disk", "failed to open the disk while iterating FCP disk path=%s\n", alias->path);
- return;
+ 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,
+ *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_uint32_t) luns_table[j].addr;
+ for (l = 0; l < luns_table[j].len; l++)
+ {
+ grub_snprintf (&bufptr[pos], 30, ",%" PRIxGRUB_UINT64_T,
+ *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[256];
+ 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[256];
+ char nqn[256];
+ };
+
+ struct nvme_controllers_table_entry_real
+ {
+ grub_uint16_t id;
+ char wwpn[256];
+ char nqn[256];
+ };
+
+ 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) * 256);
+ /* 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];
+ }
- /* 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;
+ grub_ieee1275_close (ihandle);
+ grub_dprintf ("ofdisk","NVMeoF: Found %d discovery controllers\n", discovery_controllers_table.len);
- /* 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)
+ /* 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 ("disk", "failed to get the targets while iterating FCP disk path=%s\n", alias->path);
- grub_ieee1275_close (ihandle);
- return;
+ grub_dprintf ("ofdisk", "failed to open the disk while getting nvme-controllers path=%s\n", buf);
+ continue;
}
- buf = grub_malloc (grub_strlen (alias->path) + 32 + 32);
- if (!buf)
+ 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);
- return;
+ continue;
}
- 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++)
+ /* 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++)
{
- ptr_targets = (grub_uint64_t*) (grub_uint32_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,
- *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);
+ 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);
- /* Iterate over all LUNs */
- for(j = 0; j < args_luns.nentries; j++)
- {
- ptr_luns = (grub_uint64_t*) (grub_uint32_t) luns_table[j].addr;
- for(l = 0; l < luns_table[j].len; l++)
- {
- grub_snprintf (&bufptr[pos], 30, ",%" PRIxGRUB_UINT64_T,
- *ptr_luns++);
- dev_iterate_real (buf, buf);
- }
- }
+ /* 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_ieee1275_close (ihandle);
- grub_free (buf);
- return;
+ 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)
+ {
+ /* Iterate disks */
+ dev_iterate_fcp_disks (alias);
+ /* Iterate NVMeoF */
+ dev_iterate_fcp_nvmeof (alias);
}
else if (grub_strcmp (alias->type, "vscsi") == 0)
{
--
2.31.1
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v3 6/6] ieee1275: ofpath enable NVMeoF logical device translate
2024-06-06 12:37 [PATCH v3 0/6] NVMeoFC support on Grub Avnish Chouhan
` (4 preceding siblings ...)
2024-06-06 12:37 ` [PATCH v3 5/6] ieee1275: add support for NVMeoFC Avnish Chouhan
@ 2024-06-06 12:37 ` Avnish Chouhan
5 siblings, 0 replies; 13+ messages in thread
From: Avnish Chouhan @ 2024-06-06 12:37 UTC (permalink / raw)
To: grub-devel
Cc: daniel.kiper, brking, meghanaprakash, Avnish Chouhan,
Diego Domingos
This patch add 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>
---
grub-core/osdep/linux/ofpath.c | 371 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
include/grub/util/ofpath.h | 28 ++++++++++++++++++++++++++++
2 file changed, 390 insertions(+), 9 deletions(-)
diff --git a/grub-core/osdep/linux/ofpath.c b/grub-core/osdep/linux/ofpath.c
index cc849d9..a2b4eeb 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,92 @@ 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 +469,200 @@ 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");
+ 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);
+ fp = fopen (buf, "r");
+ fscanf (fp, "%s", nvmeof_info->nqn);
+ fclose (fp);
+
+ snprintf (buf, 512, "%s/cntlid", sysfs_path);
+ fp = fopen (buf, "r");
+ fscanf (fp, "%u", &(nvmeof_info->cntlid));
+ fclose (fp);
+
+ snprintf (buf, 512, "%s/address", sysfs_path);
+ fp = fopen (buf, "r");
+ buf2 = malloc (sizeof (char) * 512);
+
+ if (!buf2)
+ {
+ free (nvmeof_info->host_wwpn);
+ free (nvmeof_info->target_wwpn);
+ free (nvmeof_info->nqn);
+ free (buf);
+ return -1;
+ }
+
+ fscanf (fp, "%s", buf2);
+ fclose (fp);
+
+ buf3 = strrchr (buf2, '-') + 1;
+ grub_memcpy (nvmeof_info->host_wwpn, buf3, 256);
+ buf3=strchr (buf2, '-') + 1;
+ buf3=strchr (buf3, '-') + 1;
+ buf3=strchr (buf3, 'x') + 1;
+ grub_memcpy (nvmeof_info->target_wwpn, buf3, 256);
+ buf3 = strchr (nvmeof_info->target_wwpn, ',');
+ *buf3 = '\0';
+ free (buf);
+ free (buf2);
+ return 0;
+}
+
+#define MAX_NVME_NSID_DIGITS 6
+
+static char *
+of_path_get_nvme_controller_name_node (const char* devname)
+{
+ char *controller_node, *end;
+
+ controller_node = strdup (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");
+ fscanf (fp, "%u", &(nsid));
+ fclose (fp);
+
+ free(sysfs_path);
+ free(buf);
+ return nsid;
+}
+
+static char *
+nvme_get_syspath (const char *nvmedev)
+{
+ char *sysfs_path, *controller_node;
+
+ sysfs_path = block_device_get_sysfs_path_and_link (nvmedev);
+ if (strstr (sysfs_path, "nvme-subsystem"))
+ {
+ controller_node = of_path_get_nvme_controller_name_node (nvmedev);
+ strcat (sysfs_path, "/");
+ strcat (sysfs_path, controller_node);
+ sysfs_path = xrealpath (sysfs_path);
+ }
+
+ return sysfs_path;
+}
+
static char *
of_path_of_nvme(const char *sys_devname __attribute__((unused)),
const char *device,
@@ -392,6 +671,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 +692,90 @@ 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;
+ }
+
+ sysfs_path = of_find_fc_host (nvmeof_info->host_wwpn);
+ if (!sysfs_path)
+ {
+ free (nvmedev);
+ 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@") + MAX_NVME_NSID_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) * MAX_NVME_NSID_DIGITS,
+ "/namespace@%x", nsid);
+ }
+ free (nvmeof_info);
+ }
+ else
+ {
+ snprintf (disk, sizeof (disk), "/disk@1");
+ }
}
of_path = find_obppath (sysfs_path);
@@ -430,7 +786,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 +1196,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 b43c523..85172bc 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 */
--
2.31.1
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel
^ permalink raw reply related [flat|nested] 13+ messages in thread