nvmf: fix disconnect logic for remove_listener RPC

Currently if we remove a listener from a subsystem, we
disconnect *all* qpairs that have the same transport ID
as the listener being removed.

Fix that, since we should only disconnect qpairs from
controllers associated with the subsystem that had the
listener removed.

Signed-off-by: Jim Harris <james.r.harris@intel.com>
Change-Id: I6cf7422d14f23bf02ba6c4b034b172870694b3e6
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/10690
Community-CI: Mellanox Build Bot
Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com>
This commit is contained in:
Jim Harris 2021-12-08 10:22:24 +00:00 committed by Tomasz Zawadzki
parent ef8f297ba4
commit 79727986e0
4 changed files with 19 additions and 4 deletions

View File

@ -40,6 +40,11 @@ they did not account for PCI devices being inserted or removed while the caller
returned from these APIs. Existing users of these APIs should switch to spdk_pci_for_each_device
instead.
### nvmf
Added a 'subsystem' parameter to spdk_nvmf_transport_stop_listen_async. When not NULL,
it will only disconnect qpairs for controllers associated with the specified subsystem.
## v21.10
Structure `spdk_nvmf_target_opts` has been extended with new member `discovery_filter` which allows to specify

View File

@ -1109,12 +1109,15 @@ spdk_nvmf_transport_stop_listen(struct spdk_nvmf_transport *transport,
* Stop accepting new connections at the provided address.
*
* This is a counterpart to spdk_nvmf_tgt_listen_ext(). It differs
* from spdk_nvmf_transport_stop_listen() in that it also destroys all
* from spdk_nvmf_transport_stop_listen() in that it also destroys
* qpairs that are connected to the specified listener. Because
* this function disconnects the qpairs, it has to be asynchronous.
*
* \param transport The transport associated with the listen address.
* \param trid The address to stop listening at.
* \param subsystem The subsystem to match for qpairs with the specified
* trid. If NULL, it will disconnect all qpairs with the
* specified trid.
* \param cb_fn The function to call on completion.
* \param cb_arg The argument to pass to the cb_fn.
*
@ -1122,6 +1125,7 @@ spdk_nvmf_transport_stop_listen(struct spdk_nvmf_transport *transport,
*/
int spdk_nvmf_transport_stop_listen_async(struct spdk_nvmf_transport *transport,
const struct spdk_nvme_transport_id *trid,
struct spdk_nvmf_subsystem *subsystem,
spdk_nvmf_tgt_subsystem_listen_done_fn cb_fn,
void *cb_arg);

View File

@ -792,8 +792,8 @@ nvmf_rpc_listen_paused(struct spdk_nvmf_subsystem *subsystem,
} else if (ctx->op == NVMF_RPC_LISTEN_REMOVE) {
rc = spdk_nvmf_subsystem_remove_listener(subsystem, &ctx->trid);
if (rc == 0) {
spdk_nvmf_transport_stop_listen_async(ctx->transport, &ctx->trid, nvmf_rpc_stop_listen_async_done,
ctx);
spdk_nvmf_transport_stop_listen_async(ctx->transport, &ctx->trid, subsystem,
nvmf_rpc_stop_listen_async_done, ctx);
return;
}
SPDK_ERRLOG("Unable to remove listener, rc %d\n", rc);

View File

@ -363,6 +363,7 @@ spdk_nvmf_transport_stop_listen(struct spdk_nvmf_transport *transport,
struct nvmf_stop_listen_ctx {
struct spdk_nvmf_transport *transport;
struct spdk_nvme_transport_id trid;
struct spdk_nvmf_subsystem *subsystem;
spdk_nvmf_tgt_subsystem_listen_done_fn cb_fn;
void *cb_arg;
};
@ -409,7 +410,10 @@ nvmf_stop_listen_disconnect_qpairs(struct spdk_io_channel_iter *i)
}
if (!spdk_nvme_transport_id_compare(&ctx->trid, &tmp_trid)) {
spdk_nvmf_qpair_disconnect(qpair, NULL, NULL);
if (ctx->subsystem == NULL ||
ctx->subsystem == qpair->ctrlr->subsys) {
spdk_nvmf_qpair_disconnect(qpair, NULL, NULL);
}
}
}
spdk_for_each_channel_continue(i, 0);
@ -418,6 +422,7 @@ nvmf_stop_listen_disconnect_qpairs(struct spdk_io_channel_iter *i)
int
spdk_nvmf_transport_stop_listen_async(struct spdk_nvmf_transport *transport,
const struct spdk_nvme_transport_id *trid,
struct spdk_nvmf_subsystem *subsystem,
spdk_nvmf_tgt_subsystem_listen_done_fn cb_fn,
void *cb_arg)
{
@ -429,6 +434,7 @@ spdk_nvmf_transport_stop_listen_async(struct spdk_nvmf_transport *transport,
}
ctx->trid = *trid;
ctx->subsystem = subsystem;
ctx->transport = transport;
ctx->cb_fn = cb_fn;
ctx->cb_arg = cb_arg;