From: Avnish Chouhan <avnish@linux.ibm.com>
To: grub-devel@gnu.org
Cc: daniel.kiper@oracle.com, brking@linux.ibm.com,
meghanaprakash@in.ibm.com, Avnish Chouhan <avnish@linux.ibm.com>,
Diego Domingos <diegodo@br.ibm.com>
Subject: [PATCH v3 6/6] ieee1275: ofpath enable NVMeoF logical device translate
Date: Thu, 6 Jun 2024 18:07:27 +0530 [thread overview]
Message-ID: <20240606123727.38614-7-avnish@linux.ibm.com> (raw)
In-Reply-To: <20240606123727.38614-1-avnish@linux.ibm.com>
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
prev parent reply other threads:[~2024-06-06 12:41 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
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-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
2024-06-06 15:34 ` Vladimir 'phcoder' Serbinenko
2024-06-07 8:34 ` avnish
2024-06-07 9:34 ` Vladimir 'phcoder' Serbinenko
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
2024-06-06 12:37 ` [PATCH v3 4/6] ieee1275: change the logic of ieee1275_get_devargs() Avnish Chouhan
2024-06-06 12:37 ` [PATCH v3 5/6] ieee1275: add support for NVMeoFC Avnish Chouhan
2024-06-06 12:37 ` Avnish Chouhan [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240606123727.38614-7-avnish@linux.ibm.com \
--to=avnish@linux.ibm.com \
--cc=brking@linux.ibm.com \
--cc=daniel.kiper@oracle.com \
--cc=diegodo@br.ibm.com \
--cc=grub-devel@gnu.org \
--cc=meghanaprakash@in.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.