From be774bf6640bbf907d911a9f6d6e7184b56349ce Mon Sep 17 00:00:00 2001 From: Ben Walker Date: Wed, 17 Jan 2018 15:33:27 -0700 Subject: [PATCH] nvmf: Check subsystem state when modifying listeners or hosts Change-Id: Idadd4eb7574b005cce8b888b28c8c3b6993343a4 Signed-off-by: Ben Walker Reviewed-on: https://review.gerrithub.io/395555 Tested-by: SPDK Automated Test System Reviewed-by: Jim Harris Reviewed-by: Daniel Verkamp --- include/spdk/nvmf.h | 13 ++++++++++++- lib/nvmf/subsystem.c | 40 ++++++++++++++++++++++++++++++++-------- 2 files changed, 44 insertions(+), 9 deletions(-) diff --git a/include/spdk/nvmf.h b/include/spdk/nvmf.h index 355f77c66..0132033b6 100644 --- a/include/spdk/nvmf.h +++ b/include/spdk/nvmf.h @@ -239,6 +239,8 @@ struct spdk_nvmf_subsystem *spdk_nvmf_subsystem_get_next(struct spdk_nvmf_subsys /** * Allow the given host NQN to connect to the given subsystem. * + * May only be performed on subsystems in the PAUSED or INACTIVE states. + * * \param subsystem Subsystem to add host to * \param host_nqn The NQN for the host * \return 0 on success. Negated errno value on failure. @@ -249,11 +251,14 @@ int spdk_nvmf_subsystem_add_host(struct spdk_nvmf_subsystem *subsystem, /** * Set whether a subsystem should allow any host or only hosts in the allowed list. * + * May only be performed on subsystems in the PAUSED or INACTIVE states. + * * \param subsystem Subsystem to modify. * \param allow_any_host true to allow any host to connect to this subsystem, or false to enforce * the whitelist configured with spdk_nvmf_subsystem_add_host(). + * \return 0 on success. Negated errno value on failure. */ -void spdk_nvmf_subsystem_set_allow_any_host(struct spdk_nvmf_subsystem *subsystem, +int spdk_nvmf_subsystem_set_allow_any_host(struct spdk_nvmf_subsystem *subsystem, bool allow_any_host); /** @@ -303,6 +308,8 @@ const char *spdk_nvmf_host_get_nqn(struct spdk_nvmf_host *host); /** * Accept new connections on the address provided * + * May only be performed on subsystems in the PAUSED or INACTIVE states. + * * \param subsystem Subsystem to add listener to * \param trid The address to accept connections from * \return 0 on success. Negated errno value on failure. @@ -352,6 +359,8 @@ const struct spdk_nvme_transport_id *spdk_nvmf_listener_get_trid( /** * Add a namespace to a subsytem. * + * May only be performed on subsystems in the PAUSED or INACTIVE states. + * * \param subsystem Subsystem to add namespace to. * \param bdev Block device to add as a namespace. * \param nsid Namespace ID to assign to the new namespace, or 0 to automatically use an available @@ -365,6 +374,8 @@ uint32_t spdk_nvmf_subsystem_add_ns(struct spdk_nvmf_subsystem *subsystem, struc /** * Remove a namespace from a subsytem. * + * May only be performed on subsystems in the PAUSED or INACTIVE states. + * * \param subsystem Subsystem the namespace belong to. * \param nsid Namespace ID to be removed. * diff --git a/lib/nvmf/subsystem.c b/lib/nvmf/subsystem.c index 6b7d3dd4d..e66ea7868 100644 --- a/lib/nvmf/subsystem.c +++ b/lib/nvmf/subsystem.c @@ -564,17 +564,22 @@ spdk_nvmf_subsystem_add_host(struct spdk_nvmf_subsystem *subsystem, const char * struct spdk_nvmf_host *host; if (!spdk_nvmf_valid_nqn(hostnqn)) { - return -1; + return -EINVAL; + } + + if (!(subsystem->state == SPDK_NVMF_SUBSYSTEM_INACTIVE || + subsystem->state == SPDK_NVMF_SUBSYSTEM_PAUSED)) { + return -EAGAIN; } host = calloc(1, sizeof(*host)); if (!host) { - return -1; + return -ENOMEM; } host->nqn = strdup(hostnqn); if (!host->nqn) { free(host); - return -1; + return -ENOMEM; } TAILQ_INSERT_HEAD(&subsystem->hosts, host, link); @@ -583,10 +588,17 @@ spdk_nvmf_subsystem_add_host(struct spdk_nvmf_subsystem *subsystem, const char * return 0; } -void +int spdk_nvmf_subsystem_set_allow_any_host(struct spdk_nvmf_subsystem *subsystem, bool allow_any_host) { + if (!(subsystem->state == SPDK_NVMF_SUBSYSTEM_INACTIVE || + subsystem->state == SPDK_NVMF_SUBSYSTEM_PAUSED)) { + return -EAGAIN; + } + subsystem->allow_any_host = allow_any_host; + + return 0; } bool @@ -644,15 +656,20 @@ spdk_nvmf_subsystem_add_listener(struct spdk_nvmf_subsystem *subsystem, struct spdk_nvmf_transport *transport; struct spdk_nvmf_listener *listener; + if (!(subsystem->state == SPDK_NVMF_SUBSYSTEM_INACTIVE || + subsystem->state == SPDK_NVMF_SUBSYSTEM_PAUSED)) { + return -EAGAIN; + } + transport = spdk_nvmf_tgt_get_transport(subsystem->tgt, trid->trtype); if (transport == NULL) { SPDK_ERRLOG("Unknown transport type %d\n", trid->trtype); - return -1; + return -EINVAL; } listener = calloc(1, sizeof(*listener)); if (!listener) { - return -1; + return -ENOMEM; } listener->trid = *trid; @@ -717,6 +734,11 @@ spdk_nvmf_subsystem_remove_ns(struct spdk_nvmf_subsystem *subsystem, uint32_t ns return -1; } + if (!(subsystem->state == SPDK_NVMF_SUBSYSTEM_INACTIVE || + subsystem->state == SPDK_NVMF_SUBSYSTEM_PAUSED)) { + return -1; + } + ns = &subsystem->ns[nsid - 1]; if (ns->allocated == false) { return -1; @@ -760,8 +782,10 @@ spdk_nvmf_subsystem_add_ns(struct spdk_nvmf_subsystem *subsystem, struct spdk_bd uint32_t i; int rc; - assert(subsystem->state == SPDK_NVMF_SUBSYSTEM_INACTIVE || - subsystem->state == SPDK_NVMF_SUBSYSTEM_PAUSED); + if (!(subsystem->state == SPDK_NVMF_SUBSYSTEM_INACTIVE || + subsystem->state == SPDK_NVMF_SUBSYSTEM_PAUSED)) { + return 0; + } if (nsid == SPDK_NVME_GLOBAL_NS_TAG) { SPDK_ERRLOG("Invalid NSID %" PRIu32 "\n", nsid);