lib/nvmf:add spdk_nvmf_transport_stop_listen_async API.
This API differs from spdk_nvmf_tranpsort_stop_listen in that it also disconnects the qpairs associated with that listener. Change-Id: Iadfc6d2debc0ef8f1a8cd5db4f20168aeae8264d Signed-off-by: Seth Howell <seth.howell@intel.com> Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/3279 Community-CI: Mellanox Build Bot Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
parent
8bff48f63c
commit
49ee92a61f
@ -117,7 +117,9 @@ struct spdk_nvmf_transport_poll_group_stat {
|
||||
};
|
||||
|
||||
/**
|
||||
* Function to be called once the listener is associated with a subsystem.
|
||||
* Function to be called once asynchronous listen add and remove
|
||||
* operations are completed. See spdk_nvmf_subsystem_add_listener()
|
||||
* and spdk_nvmf_transport_stop_listen_async().
|
||||
*
|
||||
* \param ctx Context argument passed to this function.
|
||||
* \param status 0 if it completed successfully, or negative errno if it failed.
|
||||
@ -994,6 +996,26 @@ int
|
||||
spdk_nvmf_transport_stop_listen(struct spdk_nvmf_transport *transport,
|
||||
const struct spdk_nvme_transport_id *trid);
|
||||
|
||||
/**
|
||||
* Stop accepting new connections at the provided address.
|
||||
*
|
||||
* This is a counterpart to spdk_nvmf_tgt_listen(). It differs
|
||||
* from spdk_nvmf_transport_stop_listen() in that it also destroys all
|
||||
* 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 cb_fn The function to call on completion.
|
||||
* \param cb_arg The argument to pass to the cb_fn.
|
||||
*
|
||||
* \return int. 0 when the asynchronous process starts successfully or a negated errno on failure.
|
||||
*/
|
||||
int spdk_nvmf_transport_stop_listen_async(struct spdk_nvmf_transport *transport,
|
||||
const struct spdk_nvme_transport_id *trid,
|
||||
spdk_nvmf_tgt_subsystem_listen_done_fn cb_fn,
|
||||
void *cb_arg);
|
||||
|
||||
/**
|
||||
* \brief Get current transport poll group statistics.
|
||||
*
|
||||
|
@ -35,7 +35,7 @@ SPDK_ROOT_DIR := $(abspath $(CURDIR)/../..)
|
||||
include $(SPDK_ROOT_DIR)/mk/spdk.common.mk
|
||||
|
||||
SO_VER := 5
|
||||
SO_MINOR := 0
|
||||
SO_MINOR := 1
|
||||
|
||||
C_SRCS = ctrlr.c ctrlr_discovery.c ctrlr_bdev.c \
|
||||
subsystem.c nvmf.c nvmf_rpc.c transport.c tcp.c
|
||||
|
@ -75,6 +75,7 @@
|
||||
spdk_nvmf_tgt_add_transport;
|
||||
spdk_nvmf_transport_listen;
|
||||
spdk_nvmf_transport_stop_listen;
|
||||
spdk_nvmf_transport_stop_listen_async;
|
||||
spdk_nvmf_transport_poll_group_get_stat;
|
||||
spdk_nvmf_transport_poll_group_free_stat;
|
||||
spdk_nvmf_rdma_init_hooks;
|
||||
|
@ -254,6 +254,85 @@ spdk_nvmf_transport_stop_listen(struct spdk_nvmf_transport *transport,
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct nvmf_stop_listen_ctx {
|
||||
struct spdk_nvmf_transport *transport;
|
||||
struct spdk_nvme_transport_id trid;
|
||||
spdk_nvmf_tgt_subsystem_listen_done_fn cb_fn;
|
||||
void *cb_arg;
|
||||
};
|
||||
|
||||
static void
|
||||
nvmf_stop_listen_fini(struct spdk_io_channel_iter *i, int status)
|
||||
{
|
||||
struct nvmf_stop_listen_ctx *ctx;
|
||||
struct spdk_nvmf_transport *transport;
|
||||
int rc = status;
|
||||
|
||||
ctx = spdk_io_channel_iter_get_ctx(i);
|
||||
transport = ctx->transport;
|
||||
assert(transport != NULL);
|
||||
|
||||
rc = spdk_nvmf_transport_stop_listen(transport, &ctx->trid);
|
||||
if (rc) {
|
||||
SPDK_ERRLOG("Failed to stop listening on address '%s'\n", ctx->trid.traddr);
|
||||
}
|
||||
|
||||
if (ctx->cb_fn) {
|
||||
ctx->cb_fn(ctx->cb_arg, rc);
|
||||
}
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
nvmf_stop_listen_disconnect_qpairs(struct spdk_io_channel_iter *i)
|
||||
{
|
||||
struct nvmf_stop_listen_ctx *ctx;
|
||||
struct spdk_nvmf_poll_group *group;
|
||||
struct spdk_io_channel *ch;
|
||||
struct spdk_nvmf_qpair *qpair, *tmp_qpair;
|
||||
struct spdk_nvme_transport_id tmp_trid;
|
||||
|
||||
ctx = spdk_io_channel_iter_get_ctx(i);
|
||||
ch = spdk_io_channel_iter_get_channel(i);
|
||||
group = spdk_io_channel_get_ctx(ch);
|
||||
|
||||
TAILQ_FOREACH_SAFE(qpair, &group->qpairs, link, tmp_qpair) {
|
||||
/* skip qpairs that don't match the TRID. */
|
||||
if (spdk_nvmf_qpair_get_listen_trid(qpair, &tmp_trid)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!spdk_nvme_transport_id_compare(&ctx->trid, &tmp_trid)) {
|
||||
spdk_nvmf_qpair_disconnect(qpair, NULL, NULL);
|
||||
}
|
||||
}
|
||||
spdk_for_each_channel_continue(i, 0);
|
||||
}
|
||||
|
||||
int
|
||||
spdk_nvmf_transport_stop_listen_async(struct spdk_nvmf_transport *transport,
|
||||
const struct spdk_nvme_transport_id *trid,
|
||||
spdk_nvmf_tgt_subsystem_listen_done_fn cb_fn,
|
||||
void *cb_arg)
|
||||
{
|
||||
struct nvmf_stop_listen_ctx *ctx;
|
||||
|
||||
ctx = calloc(1, sizeof(struct nvmf_stop_listen_ctx));
|
||||
if (ctx == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ctx->trid = *trid;
|
||||
ctx->transport = transport;
|
||||
ctx->cb_fn = cb_fn;
|
||||
ctx->cb_arg = cb_arg;
|
||||
|
||||
spdk_for_each_channel(transport->tgt, nvmf_stop_listen_disconnect_qpairs, ctx,
|
||||
nvmf_stop_listen_fini);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
nvmf_transport_accept(struct spdk_nvmf_transport *transport)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user