From 42ac4535963556610a5bba8d1277c5a398a6ed5a Mon Sep 17 00:00:00 2001 From: Umer Saleem Date: Mon, 12 Jun 2023 19:45:49 +0500 Subject: [PATCH] tree: Add PCI physical slot number for controller 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 --- src/libnvme.map | 1 + src/nvme/private.h | 1 + src/nvme/tree.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++ src/nvme/tree.h | 9 ++++++++ 4 files changed, 64 insertions(+) diff --git a/src/libnvme.map b/src/libnvme.map index 9d6e6466..82387d44 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -2,6 +2,7 @@ LIBNVME_1_5 { global: + nvme_ctrl_get_phy_slot; nvme_ipaddrs_eq; nvme_nbft_free; nvme_nbft_read; diff --git a/src/nvme/private.h b/src/nvme/private.h index 10f55f09..809b3bb7 100644 --- a/src/nvme/private.h +++ b/src/nvme/private.h @@ -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; diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 0ac06a4a..4ba39832 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -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; diff --git a/src/nvme/tree.h b/src/nvme/tree.h index 5e05ba69..bcf3636f 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -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