From 311ce0e2ee0ecc14f4507dd95c8fdc2f6b30e4ae Mon Sep 17 00:00:00 2001 From: Ben Walker Date: Fri, 7 Sep 2018 13:41:41 -0700 Subject: [PATCH] nvmf: Add a function to get the listen addr for a qpair The function returns the transport ID describing the listen address on which the connection originated. Change-Id: Ib11cddb8ff2ceb04a5f3ce236ba96c68b7226773 Signed-off-by: Ben Walker Reviewed-on: https://review.gerrithub.io/425023 Chandler-Test-Pool: SPDK Automated Test System Tested-by: SPDK CI Jenkins Reviewed-by: Jim Harris Reviewed-by: Changpeng Liu Reviewed-by: Shuhei Matsumoto --- include/spdk/nvmf.h | 12 +++++++++++ lib/nvmf/nvmf.c | 7 ++++++ lib/nvmf/rdma.c | 51 +++++++++++++++++++++++++++++++++++++------- lib/nvmf/transport.c | 7 ++++++ lib/nvmf/transport.h | 11 +++++++++- 5 files changed, 79 insertions(+), 9 deletions(-) diff --git a/include/spdk/nvmf.h b/include/spdk/nvmf.h index 6187afda2..89ff6b4e5 100644 --- a/include/spdk/nvmf.h +++ b/include/spdk/nvmf.h @@ -218,6 +218,18 @@ int spdk_nvmf_qpair_disconnect(struct spdk_nvmf_qpair *qpair, nvmf_qpair_disconn int spdk_nvmf_qpair_get_peer_trid(struct spdk_nvmf_qpair *qpair, struct spdk_nvme_transport_id *trid); +/** + * Get the associated listener transport ID for this queue pair. + * + * \param qpair The NVMe-oF qpair + * \param trid Output parameter that will contain the transport id. + * + * \return 0 for success. + * \return -EINVAL if the qpair is not connected. + */ +int spdk_nvmf_qpair_get_listen_trid(struct spdk_nvmf_qpair *qpair, + struct spdk_nvme_transport_id *trid); + /** * Create an NVMe-oF subsystem. * diff --git a/lib/nvmf/nvmf.c b/lib/nvmf/nvmf.c index 68a8a0d7d..c54054aae 100644 --- a/lib/nvmf/nvmf.c +++ b/lib/nvmf/nvmf.c @@ -753,6 +753,13 @@ spdk_nvmf_qpair_get_peer_trid(struct spdk_nvmf_qpair *qpair, return spdk_nvmf_transport_qpair_get_peer_trid(qpair, trid); } +int +spdk_nvmf_qpair_get_listen_trid(struct spdk_nvmf_qpair *qpair, + struct spdk_nvme_transport_id *trid) +{ + return spdk_nvmf_transport_qpair_get_listen_trid(qpair, trid); +} + int spdk_nvmf_poll_group_add_transport(struct spdk_nvmf_poll_group *group, struct spdk_nvmf_transport *transport) diff --git a/lib/nvmf/rdma.c b/lib/nvmf/rdma.c index cd4c690ce..cccb0d38f 100644 --- a/lib/nvmf/rdma.c +++ b/lib/nvmf/rdma.c @@ -233,6 +233,7 @@ struct spdk_nvmf_rdma_qpair { struct spdk_nvmf_rdma_poller *poller; struct rdma_cm_id *cm_id; + struct rdma_cm_id *listen_id; /* The maximum number of I/O outstanding on this connection at one time */ uint16_t max_queue_depth; @@ -951,6 +952,7 @@ nvmf_rdma_connect(struct spdk_nvmf_transport *transport, struct rdma_cm_event *e rqpair->max_queue_depth = max_queue_depth; rqpair->max_rw_depth = max_rw_depth; rqpair->cm_id = event->id; + rqpair->listen_id = event->listen_id; rqpair->qpair.transport = transport; rqpair->max_sge = spdk_min(port->device->attr.max_sge, SPDK_NVMF_MAX_SGL_ENTRIES); TAILQ_INIT(&rqpair->incoming_queue); @@ -2694,18 +2696,20 @@ spdk_nvmf_rdma_poll_group_poll(struct spdk_nvmf_transport_poll_group *group) } static int -spdk_nvmf_rdma_qpair_get_peer_trid(struct spdk_nvmf_qpair *qpair, - struct spdk_nvme_transport_id *trid) +spdk_nvmf_rdma_trid_from_cm_id(struct rdma_cm_id *id, + struct spdk_nvme_transport_id *trid, + bool peer) { - struct spdk_nvmf_rdma_qpair *rqpair; struct sockaddr *saddr; uint16_t port; - rqpair = SPDK_CONTAINEROF(qpair, struct spdk_nvmf_rdma_qpair, qpair); - trid->trtype = SPDK_NVME_TRANSPORT_RDMA; - saddr = rdma_get_peer_addr(rqpair->cm_id); + if (peer) { + saddr = rdma_get_peer_addr(id); + } else { + saddr = rdma_get_local_addr(id); + } switch (saddr->sa_family) { case AF_INET: { struct sockaddr_in *saddr_in = (struct sockaddr_in *)saddr; @@ -2713,7 +2717,11 @@ spdk_nvmf_rdma_qpair_get_peer_trid(struct spdk_nvmf_qpair *qpair, trid->adrfam = SPDK_NVMF_ADRFAM_IPV4; inet_ntop(AF_INET, &saddr_in->sin_addr, trid->traddr, sizeof(trid->traddr)); - port = ntohs(rdma_get_dst_port(rqpair->cm_id)); + if (peer) { + port = ntohs(rdma_get_dst_port(id)); + } else { + port = ntohs(rdma_get_src_port(id)); + } snprintf(trid->trsvcid, sizeof(trid->trsvcid), "%u", port); break; } @@ -2722,7 +2730,11 @@ spdk_nvmf_rdma_qpair_get_peer_trid(struct spdk_nvmf_qpair *qpair, trid->adrfam = SPDK_NVMF_ADRFAM_IPV6; inet_ntop(AF_INET6, &saddr_in->sin6_addr, trid->traddr, sizeof(trid->traddr)); - port = ntohs(rdma_get_dst_port(rqpair->cm_id)); + if (peer) { + port = ntohs(rdma_get_dst_port(id)); + } else { + port = ntohs(rdma_get_src_port(id)); + } snprintf(trid->trsvcid, sizeof(trid->trsvcid), "%u", port); break; } @@ -2734,6 +2746,28 @@ spdk_nvmf_rdma_qpair_get_peer_trid(struct spdk_nvmf_qpair *qpair, return 0; } +static int +spdk_nvmf_rdma_qpair_get_peer_trid(struct spdk_nvmf_qpair *qpair, + struct spdk_nvme_transport_id *trid) +{ + struct spdk_nvmf_rdma_qpair *rqpair; + + rqpair = SPDK_CONTAINEROF(qpair, struct spdk_nvmf_rdma_qpair, qpair); + + return spdk_nvmf_rdma_trid_from_cm_id(rqpair->cm_id, trid, true); +} + +static int +spdk_nvmf_rdma_qpair_get_listen_trid(struct spdk_nvmf_qpair *qpair, + struct spdk_nvme_transport_id *trid) +{ + struct spdk_nvmf_rdma_qpair *rqpair; + + rqpair = SPDK_CONTAINEROF(qpair, struct spdk_nvmf_rdma_qpair, qpair); + + return spdk_nvmf_rdma_trid_from_cm_id(rqpair->listen_id, trid, false); +} + const struct spdk_nvmf_transport_ops spdk_nvmf_transport_rdma = { .type = SPDK_NVME_TRANSPORT_RDMA, .create = spdk_nvmf_rdma_create, @@ -2756,6 +2790,7 @@ const struct spdk_nvmf_transport_ops spdk_nvmf_transport_rdma = { .qpair_fini = spdk_nvmf_rdma_close_qpair, .qpair_is_idle = spdk_nvmf_rdma_qpair_is_idle, .qpair_get_peer_trid = spdk_nvmf_rdma_qpair_get_peer_trid, + .qpair_get_listen_trid = spdk_nvmf_rdma_qpair_get_listen_trid, }; diff --git a/lib/nvmf/transport.c b/lib/nvmf/transport.c index b0ca0e817..26767ddad 100644 --- a/lib/nvmf/transport.c +++ b/lib/nvmf/transport.c @@ -216,3 +216,10 @@ spdk_nvmf_transport_qpair_get_peer_trid(struct spdk_nvmf_qpair *qpair, { return qpair->transport->ops->qpair_get_peer_trid(qpair, trid); } + +int +spdk_nvmf_transport_qpair_get_listen_trid(struct spdk_nvmf_qpair *qpair, + struct spdk_nvme_transport_id *trid) +{ + return qpair->transport->ops->qpair_get_listen_trid(qpair, trid); +} diff --git a/lib/nvmf/transport.h b/lib/nvmf/transport.h index ac5b40467..254a7f05d 100644 --- a/lib/nvmf/transport.h +++ b/lib/nvmf/transport.h @@ -132,10 +132,16 @@ struct spdk_nvmf_transport_ops { bool (*qpair_is_idle)(struct spdk_nvmf_qpair *qpair); /* - * Get the remote transport ID for the queue pair + * Get the peer transport ID for the queue pair. */ int (*qpair_get_peer_trid)(struct spdk_nvmf_qpair *qpair, struct spdk_nvme_transport_id *trid); + + /* + * Get the listener transport ID that accepted this qpair originally. + */ + int (*qpair_get_listen_trid)(struct spdk_nvmf_qpair *qpair, + struct spdk_nvme_transport_id *trid); }; struct spdk_nvmf_transport *spdk_nvmf_transport_create(struct spdk_nvmf_tgt *tgt, @@ -177,6 +183,9 @@ bool spdk_nvmf_transport_qpair_is_idle(struct spdk_nvmf_qpair *qpair); int spdk_nvmf_transport_qpair_get_peer_trid(struct spdk_nvmf_qpair *qpair, struct spdk_nvme_transport_id *trid); +int spdk_nvmf_transport_qpair_get_listen_trid(struct spdk_nvmf_qpair *qpair, + struct spdk_nvme_transport_id *trid); + extern const struct spdk_nvmf_transport_ops spdk_nvmf_transport_rdma; #endif /* SPDK_NVMF_TRANSPORT_H */