From 31d033f9448e5b0d13501e7ad2cf0eaaf9ca54ad Mon Sep 17 00:00:00 2001 From: Ben Walker Date: Mon, 24 Jul 2017 16:30:07 -0700 Subject: [PATCH] nvmf: Transports are no longer global Create one transport per nvmf target. Today, there is just one global nvmf target, but this paves the way for multiple. Change-Id: Iaa1f8c5e7b3c1e87621ef2a636c68c2dd8fd929e Signed-off-by: Ben Walker Reviewed-on: https://review.gerrithub.io/371748 Reviewed-by: Daniel Verkamp Tested-by: SPDK Automated Test System --- app/nvmf_tgt/nvmf_tgt.c | 2 +- include/spdk/nvmf.h | 2 +- lib/nvmf/ctrlr.c | 18 ++--- lib/nvmf/ctrlr.h | 4 +- lib/nvmf/ctrlr_discovery.c | 6 +- lib/nvmf/nvmf.c | 56 +++++++++----- lib/nvmf/nvmf_internal.h | 4 + lib/nvmf/rdma.c | 64 +++++++++------ lib/nvmf/request.c | 2 +- lib/nvmf/subsystem.c | 17 ++-- lib/nvmf/transport.c | 77 ++++++++----------- lib/nvmf/transport.h | 38 +++++---- .../ctrlr_discovery.c/ctrlr_discovery_ut.c | 29 +++++-- test/unit/lib/nvmf/subsystem.c/subsystem_ut.c | 29 +++++-- 14 files changed, 212 insertions(+), 136 deletions(-) diff --git a/app/nvmf_tgt/nvmf_tgt.c b/app/nvmf_tgt/nvmf_tgt.c index 1a2ce6e99..c4dfb1a5f 100644 --- a/app/nvmf_tgt/nvmf_tgt.c +++ b/app/nvmf_tgt/nvmf_tgt.c @@ -263,7 +263,7 @@ nvmf_tgt_shutdown_subsystem_by_nqn(const char *nqn) static void acceptor_poll(void *arg) { - spdk_nvmf_acceptor_poll(); + spdk_nvmf_tgt_poll(); } static void diff --git a/include/spdk/nvmf.h b/include/spdk/nvmf.h index b9ee9c98f..952af17e8 100644 --- a/include/spdk/nvmf.h +++ b/include/spdk/nvmf.h @@ -167,7 +167,7 @@ int spdk_nvmf_subsystem_set_sn(struct spdk_nvmf_subsystem *subsystem, const char const char *spdk_nvmf_subsystem_get_nqn(struct spdk_nvmf_subsystem *subsystem); enum spdk_nvmf_subtype spdk_nvmf_subsystem_get_type(struct spdk_nvmf_subsystem *subsystem); -void spdk_nvmf_acceptor_poll(void); +void spdk_nvmf_tgt_poll(void); void spdk_nvmf_handle_connect(struct spdk_nvmf_request *req); diff --git a/lib/nvmf/ctrlr.c b/lib/nvmf/ctrlr.c index 403bbf094..efb23442d 100644 --- a/lib/nvmf/ctrlr.c +++ b/lib/nvmf/ctrlr.c @@ -163,7 +163,7 @@ nvmf_init_nvme_ctrlr_properties(struct spdk_nvmf_ctrlr *ctrlr) static void ctrlr_destruct(struct spdk_nvmf_ctrlr *ctrlr) { TAILQ_REMOVE(&ctrlr->subsys->ctrlrs, ctrlr, link); - ctrlr->transport->ctrlr_fini(ctrlr); + ctrlr->transport->ops->ctrlr_fini(ctrlr); } void @@ -174,7 +174,7 @@ spdk_nvmf_ctrlr_destruct(struct spdk_nvmf_ctrlr *ctrlr) TAILQ_REMOVE(&ctrlr->qpairs, qpair, link); ctrlr->num_qpairs--; - qpair->transport->qpair_fini(qpair); + qpair->transport->ops->qpair_fini(qpair); } ctrlr_destruct(ctrlr); @@ -288,7 +288,7 @@ spdk_nvmf_ctrlr_connect(struct spdk_nvmf_qpair *qpair, } /* Establish a new ctrlr */ - ctrlr = qpair->transport->ctrlr_init(); + ctrlr = qpair->transport->ops->ctrlr_init(qpair->transport); if (ctrlr == NULL) { SPDK_ERRLOG("Memory allocation failure\n"); rsp->status.sc = SPDK_NVME_SC_INTERNAL_DEVICE_ERROR; @@ -313,9 +313,9 @@ spdk_nvmf_ctrlr_connect(struct spdk_nvmf_qpair *qpair, memcpy(ctrlr->hostid, data->hostid, sizeof(ctrlr->hostid)); - if (qpair->transport->ctrlr_add_qpair(ctrlr, qpair)) { + if (qpair->transport->ops->ctrlr_add_qpair(ctrlr, qpair)) { rsp->status.sc = SPDK_NVME_SC_INTERNAL_DEVICE_ERROR; - qpair->transport->ctrlr_fini(ctrlr); + qpair->transport->ops->ctrlr_fini(ctrlr); free(ctrlr); return; } @@ -374,7 +374,7 @@ spdk_nvmf_ctrlr_connect(struct spdk_nvmf_qpair *qpair, return; } - if (qpair->transport->ctrlr_add_qpair(ctrlr, qpair)) { + if (qpair->transport->ops->ctrlr_add_qpair(ctrlr, qpair)) { INVALID_CONNECT_CMD(qid); return; } @@ -399,8 +399,8 @@ spdk_nvmf_ctrlr_disconnect(struct spdk_nvmf_qpair *qpair) ctrlr->num_qpairs--; TAILQ_REMOVE(&ctrlr->qpairs, qpair, link); - qpair->transport->ctrlr_remove_qpair(ctrlr, qpair); - qpair->transport->qpair_fini(qpair); + qpair->transport->ops->ctrlr_remove_qpair(ctrlr, qpair); + qpair->transport->ops->qpair_fini(qpair); if (ctrlr->num_qpairs == 0) { ctrlr_destruct(ctrlr); @@ -654,7 +654,7 @@ spdk_nvmf_ctrlr_poll(struct spdk_nvmf_ctrlr *ctrlr) } TAILQ_FOREACH_SAFE(qpair, &ctrlr->qpairs, link, tmp) { - if (qpair->transport->qpair_poll(qpair) < 0) { + if (qpair->transport->ops->qpair_poll(qpair) < 0) { SPDK_ERRLOG("Transport poll failed for qpair %p; closing connection\n", qpair); spdk_nvmf_ctrlr_disconnect(qpair); } diff --git a/lib/nvmf/ctrlr.h b/lib/nvmf/ctrlr.h index b77807f28..8c3e1ad7a 100644 --- a/lib/nvmf/ctrlr.h +++ b/lib/nvmf/ctrlr.h @@ -51,7 +51,7 @@ enum spdk_nvmf_qpair_type { }; struct spdk_nvmf_qpair { - const struct spdk_nvmf_transport *transport; + struct spdk_nvmf_transport *transport; struct spdk_nvmf_ctrlr *ctrlr; enum spdk_nvmf_qpair_type type; @@ -92,7 +92,7 @@ struct spdk_nvmf_ctrlr { } async_event_config; struct spdk_nvmf_request *aer_req; uint8_t hostid[16]; - const struct spdk_nvmf_transport *transport; + struct spdk_nvmf_transport *transport; TAILQ_ENTRY(spdk_nvmf_ctrlr) link; }; diff --git a/lib/nvmf/ctrlr_discovery.c b/lib/nvmf/ctrlr_discovery.c index a64284976..e0eda9fb3 100644 --- a/lib/nvmf/ctrlr_discovery.c +++ b/lib/nvmf/ctrlr_discovery.c @@ -58,7 +58,7 @@ nvmf_update_discovery_log(void) struct spdk_nvmf_subsystem_allowed_listener *allowed_listener; struct spdk_nvmf_listen_addr *listen_addr; struct spdk_nvmf_discovery_log_page_entry *entry; - const struct spdk_nvmf_transport *transport; + struct spdk_nvmf_transport *transport; struct spdk_nvmf_discovery_log_page *disc_log; size_t cur_size; @@ -99,10 +99,10 @@ nvmf_update_discovery_log(void) entry->subtype = subsystem->subtype; snprintf(entry->subnqn, sizeof(entry->subnqn), "%s", subsystem->subnqn); - transport = spdk_nvmf_transport_get(listen_addr->trid.trtype); + transport = spdk_nvmf_tgt_get_transport(&g_nvmf_tgt, listen_addr->trid.trtype); assert(transport != NULL); - transport->listen_addr_discover(listen_addr, entry); + transport->ops->listen_addr_discover(transport, listen_addr, entry); numrec++; } diff --git a/lib/nvmf/nvmf.c b/lib/nvmf/nvmf.c index 5d7e23a8f..3ff6775e7 100644 --- a/lib/nvmf/nvmf.c +++ b/lib/nvmf/nvmf.c @@ -52,8 +52,6 @@ int spdk_nvmf_tgt_init(uint16_t max_queue_depth, uint16_t max_qpairs_per_ctrlr, uint32_t in_capsule_data_size, uint32_t max_io_size) { - int rc; - g_nvmf_tgt.max_qpairs_per_ctrlr = max_qpairs_per_ctrlr; g_nvmf_tgt.max_queue_depth = max_queue_depth; g_nvmf_tgt.in_capsule_data_size = in_capsule_data_size; @@ -64,18 +62,13 @@ spdk_nvmf_tgt_init(uint16_t max_queue_depth, uint16_t max_qpairs_per_ctrlr, g_nvmf_tgt.current_subsystem_id = 0; TAILQ_INIT(&g_nvmf_tgt.subsystems); TAILQ_INIT(&g_nvmf_tgt.listen_addrs); + TAILQ_INIT(&g_nvmf_tgt.transports); SPDK_TRACELOG(SPDK_TRACE_NVMF, "Max Queue Pairs Per Controller: %d\n", max_qpairs_per_ctrlr); SPDK_TRACELOG(SPDK_TRACE_NVMF, "Max Queue Depth: %d\n", max_queue_depth); SPDK_TRACELOG(SPDK_TRACE_NVMF, "Max In Capsule Data: %d bytes\n", in_capsule_data_size); SPDK_TRACELOG(SPDK_TRACE_NVMF, "Max I/O Size: %d bytes\n", max_io_size); - rc = spdk_nvmf_transport_init(); - if (rc < 0) { - SPDK_ERRLOG("Transport initialization failed\n"); - return -1; - } - return 0; } @@ -83,6 +76,7 @@ int spdk_nvmf_tgt_fini(void) { struct spdk_nvmf_listen_addr *listen_addr, *listen_addr_tmp; + struct spdk_nvmf_transport *transport, *transport_tmp; TAILQ_FOREACH_SAFE(listen_addr, &g_nvmf_tgt.listen_addrs, link, listen_addr_tmp) { TAILQ_REMOVE(&g_nvmf_tgt.listen_addrs, listen_addr, link); @@ -91,21 +85,32 @@ spdk_nvmf_tgt_fini(void) spdk_nvmf_listen_addr_destroy(listen_addr); } - spdk_nvmf_transport_fini(); + TAILQ_FOREACH_SAFE(transport, &g_nvmf_tgt.transports, link, transport_tmp) { + TAILQ_REMOVE(&g_nvmf_tgt.transports, transport, link); + spdk_nvmf_transport_destroy(transport); + } return 0; } +struct spdk_nvmf_transport * +spdk_nvmf_tgt_get_transport(struct spdk_nvmf_tgt *tgt, enum spdk_nvme_transport_type type) +{ + struct spdk_nvmf_transport *transport; + + TAILQ_FOREACH(transport, &tgt->transports, link) { + if (transport->ops->type == type) { + return transport; + } + } + + return NULL; +} + struct spdk_nvmf_listen_addr * spdk_nvmf_listen_addr_create(struct spdk_nvme_transport_id *trid) { struct spdk_nvmf_listen_addr *listen_addr; - const struct spdk_nvmf_transport *transport; - - transport = spdk_nvmf_transport_get(trid->trtype); - if (!transport) { - return NULL; - } listen_addr = calloc(1, sizeof(*listen_addr)); if (!listen_addr) { @@ -120,15 +125,28 @@ spdk_nvmf_listen_addr_create(struct spdk_nvme_transport_id *trid) void spdk_nvmf_listen_addr_destroy(struct spdk_nvmf_listen_addr *addr) { - const struct spdk_nvmf_transport *transport; + struct spdk_nvmf_transport *transport; - transport = spdk_nvmf_transport_get(addr->trid.trtype); - assert(transport != NULL); - transport->listen_addr_remove(addr); + transport = spdk_nvmf_tgt_get_transport(&g_nvmf_tgt, addr->trid.trtype); + if (!transport) { + SPDK_ERRLOG("Attempted to destroy listener without a valid transport\n"); + return; + } + transport->ops->listen_addr_remove(transport, addr); free(addr); } +void +spdk_nvmf_tgt_poll(void) +{ + struct spdk_nvmf_transport *transport, *tmp; + + TAILQ_FOREACH_SAFE(transport, &g_nvmf_tgt.transports, link, tmp) { + transport->ops->acceptor_poll(transport); + } +} + SPDK_TRACE_REGISTER_FN(nvmf_trace) { spdk_trace_register_object(OBJECT_NVMF_IO, 'r'); diff --git a/lib/nvmf/nvmf_internal.h b/lib/nvmf/nvmf_internal.h index 93fdc1278..01c92357a 100644 --- a/lib/nvmf/nvmf_internal.h +++ b/lib/nvmf/nvmf_internal.h @@ -87,6 +87,7 @@ struct spdk_nvmf_tgt { size_t discovery_log_page_size; TAILQ_HEAD(, spdk_nvmf_listen_addr) listen_addrs; uint32_t current_subsystem_id; + TAILQ_HEAD(, spdk_nvmf_transport) transports; }; extern struct spdk_nvmf_tgt g_nvmf_tgt; @@ -94,6 +95,9 @@ extern struct spdk_nvmf_tgt g_nvmf_tgt; struct spdk_nvmf_listen_addr *spdk_nvmf_listen_addr_create(struct spdk_nvme_transport_id *trid); void spdk_nvmf_listen_addr_destroy(struct spdk_nvmf_listen_addr *addr); +struct spdk_nvmf_transport *spdk_nvmf_tgt_get_transport(struct spdk_nvmf_tgt *tgt, + enum spdk_nvme_transport_type); + #define OBJECT_NVMF_IO 0x30 #define TRACE_GROUP_NVMF 0x3 diff --git a/lib/nvmf/rdma.c b/lib/nvmf/rdma.c index 80f048b47..82f5b983b 100644 --- a/lib/nvmf/rdma.c +++ b/lib/nvmf/rdma.c @@ -258,7 +258,8 @@ spdk_nvmf_rdma_qpair_destroy(struct spdk_nvmf_rdma_qpair *rdma_qpair) } static struct spdk_nvmf_rdma_qpair * -spdk_nvmf_rdma_qpair_create(struct rdma_cm_id *id, struct ibv_comp_channel *channel, +spdk_nvmf_rdma_qpair_create(struct spdk_nvmf_transport *transport, + struct rdma_cm_id *id, struct ibv_comp_channel *channel, uint16_t max_queue_depth, uint16_t max_rw_depth, uint32_t subsystem_id) { struct spdk_nvmf_rdma_qpair *rdma_qpair; @@ -310,7 +311,7 @@ spdk_nvmf_rdma_qpair_create(struct rdma_cm_id *id, struct ibv_comp_channel *chan } qpair = &rdma_qpair->qpair; - qpair->transport = &spdk_nvmf_transport_rdma; + qpair->transport = transport; id->context = qpair; rdma_qpair->cm_id = id; @@ -534,7 +535,7 @@ spdk_nvmf_rdma_request_transfer_data(struct spdk_nvmf_request *req) } static int -nvmf_rdma_connect(struct rdma_cm_event *event) +nvmf_rdma_connect(struct spdk_nvmf_transport *transport, struct rdma_cm_event *event) { struct spdk_nvmf_rdma_qpair *rdma_qpair = NULL; struct spdk_nvmf_rdma_listen_addr *addr; @@ -613,7 +614,7 @@ nvmf_rdma_connect(struct rdma_cm_event *event) max_queue_depth, max_rw_depth); /* Init the NVMf rdma transport connection */ - rdma_qpair = spdk_nvmf_rdma_qpair_create(event->id, addr->comp_channel, max_queue_depth, + rdma_qpair = spdk_nvmf_rdma_qpair_create(transport, event->id, addr->comp_channel, max_queue_depth, max_rw_depth, subsystem_id); if (rdma_qpair == NULL) { SPDK_ERRLOG("Error on nvmf connection creation\n"); @@ -912,35 +913,45 @@ spdk_nvmf_rdma_handle_pending_rdma_rw(struct spdk_nvmf_qpair *qpair) /* Public API callbacks begin here */ -static int -spdk_nvmf_rdma_init(uint16_t max_queue_depth, uint32_t max_io_size, - uint32_t in_capsule_data_size) +static struct spdk_nvmf_transport * +spdk_nvmf_rdma_create(struct spdk_nvmf_tgt *tgt) { int rc; + struct spdk_nvmf_transport *transport; + + transport = calloc(1, sizeof(*transport)); + if (!transport) { + return NULL; + } + + transport->tgt = tgt; + transport->ops = &spdk_nvmf_transport_rdma; SPDK_NOTICELOG("*** RDMA Transport Init ***\n"); pthread_mutex_lock(&g_rdma.lock); - g_rdma.max_queue_depth = max_queue_depth; - g_rdma.max_io_size = max_io_size; - g_rdma.in_capsule_data_size = in_capsule_data_size; + g_rdma.max_queue_depth = tgt->max_queue_depth; + g_rdma.max_io_size = tgt->max_io_size; + g_rdma.in_capsule_data_size = tgt->in_capsule_data_size; g_rdma.event_channel = rdma_create_event_channel(); if (g_rdma.event_channel == NULL) { SPDK_ERRLOG("rdma_create_event_channel() failed, %s\n", strerror(errno)); + free(transport); pthread_mutex_unlock(&g_rdma.lock); - return -1; + return NULL; } rc = fcntl(g_rdma.event_channel->fd, F_SETFL, O_NONBLOCK); if (rc < 0) { SPDK_ERRLOG("fcntl to set fd to non-blocking failed\n"); + free(transport); pthread_mutex_unlock(&g_rdma.lock); - return -1; + return NULL; } pthread_mutex_unlock(&g_rdma.lock); - return 0; + return transport; } static void @@ -953,7 +964,7 @@ spdk_nvmf_rdma_listen_addr_free(struct spdk_nvmf_rdma_listen_addr *addr) free(addr); } static int -spdk_nvmf_rdma_fini(void) +spdk_nvmf_rdma_destroy(struct spdk_nvmf_transport *transport) { pthread_mutex_lock(&g_rdma.lock); @@ -963,11 +974,14 @@ spdk_nvmf_rdma_fini(void) } pthread_mutex_unlock(&g_rdma.lock); + free(transport); + return 0; } static int -spdk_nvmf_rdma_listen_remove(struct spdk_nvmf_listen_addr *listen_addr) +spdk_nvmf_rdma_listen_remove(struct spdk_nvmf_transport *transport, + struct spdk_nvmf_listen_addr *listen_addr) { struct spdk_nvmf_rdma_listen_addr *addr, *tmp; @@ -1017,7 +1031,7 @@ spdk_nvmf_rdma_addr_listen_init(struct spdk_nvmf_rdma_listen_addr *addr) } static void -spdk_nvmf_rdma_acceptor_poll(void) +spdk_nvmf_rdma_acceptor_poll(struct spdk_nvmf_transport *transport) { struct rdma_cm_event *event; int rc; @@ -1057,7 +1071,7 @@ spdk_nvmf_rdma_acceptor_poll(void) switch (event->event) { case RDMA_CM_EVENT_CONNECT_REQUEST: - rc = nvmf_rdma_connect(event); + rc = nvmf_rdma_connect(transport, event); if (rc < 0) { SPDK_ERRLOG("Unable to process connect event. rc: %d\n", rc); break; @@ -1091,7 +1105,8 @@ spdk_nvmf_rdma_acceptor_poll(void) } static int -spdk_nvmf_rdma_listen(struct spdk_nvmf_listen_addr *listen_addr) +spdk_nvmf_rdma_listen(struct spdk_nvmf_transport *transport, + struct spdk_nvmf_listen_addr *listen_addr) { struct spdk_nvmf_rdma_listen_addr *addr; struct sockaddr_in saddr; @@ -1177,7 +1192,8 @@ spdk_nvmf_rdma_listen(struct spdk_nvmf_listen_addr *listen_addr) } static void -spdk_nvmf_rdma_discover(struct spdk_nvmf_listen_addr *listen_addr, +spdk_nvmf_rdma_discover(struct spdk_nvmf_transport *transport, + struct spdk_nvmf_listen_addr *listen_addr, struct spdk_nvmf_discovery_log_page_entry *entry) { entry->trtype = SPDK_NVMF_TRTYPE_RDMA; @@ -1193,7 +1209,7 @@ spdk_nvmf_rdma_discover(struct spdk_nvmf_listen_addr *listen_addr, } static struct spdk_nvmf_ctrlr * -spdk_nvmf_rdma_ctrlr_init(void) +spdk_nvmf_rdma_ctrlr_init(struct spdk_nvmf_transport *transport) { struct spdk_nvmf_rdma_ctrlr *rdma_ctrlr; int i; @@ -1222,7 +1238,7 @@ spdk_nvmf_rdma_ctrlr_init(void) SLIST_INSERT_HEAD(&rdma_ctrlr->data_buf_pool, buf, link); } - rdma_ctrlr->ctrlr.transport = &spdk_nvmf_transport_rdma; + rdma_ctrlr->ctrlr.transport = transport; return &rdma_ctrlr->ctrlr; } @@ -1575,10 +1591,10 @@ spdk_nvmf_rdma_qpair_is_idle(struct spdk_nvmf_qpair *qpair) return false; } -const struct spdk_nvmf_transport spdk_nvmf_transport_rdma = { +const struct spdk_nvmf_transport_ops spdk_nvmf_transport_rdma = { .type = SPDK_NVME_TRANSPORT_RDMA, - .transport_init = spdk_nvmf_rdma_init, - .transport_fini = spdk_nvmf_rdma_fini, + .create = spdk_nvmf_rdma_create, + .destroy = spdk_nvmf_rdma_destroy, .acceptor_poll = spdk_nvmf_rdma_acceptor_poll, diff --git a/lib/nvmf/request.c b/lib/nvmf/request.c index 5ee886bdf..8c74c6522 100644 --- a/lib/nvmf/request.c +++ b/lib/nvmf/request.c @@ -59,7 +59,7 @@ spdk_nvmf_request_complete(struct spdk_nvmf_request *req) response->cid, response->cdw0, response->rsvd1, *(uint16_t *)&response->status); - if (req->qpair->transport->req_complete(req)) { + if (req->qpair->transport->ops->req_complete(req)) { SPDK_ERRLOG("Transport request completion error!\n"); return -1; } diff --git a/lib/nvmf/subsystem.c b/lib/nvmf/subsystem.c index 4a32b5006..3a62884f4 100644 --- a/lib/nvmf/subsystem.c +++ b/lib/nvmf/subsystem.c @@ -118,7 +118,7 @@ nvmf_subsystem_removable(struct spdk_nvmf_subsystem *subsystem) if (subsystem->is_removed) { TAILQ_FOREACH(ctrlr, &subsystem->ctrlrs, link) { TAILQ_FOREACH(qpair, &ctrlr->qpairs, link) { - if (!qpair->transport->qpair_is_idle(qpair)) { + if (!qpair->transport->ops->qpair_is_idle(qpair)) { return false; } } @@ -262,7 +262,7 @@ struct spdk_nvmf_listen_addr * spdk_nvmf_tgt_listen(struct spdk_nvme_transport_id *trid) { struct spdk_nvmf_listen_addr *listen_addr; - const struct spdk_nvmf_transport *transport; + struct spdk_nvmf_transport *transport; int rc; TAILQ_FOREACH(listen_addr, &g_nvmf_tgt.listen_addrs, link) { @@ -271,18 +271,23 @@ spdk_nvmf_tgt_listen(struct spdk_nvme_transport_id *trid) } } - transport = spdk_nvmf_transport_get(trid->trtype); + transport = spdk_nvmf_tgt_get_transport(&g_nvmf_tgt, trid->trtype); if (!transport) { - SPDK_ERRLOG("Unknown transport '%u'\n", trid->trtype); - return NULL; + transport = spdk_nvmf_transport_create(&g_nvmf_tgt, trid->trtype); + if (!transport) { + SPDK_ERRLOG("Transport initialization failed\n"); + return NULL; + } + TAILQ_INSERT_TAIL(&g_nvmf_tgt.transports, transport, link); } + listen_addr = spdk_nvmf_listen_addr_create(trid); if (!listen_addr) { return NULL; } - rc = transport->listen_addr_add(listen_addr); + rc = transport->ops->listen_addr_add(transport, listen_addr); if (rc < 0) { free(listen_addr); SPDK_ERRLOG("Unable to listen on address '%s'\n", trid->traddr); diff --git a/lib/nvmf/transport.c b/lib/nvmf/transport.c index a6cbe25bf..ab8862111 100644 --- a/lib/nvmf/transport.c +++ b/lib/nvmf/transport.c @@ -42,71 +42,56 @@ #include "nvmf_internal.h" -static const struct spdk_nvmf_transport *const g_transports[] = { +static const struct spdk_nvmf_transport_ops *const g_transport_ops[] = { #ifdef SPDK_CONFIG_RDMA &spdk_nvmf_transport_rdma, #endif }; -#define NUM_TRANSPORTS (SPDK_COUNTOF(g_transports)) +#define NUM_TRANSPORTS (SPDK_COUNTOF(g_transport_ops)) -int -spdk_nvmf_transport_init(void) +struct spdk_nvmf_transport * +spdk_nvmf_transport_create(struct spdk_nvmf_tgt *tgt, + enum spdk_nvme_transport_type type) { size_t i; - int count = 0; + const struct spdk_nvmf_transport_ops *ops = NULL; + struct spdk_nvmf_transport *transport; for (i = 0; i != NUM_TRANSPORTS; i++) { - if (g_transports[i]->transport_init(g_nvmf_tgt.max_queue_depth, g_nvmf_tgt.max_io_size, - g_nvmf_tgt.in_capsule_data_size) < 0) { - SPDK_NOTICELOG("Transport type %s init failed\n", - spdk_nvme_transport_id_trtype_str(g_transports[i]->type)); - } else { - count++; + if (g_transport_ops[i]->type == type) { + ops = g_transport_ops[i]; + break; } } - return count; + if (!ops) { + SPDK_ERRLOG("Transport type %s unavailable.\n", + spdk_nvme_transport_id_trtype_str(type)); + return NULL; + } + + transport = ops->create(tgt); + if (!transport) { + SPDK_ERRLOG("Unable to create new transport of type %s\n", + spdk_nvme_transport_id_trtype_str(type)); + return NULL; + } + + transport->ops = ops; + transport->tgt = tgt; + + return transport; } int -spdk_nvmf_transport_fini(void) +spdk_nvmf_transport_destroy(struct spdk_nvmf_transport *transport) { - size_t i; - int count = 0; - - for (i = 0; i != NUM_TRANSPORTS; i++) { - if (g_transports[i]->transport_fini() < 0) { - SPDK_NOTICELOG("Transport type %s fini failed\n", - spdk_nvme_transport_id_trtype_str(g_transports[i]->type)); - } else { - count++; - } - } - - return count; + return transport->ops->destroy(transport); } void -spdk_nvmf_acceptor_poll(void) +spdk_nvmf_transport_poll(struct spdk_nvmf_transport *transport) { - size_t i; - - for (i = 0; i != NUM_TRANSPORTS; i++) { - g_transports[i]->acceptor_poll(); - } -} - -const struct spdk_nvmf_transport * -spdk_nvmf_transport_get(enum spdk_nvme_transport_type type) -{ - size_t i; - - for (i = 0; i != NUM_TRANSPORTS; i++) { - if (type == g_transports[i]->type) { - return g_transports[i]; - } - } - - return NULL; + transport->ops->acceptor_poll(transport); } diff --git a/lib/nvmf/transport.h b/lib/nvmf/transport.h index 79628c254..bad623b42 100644 --- a/lib/nvmf/transport.h +++ b/lib/nvmf/transport.h @@ -42,49 +42,58 @@ struct spdk_nvmf_listen_addr; struct spdk_nvmf_transport { + struct spdk_nvmf_tgt *tgt; + const struct spdk_nvmf_transport_ops *ops; + + TAILQ_ENTRY(spdk_nvmf_transport) link; +}; + +struct spdk_nvmf_transport_ops { /** * Transport type */ enum spdk_nvme_transport_type type; /** - * Initialize the transport. + * Create a transport for the given target */ - int (*transport_init)(uint16_t max_queue_depth, uint32_t max_io_size, - uint32_t in_capsule_data_size); + struct spdk_nvmf_transport *(*create)(struct spdk_nvmf_tgt *tgt); /** - * Shut down the transport. + * Destroy the transport */ - int (*transport_fini)(void); + int (*destroy)(struct spdk_nvmf_transport *transport); /** * Check for new connections on the transport. */ - void (*acceptor_poll)(void); + void (*acceptor_poll)(struct spdk_nvmf_transport *transport); /** * Instruct the acceptor to listen on the address provided. This * may be called multiple times. */ - int (*listen_addr_add)(struct spdk_nvmf_listen_addr *listen_addr); + int (*listen_addr_add)(struct spdk_nvmf_transport *transport, + struct spdk_nvmf_listen_addr *listen_addr); /** * Instruct to remove listening on the address provided. This * may be called multiple times. */ - int (*listen_addr_remove)(struct spdk_nvmf_listen_addr *listen_addr); + int (*listen_addr_remove)(struct spdk_nvmf_transport *transport, + struct spdk_nvmf_listen_addr *listen_addr); /** * Fill out a discovery log entry for a specific listen address. */ - void (*listen_addr_discover)(struct spdk_nvmf_listen_addr *listen_addr, + void (*listen_addr_discover)(struct spdk_nvmf_transport *transport, + struct spdk_nvmf_listen_addr *listen_addr, struct spdk_nvmf_discovery_log_page_entry *entry); /** * Create a new ctrlr */ - struct spdk_nvmf_ctrlr *(*ctrlr_init)(void); + struct spdk_nvmf_ctrlr *(*ctrlr_init)(struct spdk_nvmf_transport *transport); /** * Destroy a ctrlr @@ -123,11 +132,12 @@ struct spdk_nvmf_transport { bool (*qpair_is_idle)(struct spdk_nvmf_qpair *qpair); }; -int spdk_nvmf_transport_init(void); -int spdk_nvmf_transport_fini(void); +struct spdk_nvmf_transport *spdk_nvmf_transport_create(struct spdk_nvmf_tgt *tgt, + enum spdk_nvme_transport_type type); +int spdk_nvmf_transport_destroy(struct spdk_nvmf_transport *transport); -const struct spdk_nvmf_transport *spdk_nvmf_transport_get(enum spdk_nvme_transport_type type); +void spdk_nvmf_transport_poll(struct spdk_nvmf_transport *transport); -extern const struct spdk_nvmf_transport spdk_nvmf_transport_rdma; +extern const struct spdk_nvmf_transport_ops spdk_nvmf_transport_rdma; #endif /* SPDK_NVMF_TRANSPORT_H */ diff --git a/test/unit/lib/nvmf/ctrlr_discovery.c/ctrlr_discovery_ut.c b/test/unit/lib/nvmf/ctrlr_discovery.c/ctrlr_discovery_ut.c index 62fed2ff9..caf089f4a 100644 --- a/test/unit/lib/nvmf/ctrlr_discovery.c/ctrlr_discovery_ut.c +++ b/test/unit/lib/nvmf/ctrlr_discovery.c/ctrlr_discovery_ut.c @@ -80,27 +80,46 @@ spdk_bdev_get_name(const struct spdk_bdev *bdev) } static int -test_transport1_listen_addr_add(struct spdk_nvmf_listen_addr *listen_addr) +test_transport1_listen_addr_add(struct spdk_nvmf_transport *transport, + struct spdk_nvmf_listen_addr *listen_addr) { return 0; } static void -test_transport1_listen_addr_discover(struct spdk_nvmf_listen_addr *listen_addr, +test_transport1_listen_addr_discover(struct spdk_nvmf_transport *transport, + struct spdk_nvmf_listen_addr *listen_addr, struct spdk_nvmf_discovery_log_page_entry *entry) { entry->trtype = 42; } -static const struct spdk_nvmf_transport test_transport1 = { +static const struct spdk_nvmf_transport_ops test_transport1_ops = { .listen_addr_add = test_transport1_listen_addr_add, .listen_addr_discover = test_transport1_listen_addr_discover, }; -const struct spdk_nvmf_transport * -spdk_nvmf_transport_get(enum spdk_nvme_transport_type trtype) +static struct spdk_nvmf_transport test_transport1 = { + .ops = &test_transport1_ops, +}; + +struct spdk_nvmf_transport * +spdk_nvmf_transport_create(struct spdk_nvmf_tgt *tgt, + enum spdk_nvme_transport_type type) +{ + if (type == SPDK_NVME_TRANSPORT_RDMA) { + test_transport1.tgt = tgt; + return &test_transport1; + } + + return NULL; +} + +struct spdk_nvmf_transport * +spdk_nvmf_tgt_get_transport(struct spdk_nvmf_tgt *tgt, enum spdk_nvme_transport_type trtype) { if (trtype == SPDK_NVME_TRANSPORT_RDMA) { + test_transport1.tgt = tgt; return &test_transport1; } diff --git a/test/unit/lib/nvmf/subsystem.c/subsystem_ut.c b/test/unit/lib/nvmf/subsystem.c/subsystem_ut.c index a77aa80d0..0efdb5216 100644 --- a/test/unit/lib/nvmf/subsystem.c/subsystem_ut.c +++ b/test/unit/lib/nvmf/subsystem.c/subsystem_ut.c @@ -67,27 +67,46 @@ spdk_nvmf_listen_addr_destroy(struct spdk_nvmf_listen_addr *addr) } static int -test_transport1_listen_addr_add(struct spdk_nvmf_listen_addr *listen_addr) +test_transport1_listen_addr_add(struct spdk_nvmf_transport *transport, + struct spdk_nvmf_listen_addr *listen_addr) { return 0; } static void -test_transport1_listen_addr_discover(struct spdk_nvmf_listen_addr *listen_addr, +test_transport1_listen_addr_discover(struct spdk_nvmf_transport *transport, + struct spdk_nvmf_listen_addr *listen_addr, struct spdk_nvmf_discovery_log_page_entry *entry) { entry->trtype = 42; } -static const struct spdk_nvmf_transport test_transport1 = { +static const struct spdk_nvmf_transport_ops test_transport1_ops = { .listen_addr_add = test_transport1_listen_addr_add, .listen_addr_discover = test_transport1_listen_addr_discover, }; -const struct spdk_nvmf_transport * -spdk_nvmf_transport_get(enum spdk_nvme_transport_type trtype) +static struct spdk_nvmf_transport test_transport1 = { + .ops = &test_transport1_ops, +}; + +struct spdk_nvmf_transport * +spdk_nvmf_transport_create(struct spdk_nvmf_tgt *tgt, + enum spdk_nvme_transport_type type) +{ + if (type == SPDK_NVME_TRANSPORT_RDMA) { + test_transport1.tgt = tgt; + return &test_transport1; + } + + return NULL; +} + +struct spdk_nvmf_transport * +spdk_nvmf_tgt_get_transport(struct spdk_nvmf_tgt *tgt, enum spdk_nvme_transport_type trtype) { if (trtype == SPDK_NVME_TRANSPORT_RDMA) { + test_transport1.tgt = tgt; return &test_transport1; }