[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