]> www.infradead.org Git - users/sagi/libnvme.git/commitdiff
tree: Add PCI physical slot number for controller
authorUmer Saleem <usaleem@ixsystems.com>
Mon, 12 Jun 2023 14:45:49 +0000 (19:45 +0500)
committerDaniel Wagner <wagi@monom.org>
Wed, 14 Jun 2023 12:40:45 +0000 (14:40 +0200)
This commit introduces a physical slot field for controller, that
contains the PCI physcial slot number for controller device.

In case, there are multiple NVME drives present on the platform,
it's hard to identify which NVME drive is present in which slot.
The slot number is usually helpful in determining the location.
It is cross reference-able from lspci, but it would be nice to
have a direct option.

Signed-off-by: Umer Saleem <usaleem@ixsystems.com>
src/libnvme.map
src/nvme/private.h
src/nvme/tree.c
src/nvme/tree.h

index 9d6e64664585614f1c71f7da10ea63bab4882d5d..82387d44d711407585efd17bc5eae9612f65a629 100644 (file)
@@ -2,6 +2,7 @@
 
 LIBNVME_1_5 {
        global:
+               nvme_ctrl_get_phy_slot;
                nvme_ipaddrs_eq;
                nvme_nbft_free;
                nvme_nbft_read;
index 10f55f092daa31591ed91fc040a8501f2c40e17f..809b3bb744395ffdda9ca7673891ee728c8e8cff 100644 (file)
@@ -84,6 +84,7 @@ struct nvme_ctrl {
        char *dhchap_ctrl_key;
        char *cntrltype;
        char *dctype;
+       char *phy_slot;
        bool discovery_ctrl;
        bool unique_discovery_ctrl;
        bool discovered;
index 0ac06a4a523e03c2b7ccb9116d95dbb3c9b698a9..4ba39832fbc39329fe3cc13333d7773697816a12 100644 (file)
@@ -34,6 +34,8 @@
 #include "log.h"
 #include "private.h"
 
+const char *nvme_slots_sysfs_dir = "/sys/bus/pci/slots";
+
 static struct nvme_host *default_host;
 
 static void __nvme_free_host(nvme_host_t h);
@@ -822,6 +824,11 @@ const char *nvme_ctrl_get_address(nvme_ctrl_t c)
        return c->address ? c->address : "";
 }
 
+const char *nvme_ctrl_get_phy_slot(nvme_ctrl_t c)
+{
+       return c->phy_slot ? c->phy_slot : "";
+}
+
 const char *nvme_ctrl_get_firmware(nvme_ctrl_t c)
 {
        return c->firmware;
@@ -1009,6 +1016,7 @@ void nvme_deconfigure_ctrl(nvme_ctrl_t c)
        FREE_CTRL_ATTR(c->address);
        FREE_CTRL_ATTR(c->dctype);
        FREE_CTRL_ATTR(c->cntrltype);
+       FREE_CTRL_ATTR(c->phy_slot);
 }
 
 int nvme_disconnect_ctrl(nvme_ctrl_t c)
@@ -1256,6 +1264,50 @@ static char *nvme_ctrl_lookup_subsystem_name(nvme_root_t r,
        return subsys_name;
 }
 
+static char *nvme_ctrl_lookup_phy_slot(nvme_root_t r, const char *address)
+{
+       char *target_addr;
+       char *addr;
+       char *path;
+       int found = 0;
+       int ret;
+       DIR *slots_dir;
+       struct dirent *entry;
+
+       slots_dir = opendir(nvme_slots_sysfs_dir);
+       if (!slots_dir) {
+               nvme_msg(r, LOG_WARNING, "failed to open slots dir %s\n",
+               nvme_slots_sysfs_dir);
+               return NULL;
+       }
+
+       target_addr = strndup(address, 10);
+       while (!(entry = readdir(slots_dir))) {
+               if (entry->d_type == DT_DIR &&
+                   strncmp(entry->d_name, ".", 1) != 0 &&
+                   strncmp(entry->d_name, "..", 2) != 0) {
+                       ret = asprintf(&path, "/sys/bus/pci/slots/%s", entry->d_name);
+                       if (ret < 0) {
+                               errno = ENOMEM;
+                               return NULL;
+                       }
+                       addr = nvme_get_attr(path, "address");
+                       if (strcmp(addr, target_addr) == 0) {
+                               found = 1;
+                               free(path);
+                               free(addr);
+                               break;
+                       }
+                       free(path);
+                       free(addr);
+               }
+       }
+       free(target_addr);
+       if (found)
+               return strdup(entry->d_name);
+       return NULL;
+}
+
 static int nvme_configure_ctrl(nvme_root_t r, nvme_ctrl_t c, const char *path,
                               const char *name)
 {
@@ -1297,6 +1349,7 @@ static int nvme_configure_ctrl(nvme_root_t r, nvme_ctrl_t c, const char *path,
        }
        c->cntrltype = nvme_get_ctrl_attr(c, "cntrltype");
        c->dctype = nvme_get_ctrl_attr(c, "dctype");
+       c->phy_slot = nvme_ctrl_lookup_phy_slot(r, c->address);
 
        errno = 0; /* cleanup after nvme_get_ctrl_attr() */
        return 0;
index 5e05ba692269f612a6e0ec9378186bd1d4b6d1bc..bcf3636f3c333f5da507fdbe0a4f8b9282f251c6 100644 (file)
@@ -801,6 +801,15 @@ const char *nvme_ctrl_get_sysfs_dir(nvme_ctrl_t c);
  */
 const char *nvme_ctrl_get_address(nvme_ctrl_t c);
 
+/**
+ * nvme_ctrl_get_phy_slot() - PCI physical slot number of a controller
+ * @c: Controller instance
+ *
+ * Return: PCI physical slot number of @c or empty string if slot
+ * number is not present.
+ */
+const char *nvme_ctrl_get_phy_slot(nvme_ctrl_t c);
+
 /**
  * nvme_ctrl_get_firmware() - Firmware string of a controller
  * @c: Controller instance