From d5ab08662a64c410e72c027530c7a384d7ba353c Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 19 Mar 2026 16:49:43 +0100 Subject: [PATCH 01/10] libnvme: use 'struct nvmf_context' as argument for __nvme_lookup_ctrl() To simplify the interface. Signed-off-by: Hannes Reinecke --- libnvme/src/nvme/fabrics.c | 35 +++++++++++++++++++---------------- libnvme/src/nvme/private.h | 7 +++---- libnvme/src/nvme/tree.c | 37 ++++++++++++++++++++++++++----------- 3 files changed, 48 insertions(+), 31 deletions(-) diff --git a/libnvme/src/nvme/fabrics.c b/libnvme/src/nvme/fabrics.c index e365b5bb38..b963288c3f 100644 --- a/libnvme/src/nvme/fabrics.c +++ b/libnvme/src/nvme/fabrics.c @@ -968,13 +968,15 @@ static const char *lookup_context(struct nvme_global_ctx *ctx, nvme_ctrl_t c) nvme_for_each_host(ctx, h) { nvme_for_each_subsystem(h, s) { - if (__nvme_lookup_ctrl(s, nvme_ctrl_get_transport(c), - nvme_ctrl_get_traddr(c), - NULL, - NULL, - nvme_ctrl_get_trsvcid(c), - NULL, - NULL)) + struct nvmf_context fctx = { + .transport = nvme_ctrl_get_transport(c), + .traddr = nvme_ctrl_get_traddr(c), + .host_traddr = NULL, + .host_iface = NULL, + .trsvcid = nvme_ctrl_get_trsvcid(c), + .subsysnqn = NULL, + }; + if (__nvme_lookup_ctrl(s, &fctx, NULL)) return nvme_subsystem_get_application(s); } } @@ -997,14 +999,16 @@ __public int nvmf_add_ctrl(nvme_host_t h, nvme_ctrl_t c, s = nvme_lookup_subsystem(h, NULL, nvme_ctrl_get_subsysnqn(c)); if (s) { nvme_ctrl_t fc; - - fc = __nvme_lookup_ctrl(s, nvme_ctrl_get_transport(c), - nvme_ctrl_get_traddr(c), - nvme_ctrl_get_host_traddr(c), - nvme_ctrl_get_host_iface(c), - nvme_ctrl_get_trsvcid(c), - NULL, - NULL); + struct nvmf_context fctx = { + .transport = nvme_ctrl_get_transport(c), + .traddr = nvme_ctrl_get_traddr(c), + .host_traddr = nvme_ctrl_get_host_traddr(c), + .host_iface = nvme_ctrl_get_trsvcid(c), + .trsvcid = nvme_ctrl_get_trsvcid(c), + .subsysnqn = NULL, + }; + + fc = __nvme_lookup_ctrl(s, &fctx, NULL); if (fc) { const char *key; @@ -2439,7 +2443,6 @@ __public int nvmf_config_modify(struct nvme_global_ctx *ctx, nvme_msg(ctx, LOG_ERR, "Failed to lookup controller\n"); return -ENODEV; } - if (fctx->ctrlkey) nvme_ctrl_set_dhchap_ctrl_key(c, fctx->ctrlkey); diff --git a/libnvme/src/nvme/private.h b/libnvme/src/nvme/private.h index 82873fcd6b..708206f03c 100644 --- a/libnvme/src/nvme/private.h +++ b/libnvme/src/nvme/private.h @@ -381,10 +381,9 @@ int __nvme_transport_handle_open_mi(struct nvme_transport_handle *hdl, const cha int __nvme_transport_handle_init_mi(struct nvme_transport_handle *hdl); void __nvme_transport_handle_close_mi(struct nvme_transport_handle *hdl); -nvme_ctrl_t __nvme_lookup_ctrl(nvme_subsystem_t s, const char *transport, - const char *traddr, const char *host_traddr, - const char *host_iface, const char *trsvcid, - const char *subsysnqn, nvme_ctrl_t p); +nvme_ctrl_t __nvme_lookup_ctrl(nvme_subsystem_t s, + struct nvmf_context *fctx, + nvme_ctrl_t p); void *__nvme_alloc(size_t len); diff --git a/libnvme/src/nvme/tree.c b/libnvme/src/nvme/tree.c index 0d836b436a..d2159dcb36 100644 --- a/libnvme/src/nvme/tree.c +++ b/libnvme/src/nvme/tree.c @@ -1437,19 +1437,18 @@ static ctrl_match_t _candidate_init(struct nvme_global_ctx *ctx, return _match_ctrl; } -nvme_ctrl_t __nvme_lookup_ctrl(nvme_subsystem_t s, const char *transport, - const char *traddr, const char *host_traddr, - const char *host_iface, const char *trsvcid, - const char *subsysnqn, nvme_ctrl_t p) +nvme_ctrl_t __nvme_lookup_ctrl(nvme_subsystem_t s, struct nvmf_context *fctx, + nvme_ctrl_t p) { struct candidate_args candidate = {}; struct nvme_ctrl *c, *matching_c = NULL; ctrl_match_t ctrl_match; /* Init candidate and get the matching function to use */ - ctrl_match = _candidate_init(s->h->ctx, &candidate, transport, traddr, - trsvcid, subsysnqn, host_traddr, - host_iface); + ctrl_match = _candidate_init(s->h->ctx, &candidate, + fctx->transport, fctx->traddr, + fctx->trsvcid, fctx->subsysnqn, + fctx->host_traddr, fctx->host_iface); c = p ? nvme_subsystem_next_ctrl(s, p) : nvme_subsystem_first_ctrl(s); for (; c != NULL; c = nvme_subsystem_next_ctrl(s, c)) { @@ -1483,8 +1482,16 @@ nvme_ctrl_t nvme_ctrl_find(nvme_subsystem_t s, const char *transport, const char *subsysnqn, const char *host_traddr, const char *host_iface) { - return __nvme_lookup_ctrl(s, transport, traddr, host_traddr, host_iface, - trsvcid, subsysnqn, NULL/*p*/); + struct nvmf_context fctx = { + .transport = transport, + .traddr = traddr, + .host_traddr = host_traddr, + .host_iface = host_iface, + .trsvcid = trsvcid, + .subsysnqn = subsysnqn, + }; + + return __nvme_lookup_ctrl(s, &fctx, NULL/*p*/); } nvme_ctrl_t nvme_lookup_ctrl(nvme_subsystem_t s, const char *transport, @@ -1499,8 +1506,16 @@ nvme_ctrl_t nvme_lookup_ctrl(nvme_subsystem_t s, const char *transport, if (!s || !transport) return NULL; - c = __nvme_lookup_ctrl(s, transport, traddr, host_traddr, - host_iface, trsvcid, NULL, p); + struct nvmf_context fctx = { + .transport = transport, + .traddr = traddr, + .host_traddr = host_traddr, + .host_iface = host_iface, + .trsvcid = trsvcid, + .subsysnqn = NULL, + }; + + c = __nvme_lookup_ctrl(s, &fctx, p); if (c) return c; From 34612f60fdd6d5c7a023eec3fb88bfd0393b6dfc Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 19 Mar 2026 16:55:16 +0100 Subject: [PATCH 02/10] libnvme: use 'struct nvmf_context' as argument to _candidate_init() To simplify the interface. Signed-off-by: Hannes Reinecke --- libnvme/src/nvme/tree.c | 44 ++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/libnvme/src/nvme/tree.c b/libnvme/src/nvme/tree.c index d2159dcb36..d1ee10c896 100644 --- a/libnvme/src/nvme/tree.c +++ b/libnvme/src/nvme/tree.c @@ -1393,23 +1393,20 @@ static bool _match_ctrl(struct nvme_ctrl *c, struct candidate_args *candidate) */ static ctrl_match_t _candidate_init(struct nvme_global_ctx *ctx, struct candidate_args *candidate, - const char *transport, - const char *traddr, - const char *trsvcid, - const char *subsysnqn, - const char *host_traddr, - const char *host_iface) + struct nvmf_context *fctx) { memset(candidate, 0, sizeof(*candidate)); - candidate->traddr = traddr; - candidate->trsvcid = trsvcid; - candidate->transport = transport; - candidate->subsysnqn = subsysnqn; - candidate->host_iface = streqcase0(host_iface, "none") ? NULL : host_iface; - candidate->host_traddr = streqcase0(host_traddr, "none") ? NULL : host_traddr; + candidate->traddr = fctx->traddr; + candidate->trsvcid = fctx->trsvcid; + candidate->transport = fctx->transport; + candidate->subsysnqn = fctx->subsysnqn; + candidate->host_iface = streqcase0(fctx->host_iface, "none") ? + NULL : fctx->host_iface; + candidate->host_traddr = streqcase0(fctx->host_traddr, "none") ? + NULL : fctx->host_traddr; - if (streq0(subsysnqn, NVME_DISC_SUBSYS_NAME)) { + if (streq0(fctx->subsysnqn, NVME_DISC_SUBSYS_NAME)) { /* Since TP8013, the NQN of discovery controllers can be the * well-known NQN (i.e. nqn.2014-08.org.nvmexpress.discovery) or * a unique NQN. A DC created using the well-known NQN may later @@ -1421,13 +1418,13 @@ static ctrl_match_t _candidate_init(struct nvme_global_ctx *ctx, candidate->well_known_nqn = true; } - if (streq0(transport, "tcp")) { + if (streq0(fctx->transport, "tcp")) { candidate->iface_list = nvme_getifaddrs(ctx); /* TCP only */ candidate->addreq = nvme_ipaddrs_eq; return _tcp_match_ctrl; } - if (streq0(transport, "rdma")) { + if (streq0(fctx->transport, "rdma")) { candidate->addreq = nvme_ipaddrs_eq; return _match_ctrl; } @@ -1445,10 +1442,7 @@ nvme_ctrl_t __nvme_lookup_ctrl(nvme_subsystem_t s, struct nvmf_context *fctx, ctrl_match_t ctrl_match; /* Init candidate and get the matching function to use */ - ctrl_match = _candidate_init(s->h->ctx, &candidate, - fctx->transport, fctx->traddr, - fctx->trsvcid, fctx->subsysnqn, - fctx->host_traddr, fctx->host_iface); + ctrl_match = _candidate_init(s->h->ctx, &candidate, fctx); c = p ? nvme_subsystem_next_ctrl(s, p) : nvme_subsystem_first_ctrl(s); for (; c != NULL; c = nvme_subsystem_next_ctrl(s, c)) { @@ -1468,11 +1462,17 @@ __public bool nvme_ctrl_match_config(struct nvme_ctrl *c, const char *transport, { struct candidate_args candidate = {}; ctrl_match_t ctrl_match; + struct nvmf_context fctx = { + .transport = transport, + .traddr = traddr, + .host_traddr = host_traddr, + .host_iface = host_iface, + .trsvcid = trsvcid, + .subsysnqn = subsysnqn, + }; /* Init candidate and get the matching function to use */ - ctrl_match = _candidate_init(c->ctx, &candidate, transport, traddr, - trsvcid, subsysnqn, host_traddr, - host_iface); + ctrl_match = _candidate_init(c->ctx, &candidate, &fctx); return ctrl_match(c, &candidate); } From c5ec40ab56f8d4fb6fca2b6615557b1ee571d91c Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 19 Mar 2026 17:00:23 +0100 Subject: [PATCH 03/10] libnvme; use 'struct nvmf_context' as argument to nvme_ctrl_find() To simplify the interface. Signed-off-by: Hannes Reinecke --- libnvme/src/nvme/fabrics.c | 8 +------- libnvme/src/nvme/private.h | 5 +---- libnvme/src/nvme/tree.c | 16 ++-------------- libnvme/test/tree.c | 13 +++++++++---- 4 files changed, 13 insertions(+), 29 deletions(-) diff --git a/libnvme/src/nvme/fabrics.c b/libnvme/src/nvme/fabrics.c index b963288c3f..b933d05585 100644 --- a/libnvme/src/nvme/fabrics.c +++ b/libnvme/src/nvme/fabrics.c @@ -1816,13 +1816,7 @@ static nvme_ctrl_t lookup_ctrl(nvme_host_t h, struct nvmf_context *fctx) nvme_ctrl_t c; nvme_for_each_subsystem(h, s) { - c = nvme_ctrl_find(s, - fctx->transport, - fctx->traddr, - fctx->trsvcid, - fctx->subsysnqn, - fctx->host_traddr, - fctx->host_iface); + c = nvme_ctrl_find(s, fctx); if (c) return c; } diff --git a/libnvme/src/nvme/private.h b/libnvme/src/nvme/private.h index 708206f03c..c2db918d6b 100644 --- a/libnvme/src/nvme/private.h +++ b/libnvme/src/nvme/private.h @@ -398,10 +398,7 @@ nvme_ctrl_t nvme_lookup_ctrl(nvme_subsystem_t s, const char *transport, const char *traddr, const char *host_traddr, const char *host_iface, const char *trsvcid, nvme_ctrl_t p); -nvme_ctrl_t nvme_ctrl_find(nvme_subsystem_t s, const char *transport, - const char *traddr, const char *trsvcid, - const char *subsysnqn, const char *host_traddr, - const char *host_iface); +nvme_ctrl_t nvme_ctrl_find(nvme_subsystem_t s, struct nvmf_context *fctx); void __nvme_free_host(nvme_host_t h); diff --git a/libnvme/src/nvme/tree.c b/libnvme/src/nvme/tree.c index d1ee10c896..636989baf7 100644 --- a/libnvme/src/nvme/tree.c +++ b/libnvme/src/nvme/tree.c @@ -1477,21 +1477,9 @@ __public bool nvme_ctrl_match_config(struct nvme_ctrl *c, const char *transport, return ctrl_match(c, &candidate); } -nvme_ctrl_t nvme_ctrl_find(nvme_subsystem_t s, const char *transport, - const char *traddr, const char *trsvcid, - const char *subsysnqn, const char *host_traddr, - const char *host_iface) +nvme_ctrl_t nvme_ctrl_find(nvme_subsystem_t s, struct nvmf_context *fctx) { - struct nvmf_context fctx = { - .transport = transport, - .traddr = traddr, - .host_traddr = host_traddr, - .host_iface = host_iface, - .trsvcid = trsvcid, - .subsysnqn = subsysnqn, - }; - - return __nvme_lookup_ctrl(s, &fctx, NULL/*p*/); + return __nvme_lookup_ctrl(s, fctx, NULL/*p*/); } nvme_ctrl_t nvme_lookup_ctrl(nvme_subsystem_t s, const char *transport, diff --git a/libnvme/test/tree.c b/libnvme/test/tree.c index 076c10c485..862afa3f03 100644 --- a/libnvme/test/tree.c +++ b/libnvme/test/tree.c @@ -455,6 +455,14 @@ static bool ctrl_match(const char *tag, bool should_match) { struct nvme_global_ctx *ctx; + struct nvmf_context fctx = { + .transport = candidate->transport, + .traddr = candidate->traddr, + .host_traddr = candidate->host_traddr, + .host_iface = candidate->host_iface, + .trsvcid = candidate->trsvcid, + .subsysnqn = candidate->subsysnqn, + }; nvme_host_t h; nvme_ctrl_t reference_ctrl; /* Existing controller (from sysfs) */ nvme_ctrl_t candidate_ctrl; @@ -483,10 +491,7 @@ static bool ctrl_match(const char *tag, } /* nvme_ctrl_find() MUST BE RUN BEFORE nvme_lookup_ctrl() */ - found_ctrl = nvme_ctrl_find(s, candidate->transport, candidate->traddr, - candidate->trsvcid, candidate->subsysnqn, - candidate->host_traddr, - candidate->host_iface); + found_ctrl = nvme_ctrl_find(s, &fctx); candidate_ctrl = nvme_lookup_ctrl(s, candidate->transport, candidate->traddr, candidate->host_traddr, candidate->host_iface, From 2510496a9362b7354ac129f66300586192dbbd80 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 19 Mar 2026 18:26:35 +0100 Subject: [PATCH 04/10] libnvme: Separate out _nvme_create_ctrl() Separate out _nvme_create_ctrl() as a simpler interface to nvme_create_ctrl() which accepts a 'struct nvmf_context' as argument. Signed-off-by: Hannes Reinecke --- libnvme/src/nvme/fabrics.c | 36 +++++++++----------- libnvme/src/nvme/private.h | 3 ++ libnvme/src/nvme/tree.c | 67 ++++++++++++++++++++++++-------------- 3 files changed, 61 insertions(+), 45 deletions(-) diff --git a/libnvme/src/nvme/fabrics.c b/libnvme/src/nvme/fabrics.c index b933d05585..026a61ea15 100644 --- a/libnvme/src/nvme/fabrics.c +++ b/libnvme/src/nvme/fabrics.c @@ -1102,8 +1102,10 @@ static int nvmf_connect_disc_entry(nvme_host_t h, const struct nvme_fabrics_config *cfg, bool *discover, nvme_ctrl_t *cp) { - char *traddr = NULL, *trsvcid = NULL; - const char *transport; + struct nvmf_context fctx = { + .host_traddr = host_traddr, + .host_iface = host_iface, + }; nvme_ctrl_t c; int ret; @@ -1113,8 +1115,8 @@ static int nvmf_connect_disc_entry(nvme_host_t h, switch (e->adrfam) { case NVMF_ADDR_FAMILY_IP4: case NVMF_ADDR_FAMILY_IP6: - traddr = e->traddr; - trsvcid = e->trsvcid; + fctx.traddr = e->traddr; + fctx.trsvcid = e->trsvcid; break; default: nvme_msg(h->ctx, LOG_ERR, @@ -1126,7 +1128,7 @@ static int nvmf_connect_disc_entry(nvme_host_t h, case NVMF_TRTYPE_FC: switch (e->adrfam) { case NVMF_ADDR_FAMILY_FC: - traddr = e->traddr; + fctx.traddr = e->traddr; break; default: nvme_msg(h->ctx, LOG_ERR, @@ -1136,7 +1138,7 @@ static int nvmf_connect_disc_entry(nvme_host_t h, } break; case NVMF_TRTYPE_LOOP: - traddr = strlen(e->traddr) ? e->traddr : NULL; + fctx.traddr = strlen(e->traddr) ? e->traddr : NULL; break; default: nvme_msg(h->ctx, LOG_ERR, "skipping unsupported transport %d\n", @@ -1144,18 +1146,18 @@ static int nvmf_connect_disc_entry(nvme_host_t h, return -EINVAL; } - transport = nvmf_trtype_str(e->trtype); + fctx.transport = nvmf_trtype_str(e->trtype); + fctx.subsysnqn = e->subnqn; nvme_msg(h->ctx, LOG_DEBUG, "lookup ctrl " "(transport: %s, traddr: %s, trsvcid %s)\n", - transport, traddr, trsvcid); + fctx.transport, fctx.traddr, fctx.trsvcid); - ret = nvme_create_ctrl(h->ctx, e->subnqn, transport, traddr, - host_traddr, host_iface, trsvcid, &c); + ret = _nvme_create_ctrl(h->ctx, &fctx, &c); if (ret) { nvme_msg(h->ctx, LOG_DEBUG, "skipping discovery entry, " "failed to allocate %s controller with traddr %s\n", - transport, traddr); + fctx.transport, fctx.traddr); return ret; } @@ -2070,9 +2072,7 @@ static int __create_discovery_ctrl(struct nvme_global_ctx *ctx, nvme_ctrl_t c; int tmo, ret; - ret = nvme_create_ctrl(ctx, fctx->subsysnqn, fctx->transport, - fctx->traddr, fctx->host_traddr, - fctx->host_iface, fctx->trsvcid, &c); + ret = _nvme_create_ctrl(ctx, fctx, &c); if (ret) return ret; @@ -2551,9 +2551,7 @@ static int nbft_connect(struct nvme_global_ctx *ctx, if (c && nvme_ctrl_get_name(c)) return 0; - ret = nvme_create_ctrl(ctx, fctx->subsysnqn, fctx->transport, - fctx->traddr, fctx->host_traddr, - fctx->host_iface, fctx->trsvcid, &c); + ret = _nvme_create_ctrl(ctx, fctx, &c); if (ret) return ret; @@ -3034,9 +3032,7 @@ __public int nvmf_connect(struct nvme_global_ctx *ctx, struct nvmf_context *fctx return -EALREADY; } - err = nvme_create_ctrl(ctx, fctx->subsysnqn, fctx->transport, - fctx->traddr, fctx->host_traddr, fctx->host_iface, - fctx->trsvcid, &c); + err = _nvme_create_ctrl(ctx, fctx, &c); if (err) return err; diff --git a/libnvme/src/nvme/private.h b/libnvme/src/nvme/private.h index c2db918d6b..4ce55b24f9 100644 --- a/libnvme/src/nvme/private.h +++ b/libnvme/src/nvme/private.h @@ -381,6 +381,9 @@ int __nvme_transport_handle_open_mi(struct nvme_transport_handle *hdl, const cha int __nvme_transport_handle_init_mi(struct nvme_transport_handle *hdl); void __nvme_transport_handle_close_mi(struct nvme_transport_handle *hdl); +int _nvme_create_ctrl(struct nvme_global_ctx *ctx, + struct nvmf_context *fctx, + nvme_ctrl_t *cp); nvme_ctrl_t __nvme_lookup_ctrl(nvme_subsystem_t s, struct nvmf_context *fctx, nvme_ctrl_t p); diff --git a/libnvme/src/nvme/tree.c b/libnvme/src/nvme/tree.c index 636989baf7..2a7bd32f33 100644 --- a/libnvme/src/nvme/tree.c +++ b/libnvme/src/nvme/tree.c @@ -1062,26 +1062,24 @@ __public void nvmf_default_config(struct nvme_fabrics_config *cfg) cfg->ctrl_loss_tmo = NVMF_DEF_CTRL_LOSS_TMO; } -__public int nvme_create_ctrl(struct nvme_global_ctx *ctx, - const char *subsysnqn, const char *transport, - const char *traddr, const char *host_traddr, - const char *host_iface, const char *trsvcid, - nvme_ctrl_t *cp) +int _nvme_create_ctrl(struct nvme_global_ctx *ctx, + struct nvmf_context *fctx, + nvme_ctrl_t *cp) { struct nvme_ctrl *c; - if (!transport) { + if (!fctx->transport) { nvme_msg(ctx, LOG_ERR, "No transport specified\n"); return -EINVAL; } - if (strncmp(transport, "loop", 4) && - strncmp(transport, "pcie", 4) && - strncmp(transport, "apple-nvme", 10) && !traddr) { + if (strncmp(fctx->transport, "loop", 4) && + strncmp(fctx->transport, "pcie", 4) && + strncmp(fctx->transport, "apple-nvme", 10) && !fctx->traddr) { nvme_msg(ctx, LOG_ERR, "No transport address for '%s'\n", - transport); + fctx->transport); return -EINVAL; } - if (!subsysnqn) { + if (!fctx->subsysnqn) { nvme_msg(ctx, LOG_ERR, "No subsystem NQN specified\n"); return -EINVAL; } @@ -1095,25 +1093,44 @@ __public int nvme_create_ctrl(struct nvme_global_ctx *ctx, list_head_init(&c->namespaces); list_head_init(&c->paths); list_node_init(&c->entry); - c->transport = strdup(transport); - c->subsysnqn = strdup(subsysnqn); - if (traddr) - c->traddr = strdup(traddr); - if (host_traddr) { - if (traddr_is_hostname(transport, host_traddr)) - hostname2traddr(ctx, host_traddr, &c->host_traddr); + c->transport = strdup(fctx->transport); + c->subsysnqn = strdup(fctx->subsysnqn); + if (fctx->traddr) + c->traddr = strdup(fctx->traddr); + if (fctx->host_traddr) { + if (traddr_is_hostname(fctx->transport, fctx->host_traddr)) + hostname2traddr(ctx, fctx->host_traddr, + &c->host_traddr); if (!c->host_traddr) - c->host_traddr = strdup(host_traddr); + c->host_traddr = strdup(fctx->host_traddr); } - if (host_iface) - c->host_iface = strdup(host_iface); - if (trsvcid) - c->trsvcid = strdup(trsvcid); + if (fctx->host_iface) + c->host_iface = strdup(fctx->host_iface); + if (fctx->trsvcid) + c->trsvcid = strdup(fctx->trsvcid); *cp = c; return 0; } +__public int nvme_create_ctrl(struct nvme_global_ctx *ctx, + const char *subsysnqn, const char *transport, + const char *traddr, const char *host_traddr, + const char *host_iface, const char *trsvcid, + nvme_ctrl_t *cp) +{ + struct nvmf_context fctx = { + .transport = transport, + .traddr = traddr, + .host_traddr = host_traddr, + .host_iface = host_iface, + .trsvcid = trsvcid, + .subsysnqn = subsysnqn, + }; + + return _nvme_create_ctrl(ctx, &fctx, cp); +} + /** * _tcp_ctrl_match_host_traddr_no_src_addr() - Match host_traddr w/o src_addr * @c: An existing controller instance @@ -1508,8 +1525,8 @@ nvme_ctrl_t nvme_lookup_ctrl(nvme_subsystem_t s, const char *transport, return c; ctx = s->h ? s->h->ctx : NULL; - ret = nvme_create_ctrl(ctx, s->subsysnqn, transport, traddr, - host_traddr, host_iface, trsvcid, &c); + fctx.subsysnqn = s->subsysnqn; + ret = _nvme_create_ctrl(ctx, &fctx, &c); if (ret) return NULL; From bdb48f0957485f250a3ffb1273f87f2b982c7299 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 19 Mar 2026 18:33:58 +0100 Subject: [PATCH 05/10] libnvme: use 'struct nvmf_context' as argument to nvmf_connect_disc_entry() To simplify the interface. Signed-off-by: Hannes Reinecke --- libnvme/src/nvme/fabrics.c | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/libnvme/src/nvme/fabrics.c b/libnvme/src/nvme/fabrics.c index 026a61ea15..0c7c1595ad 100644 --- a/libnvme/src/nvme/fabrics.c +++ b/libnvme/src/nvme/fabrics.c @@ -1098,14 +1098,10 @@ __public int nvmf_connect_ctrl(nvme_ctrl_t c) static int nvmf_connect_disc_entry(nvme_host_t h, struct nvmf_disc_log_entry *e, - const char *host_traddr, const char *host_iface, + struct nvmf_context *fctx, const struct nvme_fabrics_config *cfg, bool *discover, nvme_ctrl_t *cp) { - struct nvmf_context fctx = { - .host_traddr = host_traddr, - .host_iface = host_iface, - }; nvme_ctrl_t c; int ret; @@ -1115,8 +1111,8 @@ static int nvmf_connect_disc_entry(nvme_host_t h, switch (e->adrfam) { case NVMF_ADDR_FAMILY_IP4: case NVMF_ADDR_FAMILY_IP6: - fctx.traddr = e->traddr; - fctx.trsvcid = e->trsvcid; + fctx->traddr = e->traddr; + fctx->trsvcid = e->trsvcid; break; default: nvme_msg(h->ctx, LOG_ERR, @@ -1128,7 +1124,7 @@ static int nvmf_connect_disc_entry(nvme_host_t h, case NVMF_TRTYPE_FC: switch (e->adrfam) { case NVMF_ADDR_FAMILY_FC: - fctx.traddr = e->traddr; + fctx->traddr = e->traddr; break; default: nvme_msg(h->ctx, LOG_ERR, @@ -1138,7 +1134,7 @@ static int nvmf_connect_disc_entry(nvme_host_t h, } break; case NVMF_TRTYPE_LOOP: - fctx.traddr = strlen(e->traddr) ? e->traddr : NULL; + fctx->traddr = strlen(e->traddr) ? e->traddr : NULL; break; default: nvme_msg(h->ctx, LOG_ERR, "skipping unsupported transport %d\n", @@ -1146,18 +1142,18 @@ static int nvmf_connect_disc_entry(nvme_host_t h, return -EINVAL; } - fctx.transport = nvmf_trtype_str(e->trtype); - fctx.subsysnqn = e->subnqn; + fctx->transport = nvmf_trtype_str(e->trtype); + fctx->subsysnqn = e->subnqn; nvme_msg(h->ctx, LOG_DEBUG, "lookup ctrl " "(transport: %s, traddr: %s, trsvcid %s)\n", - fctx.transport, fctx.traddr, fctx.trsvcid); + fctx->transport, fctx->traddr, fctx->trsvcid); - ret = _nvme_create_ctrl(h->ctx, &fctx, &c); + ret = _nvme_create_ctrl(h->ctx, fctx, &c); if (ret) { nvme_msg(h->ctx, LOG_DEBUG, "skipping discovery entry, " "failed to allocate %s controller with traddr %s\n", - fctx.transport, fctx.traddr); + fctx->transport, fctx->traddr); return ret; } @@ -1996,8 +1992,7 @@ static int _nvmf_discovery(struct nvme_global_ctx *ctx, disconnect = false; } - err = nvmf_connect_disc_entry(h, e, nfctx.host_traddr, - nfctx.host_iface, nfctx.cfg, + err = nvmf_connect_disc_entry(h, e, &nfctx, nfctx.cfg, &discover, &child); nfctx.cfg->keep_alive_tmo = tmo; @@ -2648,8 +2643,7 @@ static int nbft_discovery(struct nvme_global_ctx *ctx, if (e->subtype == NVME_NQN_DISC) { nvme_ctrl_t child; - ret = nvmf_connect_disc_entry(h, e, - nfctx.host_traddr, nfctx.host_iface, + ret = nvmf_connect_disc_entry(h, e, &nfctx, defcfg, NULL, &child); if (ret) continue; From 0d3378fe3c546f3d0ec149379fbaa6f73cf0d6df Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 19 Mar 2026 18:45:42 +0100 Subject: [PATCH 06/10] libnvme: Introduct _nvme_ctrl_match_config() To simplify the interface. Signed-off-by: Hannes Reinecke --- libnvme/src/nvme/fabrics.c | 5 +---- libnvme/src/nvme/private.h | 1 + libnvme/src/nvme/tree.c | 18 ++++++++++++------ 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/libnvme/src/nvme/fabrics.c b/libnvme/src/nvme/fabrics.c index 0c7c1595ad..32a6e539b1 100644 --- a/libnvme/src/nvme/fabrics.c +++ b/libnvme/src/nvme/fabrics.c @@ -2925,10 +2925,7 @@ __public int nvmf_discovery(struct nvme_global_ctx *ctx, struct nvmf_context *fc ret = nvme_scan_ctrl(ctx, fctx->device, &c); if (!ret) { /* Check if device matches command-line options */ - if (!nvme_ctrl_match_config(c, fctx->transport, - fctx->traddr, fctx->trsvcid, - fctx->subsysnqn, fctx->host_traddr, - fctx->host_iface)) { + if (!_nvme_ctrl_match_config(c, fctx)) { nvme_msg(ctx, LOG_ERR, "ctrl device %s found, ignoring non matching command-line options\n", fctx->device); diff --git a/libnvme/src/nvme/private.h b/libnvme/src/nvme/private.h index 4ce55b24f9..79f3fb83cf 100644 --- a/libnvme/src/nvme/private.h +++ b/libnvme/src/nvme/private.h @@ -387,6 +387,7 @@ int _nvme_create_ctrl(struct nvme_global_ctx *ctx, nvme_ctrl_t __nvme_lookup_ctrl(nvme_subsystem_t s, struct nvmf_context *fctx, nvme_ctrl_t p); +bool _nvme_ctrl_match_config(struct nvme_ctrl *c, struct nvmf_context *fctx); void *__nvme_alloc(size_t len); diff --git a/libnvme/src/nvme/tree.c b/libnvme/src/nvme/tree.c index 2a7bd32f33..b05d58a04e 100644 --- a/libnvme/src/nvme/tree.c +++ b/libnvme/src/nvme/tree.c @@ -1472,13 +1472,22 @@ nvme_ctrl_t __nvme_lookup_ctrl(nvme_subsystem_t s, struct nvmf_context *fctx, return matching_c; } +bool _nvme_ctrl_match_config(struct nvme_ctrl *c, struct nvmf_context *fctx) +{ + struct candidate_args candidate = {}; + ctrl_match_t ctrl_match; + + /* Init candidate and get the matching function to use */ + ctrl_match = _candidate_init(c->ctx, &candidate, fctx); + + return ctrl_match(c, &candidate); +} + __public bool nvme_ctrl_match_config(struct nvme_ctrl *c, const char *transport, const char *traddr, const char *trsvcid, const char *subsysnqn, const char *host_traddr, const char *host_iface) { - struct candidate_args candidate = {}; - ctrl_match_t ctrl_match; struct nvmf_context fctx = { .transport = transport, .traddr = traddr, @@ -1488,10 +1497,7 @@ __public bool nvme_ctrl_match_config(struct nvme_ctrl *c, const char *transport, .subsysnqn = subsysnqn, }; - /* Init candidate and get the matching function to use */ - ctrl_match = _candidate_init(c->ctx, &candidate, &fctx); - - return ctrl_match(c, &candidate); + return _nvme_ctrl_match_config(c, &fctx); } nvme_ctrl_t nvme_ctrl_find(nvme_subsystem_t s, struct nvmf_context *fctx) From d9bd6ecb6aaae4f83a83c010bc15fd96fb0145f1 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 20 Mar 2026 08:42:56 +0100 Subject: [PATCH 07/10] libnvme: make __nvme_lookup_ctrl() static Replace with nvme_ctrl_find() and make it static to avoid function name clashes. Signed-off-by: Hannes Reinecke --- libnvme/src/nvme/fabrics.c | 4 ++-- libnvme/src/nvme/private.h | 3 --- libnvme/src/nvme/tree.c | 5 +++-- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/libnvme/src/nvme/fabrics.c b/libnvme/src/nvme/fabrics.c index 32a6e539b1..3a6625cbc5 100644 --- a/libnvme/src/nvme/fabrics.c +++ b/libnvme/src/nvme/fabrics.c @@ -976,7 +976,7 @@ static const char *lookup_context(struct nvme_global_ctx *ctx, nvme_ctrl_t c) .trsvcid = nvme_ctrl_get_trsvcid(c), .subsysnqn = NULL, }; - if (__nvme_lookup_ctrl(s, &fctx, NULL)) + if (nvme_ctrl_find(s, &fctx)) return nvme_subsystem_get_application(s); } } @@ -1008,7 +1008,7 @@ __public int nvmf_add_ctrl(nvme_host_t h, nvme_ctrl_t c, .subsysnqn = NULL, }; - fc = __nvme_lookup_ctrl(s, &fctx, NULL); + fc = nvme_ctrl_find(s, &fctx); if (fc) { const char *key; diff --git a/libnvme/src/nvme/private.h b/libnvme/src/nvme/private.h index 79f3fb83cf..604c3a5b7d 100644 --- a/libnvme/src/nvme/private.h +++ b/libnvme/src/nvme/private.h @@ -384,9 +384,6 @@ void __nvme_transport_handle_close_mi(struct nvme_transport_handle *hdl); int _nvme_create_ctrl(struct nvme_global_ctx *ctx, struct nvmf_context *fctx, nvme_ctrl_t *cp); -nvme_ctrl_t __nvme_lookup_ctrl(nvme_subsystem_t s, - struct nvmf_context *fctx, - nvme_ctrl_t p); bool _nvme_ctrl_match_config(struct nvme_ctrl *c, struct nvmf_context *fctx); void *__nvme_alloc(size_t len); diff --git a/libnvme/src/nvme/tree.c b/libnvme/src/nvme/tree.c index b05d58a04e..c67afe6cf0 100644 --- a/libnvme/src/nvme/tree.c +++ b/libnvme/src/nvme/tree.c @@ -1451,8 +1451,9 @@ static ctrl_match_t _candidate_init(struct nvme_global_ctx *ctx, return _match_ctrl; } -nvme_ctrl_t __nvme_lookup_ctrl(nvme_subsystem_t s, struct nvmf_context *fctx, - nvme_ctrl_t p) +static nvme_ctrl_t __nvme_lookup_ctrl(nvme_subsystem_t s, + struct nvmf_context *fctx, + nvme_ctrl_t p) { struct candidate_args candidate = {}; struct nvme_ctrl *c, *matching_c = NULL; From 8dc9df5f6483b8cc518fb8ad6e321c0be8a6c60c Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 20 Mar 2026 08:52:01 +0100 Subject: [PATCH 08/10] libnvme: Re-implement __nvme_lookup_ctrl() Re-implement __nvme_lookup_ctrl() as equivalent to nvme_lookup_ctrl() but taking 'struct nvmf_context' as argument. Care needs to be taken to handle the 'subsysnqn' entry in 'struct nvmf_context'; __nvme_ctrl_find() needs to be called with a 'NULL' subsysnqn as the controller might be on any subsystem, and we need to set 'subsysnqn' to the NQN of the subsystem the controller should be created in rather than the subsysnqn from 'struct nvmf_context' (which might be empty). Signed-off-by: Hannes Reinecke --- libnvme/src/nvme/fabrics.c | 4 +-- libnvme/src/nvme/json.c | 16 ++++----- libnvme/src/nvme/private.h | 3 ++ libnvme/src/nvme/tree.c | 72 +++++++++++++++++++++++++------------- 4 files changed, 59 insertions(+), 36 deletions(-) diff --git a/libnvme/src/nvme/fabrics.c b/libnvme/src/nvme/fabrics.c index 3a6625cbc5..3eac88e186 100644 --- a/libnvme/src/nvme/fabrics.c +++ b/libnvme/src/nvme/fabrics.c @@ -2425,9 +2425,7 @@ __public int nvmf_config_modify(struct nvme_global_ctx *ctx, return -ENODEV; } - c = nvme_lookup_ctrl(s, fctx->transport, fctx->traddr, - fctx->host_traddr, fctx->host_iface, - fctx->trsvcid, NULL); + c = __nvme_lookup_ctrl(s, fctx, NULL); if (!c) { nvme_msg(ctx, LOG_ERR, "Failed to lookup controller\n"); return -ENODEV; diff --git a/libnvme/src/nvme/json.c b/libnvme/src/nvme/json.c index 329c6e72ca..dbac69737e 100644 --- a/libnvme/src/nvme/json.c +++ b/libnvme/src/nvme/json.c @@ -83,27 +83,25 @@ static void json_parse_port(nvme_subsystem_t s, struct json_object *port_obj) { nvme_ctrl_t c; struct json_object *attr_obj; - const char *transport, *traddr = NULL; - const char *host_traddr = NULL, *host_iface = NULL, *trsvcid = NULL; + struct nvmf_context fctx = {}; attr_obj = json_object_object_get(port_obj, "transport"); if (!attr_obj) return; - transport = json_object_get_string(attr_obj); + fctx.transport = json_object_get_string(attr_obj); attr_obj = json_object_object_get(port_obj, "traddr"); if (attr_obj) - traddr = json_object_get_string(attr_obj); + fctx.traddr = json_object_get_string(attr_obj); attr_obj = json_object_object_get(port_obj, "host_traddr"); if (attr_obj) - host_traddr = json_object_get_string(attr_obj); + fctx.host_traddr = json_object_get_string(attr_obj); attr_obj = json_object_object_get(port_obj, "host_iface"); if (attr_obj) - host_iface = json_object_get_string(attr_obj); + fctx.host_iface = json_object_get_string(attr_obj); attr_obj = json_object_object_get(port_obj, "trsvcid"); if (attr_obj) - trsvcid = json_object_get_string(attr_obj); - c = nvme_lookup_ctrl(s, transport, traddr, host_traddr, - host_iface, trsvcid, NULL); + fctx.trsvcid = json_object_get_string(attr_obj); + c = __nvme_lookup_ctrl(s, &fctx, NULL); if (!c) return; json_update_attributes(c, port_obj); diff --git a/libnvme/src/nvme/private.h b/libnvme/src/nvme/private.h index 604c3a5b7d..a2b458bb80 100644 --- a/libnvme/src/nvme/private.h +++ b/libnvme/src/nvme/private.h @@ -399,6 +399,9 @@ nvme_ctrl_t nvme_lookup_ctrl(nvme_subsystem_t s, const char *transport, const char *traddr, const char *host_traddr, const char *host_iface, const char *trsvcid, nvme_ctrl_t p); +nvme_ctrl_t __nvme_lookup_ctrl(nvme_subsystem_t s, + struct nvmf_context *fctx, + nvme_ctrl_t p); nvme_ctrl_t nvme_ctrl_find(nvme_subsystem_t s, struct nvmf_context *fctx); void __nvme_free_host(nvme_host_t h); diff --git a/libnvme/src/nvme/tree.c b/libnvme/src/nvme/tree.c index c67afe6cf0..02aba37c1c 100644 --- a/libnvme/src/nvme/tree.c +++ b/libnvme/src/nvme/tree.c @@ -1451,9 +1451,9 @@ static ctrl_match_t _candidate_init(struct nvme_global_ctx *ctx, return _match_ctrl; } -static nvme_ctrl_t __nvme_lookup_ctrl(nvme_subsystem_t s, - struct nvmf_context *fctx, - nvme_ctrl_t p) +static nvme_ctrl_t __nvme_ctrl_find(nvme_subsystem_t s, + struct nvmf_context *fctx, + nvme_ctrl_t p) { struct candidate_args candidate = {}; struct nvme_ctrl *c, *matching_c = NULL; @@ -1503,37 +1503,35 @@ __public bool nvme_ctrl_match_config(struct nvme_ctrl *c, const char *transport, nvme_ctrl_t nvme_ctrl_find(nvme_subsystem_t s, struct nvmf_context *fctx) { - return __nvme_lookup_ctrl(s, fctx, NULL/*p*/); + return __nvme_ctrl_find(s, fctx, NULL/*p*/); } -nvme_ctrl_t nvme_lookup_ctrl(nvme_subsystem_t s, const char *transport, - const char *traddr, const char *host_traddr, - const char *host_iface, const char *trsvcid, - nvme_ctrl_t p) +nvme_ctrl_t __nvme_lookup_ctrl(nvme_subsystem_t s, + struct nvmf_context *fctx, + nvme_ctrl_t p) { struct nvme_global_ctx *ctx; struct nvme_ctrl *c; + const char *subsysnqn = fctx->subsysnqn; int ret; - if (!s || !transport) + if (!s || !fctx->transport) return NULL; - struct nvmf_context fctx = { - .transport = transport, - .traddr = traddr, - .host_traddr = host_traddr, - .host_iface = host_iface, - .trsvcid = trsvcid, - .subsysnqn = NULL, - }; - - c = __nvme_lookup_ctrl(s, &fctx, p); - if (c) + /* Clear out subsysnqn; might be different for discovery subsystems */ + fctx->subsysnqn = NULL; + c = __nvme_ctrl_find(s, fctx, p); + if (c) { + fctx->subsysnqn = subsysnqn; return c; + } ctx = s->h ? s->h->ctx : NULL; - fctx.subsysnqn = s->subsysnqn; - ret = _nvme_create_ctrl(ctx, &fctx, &c); + /* Set the NQN to the subsystem the controller should be created in */ + fctx->subsysnqn = s->subsysnqn; + ret = _nvme_create_ctrl(ctx, fctx, &c); + /* And restore NQN to avoid issues with repetitive calls */ + fctx->subsysnqn = subsysnqn; if (ret) return NULL; @@ -1543,6 +1541,26 @@ nvme_ctrl_t nvme_lookup_ctrl(nvme_subsystem_t s, const char *transport, return c; } +nvme_ctrl_t nvme_lookup_ctrl(nvme_subsystem_t s, const char *transport, + const char *traddr, const char *host_traddr, + const char *host_iface, const char *trsvcid, + nvme_ctrl_t p) +{ + if (!s || !transport) + return NULL; + + struct nvmf_context fctx = { + .transport = transport, + .traddr = traddr, + .host_traddr = host_traddr, + .host_iface = host_iface, + .trsvcid = trsvcid, + .subsysnqn = NULL, + }; + + return __nvme_lookup_ctrl(s, &fctx, p); +} + static int nvme_ctrl_scan_paths(struct nvme_global_ctx *ctx, struct nvme_ctrl *c) { _cleanup_dirents_ struct dirents paths = {}; @@ -1893,8 +1911,14 @@ int nvme_ctrl_alloc(struct nvme_global_ctx *ctx, nvme_subsystem_t s, skip_address: p = NULL; do { - c = nvme_lookup_ctrl(s, transport, traddr, - host_traddr, host_iface, trsvcid, p); + struct nvmf_context fctx = { + .transport = transport, + .traddr = traddr, + .host_traddr = host_traddr, + .host_iface = host_iface, + .trsvcid = trsvcid, + }; + c = __nvme_lookup_ctrl(s, &fctx, p); if (c) { if (!c->name) break; From 96d24954ecb8400a689623f3109fbdf15ae9eab7 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 20 Mar 2026 13:27:20 +0100 Subject: [PATCH 09/10] libnvme: convert test/tree.c to 'struct nvmf_context' Use 'struct nvmf_context' throughout the file to test the new interface. Signed-off-by: Hannes Reinecke --- libnvme/test/tree.c | 220 +++++++++++++++++++++++--------------------- 1 file changed, 113 insertions(+), 107 deletions(-) diff --git a/libnvme/test/tree.c b/libnvme/test/tree.c index 862afa3f03..86aae7808f 100644 --- a/libnvme/test/tree.c +++ b/libnvme/test/tree.c @@ -17,15 +17,8 @@ struct test_data { /* input data */ - const char *hostnqn; - const char *hostid; + struct nvmf_context f; const char *subsysname; - const char *subsysnqn; - const char *transport; - const char *traddr; - const char *host_traddr; - const char *host_iface; - const char *trsvcid; /* track controller generated by input data */ nvme_subsystem_t s; @@ -40,22 +33,27 @@ struct test_data { #define SRC_ADDR4 "192.168.56.100" #define SRC_ADDR6 "1234:5678:abcd:EF01:1234:5678:abcd:EF01" -#define DEFAULTS DEFAULT_HOSTNQN, DEFAULT_HOSTNQN, DEFAULT_SUBSYSNAME, DEFAULT_SUBSYSNQN +#define DEFAULTS(t, a, h, i, s) \ + .f = { .hostnqn = DEFAULT_HOSTNQN, \ + .subsysnqn = DEFAULT_SUBSYSNQN, \ + .transport = (t), .traddr = (a), .host_traddr = (h), \ + .host_iface = (i), .trsvcid = (s), }, \ + .subsysname = DEFAULT_SUBSYSNAME struct test_data test_data[] = { - { DEFAULTS, "tcp", "192.168.1.1", "192.168.1.20", NULL, "4420" }, - { DEFAULTS, "tcp", "192.168.1.1", "192.168.1.20", NULL, "4421" }, - { DEFAULTS, "tcp", "192.168.1.2", "192.168.1.20", "eth1", "4420" }, - { DEFAULTS, "tcp", "192.168.1.2", "192.168.1.20", "eth1", "4421" }, - { DEFAULTS, "rdma", "192.168.1.3", "192.168.1.20", NULL, NULL }, - { DEFAULTS, "rdma", "192.168.1.4", "192.168.1.20", NULL, NULL }, - { DEFAULTS, "fc", - "nn-0x201700a09890f5bf:pn-0x201900a09890f5bf", - "nn-0x200000109b579ef3:pn-0x100000109b579ef3" + { DEFAULTS("tcp", "192.168.1.1", "192.168.1.20", NULL, "4420") }, + { DEFAULTS("tcp", "192.168.1.1", "192.168.1.20", NULL, "4421") }, + { DEFAULTS("tcp", "192.168.1.2", "192.168.1.20", "eth1", "4420") }, + { DEFAULTS("tcp", "192.168.1.2", "192.168.1.20", "eth1", "4421") }, + { DEFAULTS("rdma", "192.168.1.3", "192.168.1.20", NULL, NULL) }, + { DEFAULTS("rdma", "192.168.1.4", "192.168.1.20", NULL, NULL) }, + { DEFAULTS("fc", + "nn-0x201700a09890f5bf:pn-0x201900a09890f5bf", + "nn-0x200000109b579ef3:pn-0x100000109b579ef3", NULL, NULL) }, - { DEFAULTS, "fc", - "nn-0x201700a09890f5bf:pn-0x201900a09890f5bf", - "nn-0x200000109b579ef6:pn-0x100000109b579ef6", + { DEFAULTS("fc", + "nn-0x201700a09890f5bf:pn-0x201900a09890f5bf", + "nn-0x200000109b579ef6:pn-0x100000109b579ef6", NULL, NULL) }, }; @@ -80,8 +78,9 @@ static void show_ctrl(nvme_ctrl_t c) else printf(" "); - printf("0x%p: %s %s %s %s %s ", + printf("0x%p: %s %s %s %s %s %s", c, + nvme_ctrl_get_subsysnqn(c), nvme_ctrl_get_transport(c), nvme_ctrl_get_traddr(c), nvme_ctrl_get_host_traddr(c), @@ -97,26 +96,26 @@ static bool match_ctrl(struct test_data *d, nvme_ctrl_t c) if (d->c != c) pass = false; - if (strcmp(d->transport, nvme_ctrl_get_transport(d->c))) + if (strcmp(d->f.transport, nvme_ctrl_get_transport(d->c))) pass = false; - if (strcmp(d->traddr, nvme_ctrl_get_traddr(d->c))) + if (strcmp(d->f.traddr, nvme_ctrl_get_traddr(d->c))) pass = false; host_traddr = nvme_ctrl_get_host_traddr(c); - if (d->host_traddr && - (!host_traddr || strcmp(d->host_traddr, host_traddr))) + if (d->f.host_traddr && + (!host_traddr || strcmp(d->f.host_traddr, host_traddr))) pass = false; host_iface = nvme_ctrl_get_host_iface(c); - if (d->host_iface && - (!host_iface || strcmp(d->host_iface, host_iface))) + if (d->f.host_iface && + (!host_iface || strcmp(d->f.host_iface, host_iface))) pass = false; trsvid = nvme_ctrl_get_trsvcid(c); - if (d->trsvcid && - (!trsvid || strcmp(d->trsvcid, trsvid))) + if (d->f.trsvcid && + (!trsvid || strcmp(d->f.trsvcid, trsvid))) pass = false; printf("[%s]", pass? "PASS" : "FAILED"); @@ -139,11 +138,9 @@ static struct nvme_global_ctx *create_tree() struct test_data *d = &test_data[i]; assert(!nvme_get_subsystem(ctx, h, d->subsysname, - d->subsysnqn, &d->s)); + d->f.subsysnqn, &d->s)); assert(d->s); - d->c = nvme_lookup_ctrl(d->s, d->transport, d->traddr, - d->host_traddr, d->host_iface, - d->trsvcid, NULL); + d->c = __nvme_lookup_ctrl(d->s, &d->f, NULL); assert(d->c); d->ctrl_id = i; @@ -176,36 +173,41 @@ static bool tcp_ctrl_lookup(nvme_subsystem_t s, struct test_data *d) { nvme_ctrl_t c; bool pass = true; + struct nvmf_context f = d->f; - c = nvme_lookup_ctrl(s, d->transport, d->traddr, NULL, - NULL, d->trsvcid, NULL); - printf("%10s %12s %10s -> ", d->trsvcid, "", ""); + f.host_traddr = NULL; + f.host_iface = NULL; + c = __nvme_lookup_ctrl(s, &f, NULL); + printf("%10s %12s %10s -> ", f.trsvcid, "", ""); show_ctrl(c); pass &= match_ctrl(d, c); printf("\n"); - if (d->host_traddr) { - c = nvme_lookup_ctrl(s, d->transport, d->traddr, d->host_traddr, - NULL, d->trsvcid, NULL); - printf("%10s %12s %10s -> ", d->trsvcid, d->host_traddr, ""); + if (d->f.host_traddr) { + f = d->f; + f.host_iface = NULL; + c = __nvme_lookup_ctrl(s, &f, NULL); + printf("%10s %12s %10s -> ", f.trsvcid, f.host_traddr, ""); show_ctrl(c); pass &= match_ctrl(d, c); printf("\n"); } - if (d->host_iface) { - c = nvme_lookup_ctrl(s, d->transport, d->traddr, NULL, - d->host_iface, d->trsvcid, NULL); - printf("%10s %12s %10s -> ", d->trsvcid, "", d->host_iface); + if (d->f.host_iface) { + f = d->f; + f.host_traddr = NULL; + c = __nvme_lookup_ctrl(s, &f, NULL); + printf("%10s %12s %10s -> ", f.trsvcid, "", f.host_iface); show_ctrl(c); pass &= match_ctrl(d, c); printf("\n"); } - if (d->host_iface && d->traddr) { - c = nvme_lookup_ctrl(s, d->transport, d->traddr, d->host_traddr, - d->host_iface, d->trsvcid, NULL); - printf("%10s %12s %10s -> ", d->trsvcid, d->host_traddr, d->host_iface); + if (d->f.host_iface && d->f.traddr) { + f = d->f; + c = __nvme_lookup_ctrl(s, &f, NULL); + printf("%10s %12s %10s -> ", f.trsvcid, + f.host_traddr, f.host_iface); show_ctrl(c); pass &= match_ctrl(d, c); printf("\n"); @@ -218,9 +220,11 @@ static bool default_ctrl_lookup(nvme_subsystem_t s, struct test_data *d) { nvme_ctrl_t c; bool pass = true; + struct nvmf_context f = d->f; - c = nvme_lookup_ctrl(s, d->transport, d->traddr, d->host_traddr, - NULL, NULL, NULL); + f.host_iface = NULL; + f.trsvcid = NULL; + c = __nvme_lookup_ctrl(s, &f, NULL); printf("%10s %12s %10s -> ", "", "", ""); show_ctrl(c); pass &= match_ctrl(d, c); @@ -246,7 +250,7 @@ static bool ctrl_lookups(struct nvme_global_ctx *ctx) show_ctrl(d->c); printf("\n"); - if (!strcmp("tcp", d->transport)) + if (!strcmp("tcp", d->f.transport)) pass &= tcp_ctrl_lookup(s, d); else pass &= default_ctrl_lookup(s, d); @@ -276,6 +280,13 @@ static bool test_lookup(void) static bool test_src_addr() { struct nvme_global_ctx *ctx; + struct nvmf_context fctx = { + .transport = "tcp", + .traddr = "192.168.56.1", + .host_traddr = NULL, + .host_iface = NULL, + .trsvcid = "8009", + }; bool pass = true; nvme_host_t h; nvme_ctrl_t c; @@ -294,7 +305,7 @@ static bool test_src_addr() nvme_get_subsystem(ctx, h, DEFAULT_SUBSYSNAME, DEFAULT_SUBSYSNQN, &s); assert(s); - c = nvme_lookup_ctrl(s, "tcp", "192.168.56.1", NULL, NULL, "8009", NULL); + c = __nvme_lookup_ctrl(s, &fctx, NULL); assert(c); c->address = NULL; @@ -420,13 +431,8 @@ static bool test_src_addr() } struct ctrl_args { - const char *transport; - const char *traddr; - const char *trsvcid; - const char *host_traddr; - const char *host_iface; + struct nvmf_context f; const char *address; - const char *subsysnqn; }; static void set_ctrl_args(struct ctrl_args *args, @@ -438,13 +444,13 @@ static void set_ctrl_args(struct ctrl_args *args, const char *address, const char *subsysnqn) { - args->transport = transport; - args->traddr = traddr; - args->trsvcid = trsvcid; - args->host_traddr = host_traddr; - args->host_iface = host_iface; + args->f.transport = transport; + args->f.traddr = traddr; + args->f.trsvcid = trsvcid; + args->f.host_traddr = host_traddr; + args->f.host_iface = host_iface; args->address = address; - args->subsysnqn = subsysnqn; + args->f.subsysnqn = subsysnqn; } static bool ctrl_match(const char *tag, @@ -455,14 +461,6 @@ static bool ctrl_match(const char *tag, bool should_match) { struct nvme_global_ctx *ctx; - struct nvmf_context fctx = { - .transport = candidate->transport, - .traddr = candidate->traddr, - .host_traddr = candidate->host_traddr, - .host_iface = candidate->host_iface, - .trsvcid = candidate->trsvcid, - .subsysnqn = candidate->subsysnqn, - }; nvme_host_t h; nvme_ctrl_t reference_ctrl; /* Existing controller (from sysfs) */ nvme_ctrl_t candidate_ctrl; @@ -476,14 +474,12 @@ static bool ctrl_match(const char *tag, assert(h); assert(!nvme_get_subsystem(ctx, h, DEFAULT_SUBSYSNAME, - reference->subsysnqn ? - reference->subsysnqn : DEFAULT_SUBSYSNQN, + reference->f.subsysnqn ? + reference->f.subsysnqn : DEFAULT_SUBSYSNQN, &s)); assert(s); - reference_ctrl = nvme_lookup_ctrl(s, reference->transport, reference->traddr, - reference->host_traddr, reference->host_iface, - reference->trsvcid, NULL); + reference_ctrl = __nvme_lookup_ctrl(s, &reference->f, NULL); assert(reference_ctrl); reference_ctrl->name = "nvme1"; /* fake the device name */ if (reference->address) { @@ -491,46 +487,57 @@ static bool ctrl_match(const char *tag, } /* nvme_ctrl_find() MUST BE RUN BEFORE nvme_lookup_ctrl() */ - found_ctrl = nvme_ctrl_find(s, &fctx); + found_ctrl = nvme_ctrl_find(s, &candidate->f); - candidate_ctrl = nvme_lookup_ctrl(s, candidate->transport, candidate->traddr, - candidate->host_traddr, candidate->host_iface, - candidate->trsvcid, NULL); + candidate_ctrl = __nvme_lookup_ctrl(s, &candidate->f, NULL); if (should_match) { if (candidate_ctrl != reference_ctrl) { printf("%s-%d-%d: Candidate (%s, %s, %s, %s, %s, %s) failed to match (%s, %s, %s, %s, %s, %s, %s)\n", tag, reference_id, candidate_id, - candidate->transport, candidate->traddr, candidate->trsvcid, - candidate->subsysnqn, candidate->host_traddr, candidate->host_iface, - reference->transport, reference->traddr, reference->trsvcid, reference->subsysnqn, - reference->host_traddr, reference->host_iface, reference->address); + candidate->f.transport, candidate->f.traddr, + candidate->f.trsvcid, candidate->f.subsysnqn, + candidate->f.host_traddr, + candidate->f.host_iface, + reference->f.transport, reference->f.traddr, + reference->f.trsvcid, reference->f.subsysnqn, + reference->f.host_traddr, + reference->f.host_iface, reference->address); return false; } if (!found_ctrl) { printf("%s-%d-%d: Candidate (%s, %s, %s, %s, %s, %s) failed to find controller\n", tag, reference_id, candidate_id, - candidate->transport, candidate->traddr, candidate->trsvcid, - candidate->subsysnqn, candidate->host_traddr, candidate->host_iface); + candidate->f.transport, candidate->f.traddr, + candidate->f.trsvcid, candidate->f.subsysnqn, + candidate->f.host_traddr, + candidate->f.host_iface); return false; } } else { if (candidate_ctrl == reference_ctrl) { printf("%s-%d-%d: Candidate (%s, %s, %s, %s, %s, %s) should not match (%s, %s, %s, %s, %s, %s, %s)\n", tag, reference_id, candidate_id, - candidate->transport, candidate->traddr, candidate->trsvcid, - candidate->subsysnqn, candidate->host_traddr, candidate->host_iface, - reference->transport, reference->traddr, reference->trsvcid, reference->subsysnqn, - reference->host_traddr, reference->host_iface, reference->address); + candidate->f.transport, candidate->f.traddr, + candidate->f.trsvcid, candidate->f.subsysnqn, + candidate->f.host_traddr, + candidate->f.host_iface, + reference->f.transport, reference->f.traddr, + reference->f.trsvcid, reference->f.subsysnqn, + reference->f.host_traddr, + reference->f.host_iface, reference->address); return false; } if (found_ctrl) { printf("%s-%d-%d: Candidate (%s, %s, %s, %s, %s, %s) should not have found controller. found_ctrl=%p reference=%p\n", tag, reference_id, candidate_id, - candidate->transport, candidate->traddr, candidate->trsvcid, candidate->subsysnqn, - candidate->host_traddr, candidate->host_iface, found_ctrl, reference_ctrl); + candidate->f.transport, candidate->f.traddr, + candidate->f.trsvcid, candidate->f.subsysnqn, + candidate->f.host_traddr, + candidate->f.host_iface, + found_ctrl, reference_ctrl); return false; } } @@ -1089,39 +1096,38 @@ static bool ctrl_config_match(const char *tag, assert(h); assert(!nvme_get_subsystem(ctx, h, DEFAULT_SUBSYSNAME, - reference->subsysnqn ? - reference->subsysnqn : DEFAULT_SUBSYSNQN, + reference->f.subsysnqn ? + reference->f.subsysnqn : DEFAULT_SUBSYSNQN, &s)); assert(s); - reference_ctrl = nvme_lookup_ctrl(s, reference->transport, reference->traddr, - reference->host_traddr, reference->host_iface, - reference->trsvcid, NULL); + reference_ctrl = __nvme_lookup_ctrl(s, &reference->f, NULL); assert(reference_ctrl); reference_ctrl->name = "nvme1"; /* fake the device name */ if (reference->address) { reference_ctrl->address = (char *)reference->address; } - match = nvme_ctrl_match_config(reference_ctrl, - candidate->transport, candidate->traddr, - candidate->trsvcid, candidate->subsysnqn, - candidate->host_traddr, candidate->host_iface); + match = _nvme_ctrl_match_config(reference_ctrl, &candidate->f); if (should_match) { if (!match) { printf("%s-%d-%d: Failed to match config for Candidate (%s, %s, %s, %s, %s, %s)\n", tag, reference_id, candidate_id, - candidate->transport, candidate->traddr, candidate->trsvcid, - candidate->subsysnqn, candidate->host_traddr, candidate->host_iface); + candidate->f.transport, candidate->f.traddr, + candidate->f.trsvcid, candidate->f.subsysnqn, + candidate->f.host_traddr, + candidate->f.host_iface); return false; } } else { if (match) { printf("%s-%d-%d: Config should not have matched for Candidate (%s, %s, %s, %s, %s, %s)\n", tag, reference_id, candidate_id, - candidate->transport, candidate->traddr, candidate->trsvcid, - candidate->subsysnqn, candidate->host_traddr, candidate->host_iface); + candidate->f.transport, candidate->f.traddr, + candidate->f.trsvcid, candidate->f.subsysnqn, + candidate->f.host_traddr, + candidate->f.host_iface); return false; } } From b866e4889eac85d0de549974d3ccaf1f00353d40 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 20 Mar 2026 13:35:45 +0100 Subject: [PATCH 10/10] libnvme: Drop __nvme_lookup_ctrl() All functions have been converted to the new interface, so rename __nvme_lookup_ctrl() to nvme_lookup_ctrl() and drop the wrapper. Signed-off-by: Hannes Reinecke --- libnvme/src/nvme/fabrics.c | 2 +- libnvme/src/nvme/json.c | 2 +- libnvme/src/nvme/private.h | 8 ++------ libnvme/src/nvme/tree.c | 28 ++++------------------------ libnvme/test/tree.c | 20 ++++++++++---------- 5 files changed, 18 insertions(+), 42 deletions(-) diff --git a/libnvme/src/nvme/fabrics.c b/libnvme/src/nvme/fabrics.c index 3eac88e186..129aa134d3 100644 --- a/libnvme/src/nvme/fabrics.c +++ b/libnvme/src/nvme/fabrics.c @@ -2425,7 +2425,7 @@ __public int nvmf_config_modify(struct nvme_global_ctx *ctx, return -ENODEV; } - c = __nvme_lookup_ctrl(s, fctx, NULL); + c = nvme_lookup_ctrl(s, fctx, NULL); if (!c) { nvme_msg(ctx, LOG_ERR, "Failed to lookup controller\n"); return -ENODEV; diff --git a/libnvme/src/nvme/json.c b/libnvme/src/nvme/json.c index dbac69737e..f42f3a26e2 100644 --- a/libnvme/src/nvme/json.c +++ b/libnvme/src/nvme/json.c @@ -101,7 +101,7 @@ static void json_parse_port(nvme_subsystem_t s, struct json_object *port_obj) attr_obj = json_object_object_get(port_obj, "trsvcid"); if (attr_obj) fctx.trsvcid = json_object_get_string(attr_obj); - c = __nvme_lookup_ctrl(s, &fctx, NULL); + c = nvme_lookup_ctrl(s, &fctx, NULL); if (!c) return; json_update_attributes(c, port_obj); diff --git a/libnvme/src/nvme/private.h b/libnvme/src/nvme/private.h index a2b458bb80..1f92efbc19 100644 --- a/libnvme/src/nvme/private.h +++ b/libnvme/src/nvme/private.h @@ -395,13 +395,9 @@ nvme_host_t nvme_lookup_host(struct nvme_global_ctx *ctx, const char *hostnqn, nvme_subsystem_t nvme_lookup_subsystem(struct nvme_host *h, const char *name, const char *subsysnqn); -nvme_ctrl_t nvme_lookup_ctrl(nvme_subsystem_t s, const char *transport, - const char *traddr, const char *host_traddr, - const char *host_iface, const char *trsvcid, +nvme_ctrl_t nvme_lookup_ctrl(nvme_subsystem_t s, + struct nvmf_context *fctx, nvme_ctrl_t p); -nvme_ctrl_t __nvme_lookup_ctrl(nvme_subsystem_t s, - struct nvmf_context *fctx, - nvme_ctrl_t p); nvme_ctrl_t nvme_ctrl_find(nvme_subsystem_t s, struct nvmf_context *fctx); void __nvme_free_host(nvme_host_t h); diff --git a/libnvme/src/nvme/tree.c b/libnvme/src/nvme/tree.c index 02aba37c1c..010dd3ce93 100644 --- a/libnvme/src/nvme/tree.c +++ b/libnvme/src/nvme/tree.c @@ -1506,9 +1506,9 @@ nvme_ctrl_t nvme_ctrl_find(nvme_subsystem_t s, struct nvmf_context *fctx) return __nvme_ctrl_find(s, fctx, NULL/*p*/); } -nvme_ctrl_t __nvme_lookup_ctrl(nvme_subsystem_t s, - struct nvmf_context *fctx, - nvme_ctrl_t p) +nvme_ctrl_t nvme_lookup_ctrl(nvme_subsystem_t s, + struct nvmf_context *fctx, + nvme_ctrl_t p) { struct nvme_global_ctx *ctx; struct nvme_ctrl *c; @@ -1541,26 +1541,6 @@ nvme_ctrl_t __nvme_lookup_ctrl(nvme_subsystem_t s, return c; } -nvme_ctrl_t nvme_lookup_ctrl(nvme_subsystem_t s, const char *transport, - const char *traddr, const char *host_traddr, - const char *host_iface, const char *trsvcid, - nvme_ctrl_t p) -{ - if (!s || !transport) - return NULL; - - struct nvmf_context fctx = { - .transport = transport, - .traddr = traddr, - .host_traddr = host_traddr, - .host_iface = host_iface, - .trsvcid = trsvcid, - .subsysnqn = NULL, - }; - - return __nvme_lookup_ctrl(s, &fctx, p); -} - static int nvme_ctrl_scan_paths(struct nvme_global_ctx *ctx, struct nvme_ctrl *c) { _cleanup_dirents_ struct dirents paths = {}; @@ -1918,7 +1898,7 @@ int nvme_ctrl_alloc(struct nvme_global_ctx *ctx, nvme_subsystem_t s, .host_iface = host_iface, .trsvcid = trsvcid, }; - c = __nvme_lookup_ctrl(s, &fctx, p); + c = nvme_lookup_ctrl(s, &fctx, p); if (c) { if (!c->name) break; diff --git a/libnvme/test/tree.c b/libnvme/test/tree.c index 86aae7808f..6bb23a2b7b 100644 --- a/libnvme/test/tree.c +++ b/libnvme/test/tree.c @@ -140,7 +140,7 @@ static struct nvme_global_ctx *create_tree() assert(!nvme_get_subsystem(ctx, h, d->subsysname, d->f.subsysnqn, &d->s)); assert(d->s); - d->c = __nvme_lookup_ctrl(d->s, &d->f, NULL); + d->c = nvme_lookup_ctrl(d->s, &d->f, NULL); assert(d->c); d->ctrl_id = i; @@ -177,7 +177,7 @@ static bool tcp_ctrl_lookup(nvme_subsystem_t s, struct test_data *d) f.host_traddr = NULL; f.host_iface = NULL; - c = __nvme_lookup_ctrl(s, &f, NULL); + c = nvme_lookup_ctrl(s, &f, NULL); printf("%10s %12s %10s -> ", f.trsvcid, "", ""); show_ctrl(c); pass &= match_ctrl(d, c); @@ -186,7 +186,7 @@ static bool tcp_ctrl_lookup(nvme_subsystem_t s, struct test_data *d) if (d->f.host_traddr) { f = d->f; f.host_iface = NULL; - c = __nvme_lookup_ctrl(s, &f, NULL); + c = nvme_lookup_ctrl(s, &f, NULL); printf("%10s %12s %10s -> ", f.trsvcid, f.host_traddr, ""); show_ctrl(c); pass &= match_ctrl(d, c); @@ -196,7 +196,7 @@ static bool tcp_ctrl_lookup(nvme_subsystem_t s, struct test_data *d) if (d->f.host_iface) { f = d->f; f.host_traddr = NULL; - c = __nvme_lookup_ctrl(s, &f, NULL); + c = nvme_lookup_ctrl(s, &f, NULL); printf("%10s %12s %10s -> ", f.trsvcid, "", f.host_iface); show_ctrl(c); pass &= match_ctrl(d, c); @@ -205,7 +205,7 @@ static bool tcp_ctrl_lookup(nvme_subsystem_t s, struct test_data *d) if (d->f.host_iface && d->f.traddr) { f = d->f; - c = __nvme_lookup_ctrl(s, &f, NULL); + c = nvme_lookup_ctrl(s, &f, NULL); printf("%10s %12s %10s -> ", f.trsvcid, f.host_traddr, f.host_iface); show_ctrl(c); @@ -224,7 +224,7 @@ static bool default_ctrl_lookup(nvme_subsystem_t s, struct test_data *d) f.host_iface = NULL; f.trsvcid = NULL; - c = __nvme_lookup_ctrl(s, &f, NULL); + c = nvme_lookup_ctrl(s, &f, NULL); printf("%10s %12s %10s -> ", "", "", ""); show_ctrl(c); pass &= match_ctrl(d, c); @@ -305,7 +305,7 @@ static bool test_src_addr() nvme_get_subsystem(ctx, h, DEFAULT_SUBSYSNAME, DEFAULT_SUBSYSNQN, &s); assert(s); - c = __nvme_lookup_ctrl(s, &fctx, NULL); + c = nvme_lookup_ctrl(s, &fctx, NULL); assert(c); c->address = NULL; @@ -479,7 +479,7 @@ static bool ctrl_match(const char *tag, &s)); assert(s); - reference_ctrl = __nvme_lookup_ctrl(s, &reference->f, NULL); + reference_ctrl = nvme_lookup_ctrl(s, &reference->f, NULL); assert(reference_ctrl); reference_ctrl->name = "nvme1"; /* fake the device name */ if (reference->address) { @@ -489,7 +489,7 @@ static bool ctrl_match(const char *tag, /* nvme_ctrl_find() MUST BE RUN BEFORE nvme_lookup_ctrl() */ found_ctrl = nvme_ctrl_find(s, &candidate->f); - candidate_ctrl = __nvme_lookup_ctrl(s, &candidate->f, NULL); + candidate_ctrl = nvme_lookup_ctrl(s, &candidate->f, NULL); if (should_match) { if (candidate_ctrl != reference_ctrl) { @@ -1101,7 +1101,7 @@ static bool ctrl_config_match(const char *tag, &s)); assert(s); - reference_ctrl = __nvme_lookup_ctrl(s, &reference->f, NULL); + reference_ctrl = nvme_lookup_ctrl(s, &reference->f, NULL); assert(reference_ctrl); reference_ctrl->name = "nvme1"; /* fake the device name */ if (reference->address) {