nvmf: Add spdk_nvmf_subsystem_disconnect_host
This will disconnect all connections to a subsystem from a given host identified by HOSTNQN. Change-Id: Ibc9cea1f08a58a05dbac3a0bb47df8d8a58e7c10 Signed-off-by: Ben Walker <benjamin.walker@intel.com> Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4556 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com> Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
This commit is contained in:
parent
ce594c1e43
commit
5efa3d61ff
@ -484,6 +484,25 @@ int spdk_nvmf_subsystem_add_host(struct spdk_nvmf_subsystem *subsystem,
|
|||||||
*/
|
*/
|
||||||
int spdk_nvmf_subsystem_remove_host(struct spdk_nvmf_subsystem *subsystem, const char *hostnqn);
|
int spdk_nvmf_subsystem_remove_host(struct spdk_nvmf_subsystem *subsystem, const char *hostnqn);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disconnect all connections originating from the provided hostnqn
|
||||||
|
*
|
||||||
|
* To disconnect and block all new connections from a host, first call
|
||||||
|
* spdk_nvmf_subsystem_remove_host() to remove it from the list of allowed hosts, then
|
||||||
|
* call spdk_nvmf_subsystem_disconnect_host() to close any remaining connections.
|
||||||
|
*
|
||||||
|
* \param subsystem Subsystem to operate on
|
||||||
|
* \param hostnqn The NQN for the host
|
||||||
|
* \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_subsystem_disconnect_host(struct spdk_nvmf_subsystem *subsystem,
|
||||||
|
const char *hostnqn,
|
||||||
|
spdk_nvmf_tgt_subsystem_listen_done_fn cb_fn,
|
||||||
|
void *cb_arg);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set whether a subsystem should allow any host or only hosts in the allowed list.
|
* Set whether a subsystem should allow any host or only hosts in the allowed list.
|
||||||
*
|
*
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
spdk_nvmf_subsystem_get_next;
|
spdk_nvmf_subsystem_get_next;
|
||||||
spdk_nvmf_subsystem_add_host;
|
spdk_nvmf_subsystem_add_host;
|
||||||
spdk_nvmf_subsystem_remove_host;
|
spdk_nvmf_subsystem_remove_host;
|
||||||
|
spdk_nvmf_subsystem_disconnect_host;
|
||||||
spdk_nvmf_subsystem_set_allow_any_host;
|
spdk_nvmf_subsystem_set_allow_any_host;
|
||||||
spdk_nvmf_subsystem_get_allow_any_host;
|
spdk_nvmf_subsystem_get_allow_any_host;
|
||||||
spdk_nvmf_subsystem_host_allowed;
|
spdk_nvmf_subsystem_host_allowed;
|
||||||
|
@ -760,6 +760,79 @@ spdk_nvmf_subsystem_remove_host(struct spdk_nvmf_subsystem *subsystem, const cha
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct nvmf_subsystem_disconnect_host_ctx {
|
||||||
|
struct spdk_nvmf_subsystem *subsystem;
|
||||||
|
char *hostnqn;
|
||||||
|
spdk_nvmf_tgt_subsystem_listen_done_fn cb_fn;
|
||||||
|
void *cb_arg;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
nvmf_subsystem_disconnect_host_fini(struct spdk_io_channel_iter *i, int status)
|
||||||
|
{
|
||||||
|
struct nvmf_subsystem_disconnect_host_ctx *ctx;
|
||||||
|
|
||||||
|
ctx = spdk_io_channel_iter_get_ctx(i);
|
||||||
|
|
||||||
|
if (ctx->cb_fn) {
|
||||||
|
ctx->cb_fn(ctx->cb_arg, status);
|
||||||
|
}
|
||||||
|
free(ctx->hostnqn);
|
||||||
|
free(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nvmf_subsystem_disconnect_qpairs_by_host(struct spdk_io_channel_iter *i)
|
||||||
|
{
|
||||||
|
struct nvmf_subsystem_disconnect_host_ctx *ctx;
|
||||||
|
struct spdk_nvmf_poll_group *group;
|
||||||
|
struct spdk_io_channel *ch;
|
||||||
|
struct spdk_nvmf_qpair *qpair, *tmp_qpair;
|
||||||
|
struct spdk_nvmf_ctrlr *ctrlr;
|
||||||
|
|
||||||
|
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) {
|
||||||
|
ctrlr = qpair->ctrlr;
|
||||||
|
|
||||||
|
if (ctrlr == NULL || ctrlr->subsys != ctx->subsystem) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strncmp(ctrlr->hostnqn, ctx->hostnqn, sizeof(ctrlr->hostnqn)) == 0) {
|
||||||
|
/* Right now this does not wait for the queue pairs to actually disconnect. */
|
||||||
|
spdk_nvmf_qpair_disconnect(qpair, NULL, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
spdk_for_each_channel_continue(i, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
spdk_nvmf_subsystem_disconnect_host(struct spdk_nvmf_subsystem *subsystem,
|
||||||
|
const char *hostnqn,
|
||||||
|
spdk_nvmf_tgt_subsystem_listen_done_fn cb_fn,
|
||||||
|
void *cb_arg)
|
||||||
|
{
|
||||||
|
struct nvmf_subsystem_disconnect_host_ctx *ctx;
|
||||||
|
|
||||||
|
ctx = calloc(1, sizeof(struct nvmf_subsystem_disconnect_host_ctx));
|
||||||
|
if (ctx == NULL) {
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->subsystem = subsystem;
|
||||||
|
ctx->hostnqn = strdup(hostnqn);
|
||||||
|
ctx->cb_fn = cb_fn;
|
||||||
|
ctx->cb_arg = cb_arg;
|
||||||
|
|
||||||
|
spdk_for_each_channel(subsystem->tgt, nvmf_subsystem_disconnect_qpairs_by_host, ctx,
|
||||||
|
nvmf_subsystem_disconnect_host_fini);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
spdk_nvmf_subsystem_set_allow_any_host(struct spdk_nvmf_subsystem *subsystem, bool allow_any_host)
|
spdk_nvmf_subsystem_set_allow_any_host(struct spdk_nvmf_subsystem *subsystem, bool allow_any_host)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user