[PATCH 1/1] nvmet: View subsystem connections on nvmeof target
Redouane BOUFENGHOUR
redouane.boufenghour at shadow.tech
Wed Sep 20 07:12:06 PDT 2023
We add a new entry in the tcp and rdma factories to retrieve the peer
address of a ctrl.
The functions nvmet_rdma_disc_peer_addr and nvmet_tcp_disc_peer_addr return
a snprintf of size NVMF_TRADDR_SIZE with the address connected to the ctlrs
which is then displayed in a subsys attribute attr_connected_ctrls on RO
Co-developed-by: Valentin BRICE <valentin.brice at shadow.tech>
Signed-off-by: Valentin BRICE <valentin.brice at shadow.tech>
Co-developed-by: Antoine DAMHET <antoine.damhet at shadow.tech>
Signed-off-by: Antoine DAMHET <antoine.damhet at shadow.tech>
Co-developed-by: Redouane BOUFENGHOUR <redouane.boufenghour at shadow.tech>
Signed-off-by: Redouane BOUFENGHOUR <redouane.boufenghour at shadow.tech>
---
drivers/nvme/target/configfs.c | 30 ++++++++++++++++++++++++++++++
drivers/nvme/target/core.c | 7 +++++++
drivers/nvme/target/nvmet.h | 2 ++
drivers/nvme/target/rdma.c | 10 ++++++++++
drivers/nvme/target/tcp.c | 13 +++++++++++++
5 files changed, 62 insertions(+)
diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c
index 907143870da5..6cbbe71244dd 100644
--- a/drivers/nvme/target/configfs.c
+++ b/drivers/nvme/target/configfs.c
@@ -1426,6 +1426,35 @@ static ssize_t nvmet_subsys_attr_qid_max_store(struct config_item *item,
}
CONFIGFS_ATTR(nvmet_subsys_, attr_qid_max);
+static ssize_t nvmet_subsys_attr_connected_ctrls_show(
+ struct config_item *item, char *page)
+{
+ ssize_t len, ret;
+ int peer;
+ char dstaddr[NVMF_TRADDR_SIZE];
+ struct nvmet_subsys *subsys;
+ struct nvmet_ctrl *ctrl;
+
+ subsys = to_subsys(item);
+ len = 0;
+
+ list_for_each_entry(ctrl, &subsys->ctrls, subsys_entry) {
+ peer = get_peer_traddr(ctrl, ctrl->sqs[0], dstaddr);
+ if (peer < 0)
+ snprintf(dstaddr, NVMF_TRADDR_SIZE, "unknown");
+ ret = snprintf(page + len, PAGE_SIZE - len,
+ "hostnqn: %s; peer_addr: %s\n",
+ ctrl->hostnqn, dstaddr);
+ if (ret >= PAGE_SIZE - len) {
+ sprintf(page + PAGE_SIZE - 14, "\n[truncated]");
+ return PAGE_SIZE;
+ }
+ len += ret;
+ }
+ return len;
+}
+CONFIGFS_ATTR_RO(nvmet_subsys_, attr_connected_ctrls);
+
static struct configfs_attribute *nvmet_subsys_attrs[] = {
&nvmet_subsys_attr_attr_allow_any_host,
&nvmet_subsys_attr_attr_version,
@@ -1436,6 +1465,7 @@ static struct configfs_attribute *nvmet_subsys_attrs[] = {
&nvmet_subsys_attr_attr_qid_max,
&nvmet_subsys_attr_attr_ieee_oui,
&nvmet_subsys_attr_attr_firmware,
+ &nvmet_subsys_attr_attr_connected_ctrls,
#ifdef CONFIG_BLK_DEV_INTEGRITY
&nvmet_subsys_attr_attr_pi_enable,
#endif
diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
index 3935165048e7..ba5997a14675 100644
--- a/drivers/nvme/target/core.c
+++ b/drivers/nvme/target/core.c
@@ -1629,6 +1629,13 @@ static void nvmet_subsys_free(struct kref *ref)
kfree(subsys);
}
+int get_peer_traddr(struct nvmet_ctrl *ctrl, struct nvmet_sq *sq, char *dstaddr)
+{
+ if (ctrl->ops->disc_peertraddr == NULL)
+ return -EOPNOTSUPP;
+ return ctrl->ops->disc_peertraddr(sq, ctrl->port, dstaddr);
+}
+
void nvmet_subsys_del_ctrls(struct nvmet_subsys *subsys)
{
struct nvmet_ctrl *ctrl;
diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h
index 8cfd60f3b564..60ea2391a957 100644
--- a/drivers/nvme/target/nvmet.h
+++ b/drivers/nvme/target/nvmet.h
@@ -341,6 +341,8 @@ struct nvmet_fabrics_ops {
void (*discovery_chg)(struct nvmet_port *port);
u8 (*get_mdts)(const struct nvmet_ctrl *ctrl);
u16 (*get_max_queue_size)(const struct nvmet_ctrl *ctrl);
+ int (*disc_peertraddr)(struct nvmet_sq *nvme_sq,
+ struct nvmet_port *port, char *dstaddr);
};
#define NVMET_MAX_INLINE_BIOVEC 8
diff --git a/drivers/nvme/target/rdma.c b/drivers/nvme/target/rdma.c
index 4597bca43a6d..395554a77fc1 100644
--- a/drivers/nvme/target/rdma.c
+++ b/drivers/nvme/target/rdma.c
@@ -1992,6 +1992,15 @@ static void nvmet_rdma_disc_port_addr(struct nvmet_req *req,
memcpy(traddr, nport->disc_addr.traddr, NVMF_TRADDR_SIZE);
}
}
+int nvmet_rdma_disc_peer_addr(struct nvmet_sq *nvme_sq,
+ struct nvmet_port *nport, char *dstaddr)
+{
+ struct nvmet_rdma_queue *queue =
+ container_of(nvme_sq, struct nvmet_rdma_queue, nvme_sq);
+
+ snprintf(dstaddr, NVMF_TRADDR_SIZE, "%pISc",
+ (struct sockaddr *)&queue->cm_id->route.addr.dst_addr);
+}
static u8 nvmet_rdma_get_mdts(const struct nvmet_ctrl *ctrl)
{
@@ -2015,6 +2024,7 @@ static const struct nvmet_fabrics_ops nvmet_rdma_ops = {
.queue_response = nvmet_rdma_queue_response,
.delete_ctrl = nvmet_rdma_delete_ctrl,
.disc_traddr = nvmet_rdma_disc_port_addr,
+ .disc_peertraddr = nvmet_rdma_disc_peer_addr,
.get_mdts = nvmet_rdma_get_mdts,
.get_max_queue_size = nvmet_rdma_get_max_queue_size,
};
diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c
index 868aa4de2e4c..ae454c176fac 100644
--- a/drivers/nvme/target/tcp.c
+++ b/drivers/nvme/target/tcp.c
@@ -1871,6 +1871,18 @@ static void nvmet_tcp_disc_port_addr(struct nvmet_req *req,
}
}
+int nvmet_tcp_disc_peer_addr(struct nvmet_sq *sq,
+ struct nvmet_port *nport, char *dstaddr)
+{
+ struct nvmet_tcp_queue *queue =
+ container_of(sq, struct nvmet_tcp_queue, nvme_sq);
+
+ if (queue->sockaddr_peer.ss_family == AF_UNSPEC)
+ return -EINVAL;
+ return snprintf(dstaddr, NVMF_TRADDR_SIZE, "%pISc",
+ (struct sockaddr *)&queue->sockaddr_peer);
+}
+
static const struct nvmet_fabrics_ops nvmet_tcp_ops = {
.owner = THIS_MODULE,
.type = NVMF_TRTYPE_TCP,
@@ -1881,6 +1893,7 @@ static const struct nvmet_fabrics_ops nvmet_tcp_ops = {
.delete_ctrl = nvmet_tcp_delete_ctrl,
.install_queue = nvmet_tcp_install_queue,
.disc_traddr = nvmet_tcp_disc_port_addr,
+ .disc_peertraddr = nvmet_tcp_disc_peer_addr,
};
static int __init nvmet_tcp_init(void)
--
2.39.2 (Apple Git-143)
More information about the Linux-nvme
mailing list