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 ctx Context argument passed to this function.
|
||||||
* \param status 0 if it completed successfully, or negative errno if it failed.
|
* \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,
|
spdk_nvmf_transport_stop_listen(struct spdk_nvmf_transport *transport,
|
||||||
const struct spdk_nvme_transport_id *trid);
|
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.
|
* \brief Get current transport poll group statistics.
|
||||||
*
|
*
|
||||||
|
@ -35,7 +35,7 @@ SPDK_ROOT_DIR := $(abspath $(CURDIR)/../..)
|
|||||||
include $(SPDK_ROOT_DIR)/mk/spdk.common.mk
|
include $(SPDK_ROOT_DIR)/mk/spdk.common.mk
|
||||||
|
|
||||||
SO_VER := 5
|
SO_VER := 5
|
||||||
SO_MINOR := 0
|
SO_MINOR := 1
|
||||||
|
|
||||||
C_SRCS = ctrlr.c ctrlr_discovery.c ctrlr_bdev.c \
|
C_SRCS = ctrlr.c ctrlr_discovery.c ctrlr_bdev.c \
|
||||||
subsystem.c nvmf.c nvmf_rpc.c transport.c tcp.c
|
subsystem.c nvmf.c nvmf_rpc.c transport.c tcp.c
|
||||||
|
@ -75,6 +75,7 @@
|
|||||||
spdk_nvmf_tgt_add_transport;
|
spdk_nvmf_tgt_add_transport;
|
||||||
spdk_nvmf_transport_listen;
|
spdk_nvmf_transport_listen;
|
||||||
spdk_nvmf_transport_stop_listen;
|
spdk_nvmf_transport_stop_listen;
|
||||||
|
spdk_nvmf_transport_stop_listen_async;
|
||||||
spdk_nvmf_transport_poll_group_get_stat;
|
spdk_nvmf_transport_poll_group_get_stat;
|
||||||
spdk_nvmf_transport_poll_group_free_stat;
|
spdk_nvmf_transport_poll_group_free_stat;
|
||||||
spdk_nvmf_rdma_init_hooks;
|
spdk_nvmf_rdma_init_hooks;
|
||||||
|
@ -254,6 +254,85 @@ spdk_nvmf_transport_stop_listen(struct spdk_nvmf_transport *transport,
|
|||||||
return 0;
|
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
|
uint32_t
|
||||||
nvmf_transport_accept(struct spdk_nvmf_transport *transport)
|
nvmf_transport_accept(struct spdk_nvmf_transport *transport)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user