[PATCH 1/1] nvmet: View subsystem connections on nvmeof target

James Smart jsmart2021 at gmail.com
Fri Sep 22 16:08:33 PDT 2023


On 9/20/2023 7:12 AM, Redouane BOUFENGHOUR wrote:
> 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

The "peertraddr" term is odd. On the host side we have "host traddr" for 
the address information for the host side of the connection to the 
controller. I'd prefer to use host traddr over the peer traddr name.

as for the patches:
- I'm not a fan of dstaddr passed between common/transport layers and 
transports "assuming" they know the length via a compile time define. 
I'd prefer being explicit and having the dstaddr buffer length passed 
around as well.

- Are there cases where the address field is more than a single traddr 
value ?  For example, do you need to know host IP address and port # ? 
You can leave it up to the transport to fill in whatever data 
constitutes an "address" which if the max length of the destbuffer is 
known, makes that easier.

-- james



> 
> 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)




More information about the Linux-nvme mailing list