[PATCH 1/1] nvmet: View subsystem connections on nvmeof target
Redouane BOUFENGHOUR
redouane.boufenghour at shadow.tech
Wed Sep 27 00:10:49 PDT 2023
Hello,
Thank you for your answers. If I transfer my display code to the
debugfs, is it ok if I create a tree
nvmet/subsystem/nameofsubsystem/crtl/NumberOfcontroler/host_traddr and
nvmet/subsystem/nameofsubsystem/crtl/NumberOfcontroler/host_nqn?
Concerning the traddr value, for me this information is directly
retrieved from the queue_tcp and rdma so it will only be ipv6 or ipv4
but in any case I will add a security on the destbuffer.
I'll get back to you with the corrected patch.
Redouane,
Le sam. 23 sept. 2023 à 01:08, James Smart <jsmart2021 at gmail.com> a écrit :
>
> 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)
>
--
Redouane Boufenghour
Storage Engineer
Join us at shadow.tech
More information about the Linux-nvme
mailing list