From 95ac75aabe34458230beb123223cd14a4de1226d Mon Sep 17 00:00:00 2001 From: Ben Walker Date: Tue, 19 Dec 2017 16:39:04 -0700 Subject: [PATCH] nvmf: Add synchronization primitives for subsystems This allows the user to pause a subsystem, make some modifications, and then resume it. Change-Id: Ia18371023d8fc66e1797fda293a01b68c0a61c96 Signed-off-by: Ben Walker Reviewed-on: https://review.gerrithub.io/392422 Tested-by: SPDK Automated Test System Reviewed-by: Daniel Verkamp Reviewed-by: Jim Harris --- app/nvmf_tgt/conf.c | 31 +- app/nvmf_tgt/nvmf_rpc.c | 76 ++-- app/nvmf_tgt/nvmf_tgt.c | 62 +++- app/nvmf_tgt/nvmf_tgt.h | 11 +- include/spdk/nvmf.h | 82 ++++- lib/nvmf/nvmf.c | 173 ++++++--- lib/nvmf/nvmf_internal.h | 26 +- lib/nvmf/subsystem.c | 347 +++++++++++------- .../ctrlr_discovery.c/ctrlr_discovery_ut.c | 13 +- test/unit/lib/nvmf/subsystem.c/subsystem_ut.c | 19 +- 10 files changed, 570 insertions(+), 270 deletions(-) diff --git a/app/nvmf_tgt/conf.c b/app/nvmf_tgt/conf.c index ca5661a06d..7aafabcdfc 100644 --- a/app/nvmf_tgt/conf.c +++ b/app/nvmf_tgt/conf.c @@ -160,6 +160,7 @@ spdk_nvmf_parse_subsystem(struct spdk_conf_section *sp) const char *sn; size_t num_ns; struct spdk_nvmf_ns_params ns_list[MAX_NAMESPACES] = {}; + struct spdk_nvmf_subsystem *subsystem; nqn = spdk_conf_section_get_val(sp, "NQN"); mode = spdk_conf_section_get_val(sp, "Mode"); @@ -258,17 +259,17 @@ spdk_nvmf_parse_subsystem(struct spdk_conf_section *sp) num_ns++; } - ret = spdk_nvmf_construct_subsystem(nqn, - num_listen_addrs, listen_addrs, - num_hosts, hosts, allow_any_host, - sn, - num_ns, ns_list); + subsystem = spdk_nvmf_construct_subsystem(nqn, + num_listen_addrs, listen_addrs, + num_hosts, hosts, allow_any_host, + sn, + num_ns, ns_list); for (i = 0; i < MAX_LISTEN_ADDRESSES; i++) { free(listen_addrs_str[i]); } - return ret; + return (subsystem != NULL); } static int @@ -310,8 +311,8 @@ spdk_nvmf_parse_conf(void) return 0; } -int -spdk_nvmf_construct_subsystem(const char *name, +struct spdk_nvmf_subsystem * + spdk_nvmf_construct_subsystem(const char *name, int num_listen_addresses, struct rpc_listen_address *addresses, int num_hosts, char *hosts[], bool allow_any_host, const char *sn, size_t num_ns, struct spdk_nvmf_ns_params *ns_list) @@ -323,23 +324,23 @@ spdk_nvmf_construct_subsystem(const char *name, if (name == NULL) { SPDK_ERRLOG("No NQN specified for subsystem\n"); - return -1; + return NULL; } if (num_listen_addresses > MAX_LISTEN_ADDRESSES) { SPDK_ERRLOG("invalid listen adresses number\n"); - return -1; + return NULL; } if (num_hosts > MAX_HOSTS) { SPDK_ERRLOG("invalid hosts number\n"); - return -1; + return NULL; } subsystem = nvmf_tgt_create_subsystem(name, SPDK_NVMF_SUBTYPE_NVME, num_ns); if (subsystem == NULL) { SPDK_ERRLOG("Subsystem creation failed\n"); - return -1; + return NULL; } /* Parse Listen sections */ @@ -409,9 +410,9 @@ spdk_nvmf_construct_subsystem(const char *name, } - return 0; + return subsystem; error: - spdk_nvmf_delete_subsystem(subsystem); - return -1; + spdk_nvmf_subsystem_destroy(subsystem); + return NULL; } diff --git a/app/nvmf_tgt/nvmf_rpc.c b/app/nvmf_tgt/nvmf_rpc.c index 3d70ba74fc..6fe6d519a2 100644 --- a/app/nvmf_tgt/nvmf_rpc.c +++ b/app/nvmf_tgt/nvmf_rpc.c @@ -333,6 +333,22 @@ free_rpc_subsystem(struct rpc_subsystem *req) free_rpc_hosts(&req->hosts); } +static void +spdk_rpc_nvmf_subsystem_started(struct spdk_nvmf_subsystem *subsystem, + void *cb_arg, int status) +{ + struct spdk_jsonrpc_request *request = cb_arg; + struct spdk_json_write_ctx *w; + + w = spdk_jsonrpc_begin_result(request); + if (w == NULL) { + return; + } + + spdk_json_write_bool(w, true); + spdk_jsonrpc_end_result(request, w); +} + static const struct spdk_json_object_decoder rpc_subsystem_decoders[] = { {"core", offsetof(struct rpc_subsystem, core), spdk_json_decode_int32, true}, {"mode", offsetof(struct rpc_subsystem, mode), spdk_json_decode_string, true}, @@ -349,8 +365,7 @@ spdk_rpc_construct_nvmf_subsystem(struct spdk_jsonrpc_request *request, const struct spdk_json_val *params) { struct rpc_subsystem req = {}; - struct spdk_json_write_ctx *w; - int ret; + struct spdk_nvmf_subsystem *subsystem; req.core = -1; /* Explicitly set the core as the uninitialized value */ if (spdk_json_decode_object(params, rpc_subsystem_decoders, @@ -384,25 +399,23 @@ spdk_rpc_construct_nvmf_subsystem(struct spdk_jsonrpc_request *request, SPDK_NOTICELOG("Ignoring it and continuing.\n"); } - ret = spdk_nvmf_construct_subsystem(req.nqn, - req.listen_addresses.num_listen_address, - req.listen_addresses.addresses, - req.hosts.num_hosts, req.hosts.hosts, req.allow_any_host, - req.serial_number, - req.namespaces.num_ns, req.namespaces.ns_params); - if (ret) { + subsystem = spdk_nvmf_construct_subsystem(req.nqn, + req.listen_addresses.num_listen_address, + req.listen_addresses.addresses, + req.hosts.num_hosts, req.hosts.hosts, req.allow_any_host, + req.serial_number, + req.namespaces.num_ns, req.namespaces.ns_params); + if (!subsystem) { goto invalid; } free_rpc_subsystem(&req); - w = spdk_jsonrpc_begin_result(request); - if (w == NULL) { - return; - } - spdk_json_write_bool(w, true); - spdk_jsonrpc_end_result(request, w); + spdk_nvmf_subsystem_start(subsystem, + spdk_rpc_nvmf_subsystem_started, + request); + return; invalid: @@ -421,6 +434,24 @@ free_rpc_delete_subsystem(struct rpc_delete_subsystem *r) free(r->nqn); } +static void +spdk_rpc_nvmf_subsystem_stopped(struct spdk_nvmf_subsystem *subsystem, + void *cb_arg, int status) +{ + struct spdk_jsonrpc_request *request = cb_arg; + struct spdk_json_write_ctx *w; + + spdk_nvmf_subsystem_destroy(subsystem); + + w = spdk_jsonrpc_begin_result(request); + if (w == NULL) { + return; + } + + spdk_json_write_bool(w, true); + spdk_jsonrpc_end_result(request, w); +} + static const struct spdk_json_object_decoder rpc_delete_subsystem_decoders[] = { {"nqn", offsetof(struct rpc_delete_subsystem, nqn), spdk_json_decode_string}, }; @@ -430,7 +461,7 @@ spdk_rpc_delete_nvmf_subsystem(struct spdk_jsonrpc_request *request, const struct spdk_json_val *params) { struct rpc_delete_subsystem req = {}; - struct spdk_json_write_ctx *w; + struct spdk_nvmf_subsystem *subsystem; if (spdk_json_decode_object(params, rpc_delete_subsystem_decoders, SPDK_COUNTOF(rpc_delete_subsystem_decoders), @@ -444,20 +475,17 @@ spdk_rpc_delete_nvmf_subsystem(struct spdk_jsonrpc_request *request, goto invalid; } - if (nvmf_tgt_shutdown_subsystem_by_nqn(req.nqn)) { - SPDK_ERRLOG("shutdown_subsystem failed\n"); + subsystem = spdk_nvmf_tgt_find_subsystem(g_tgt.tgt, req.nqn); + if (!subsystem) { goto invalid; } free_rpc_delete_subsystem(&req); - w = spdk_jsonrpc_begin_result(request); - if (w == NULL) { - return; - } + spdk_nvmf_subsystem_stop(subsystem, + spdk_rpc_nvmf_subsystem_stopped, + request); - spdk_json_write_bool(w, true); - spdk_jsonrpc_end_result(request, w); return; invalid: diff --git a/app/nvmf_tgt/nvmf_tgt.c b/app/nvmf_tgt/nvmf_tgt.c index 8546d67b5a..5d92865488 100644 --- a/app/nvmf_tgt/nvmf_tgt.c +++ b/app/nvmf_tgt/nvmf_tgt.c @@ -99,7 +99,7 @@ nvmf_tgt_create_subsystem(const char *name, enum spdk_nvmf_subtype subtype, uint return NULL; } - subsystem = spdk_nvmf_create_subsystem(g_tgt.tgt, name, subtype, num_ns); + subsystem = spdk_nvmf_subsystem_create(g_tgt.tgt, name, subtype, num_ns); if (subsystem == NULL) { SPDK_ERRLOG("Subsystem creation failed\n"); return NULL; @@ -120,7 +120,7 @@ nvmf_tgt_shutdown_subsystem_by_nqn(const char *nqn) return -EINVAL; } - spdk_nvmf_delete_subsystem(subsystem); + spdk_nvmf_subsystem_destroy(subsystem); return 0; } @@ -187,7 +187,7 @@ nvmf_tgt_destroy_poll_group(void *ctx) static void nvmf_tgt_create_poll_group_done(void *ctx) { - g_tgt.state = NVMF_TGT_INIT_START_ACCEPTOR; + g_tgt.state = NVMF_TGT_INIT_START_SUBSYSTEMS; nvmf_tgt_advance_state(NULL, NULL); } @@ -207,6 +207,36 @@ nvmf_tgt_create_poll_group(void *ctx) g_active_poll_groups++; } +static void +nvmf_tgt_subsystem_started(struct spdk_nvmf_subsystem *subsystem, + void *cb_arg, int status) +{ + subsystem = spdk_nvmf_subsystem_get_next(subsystem); + + if (subsystem) { + spdk_nvmf_subsystem_start(subsystem, nvmf_tgt_subsystem_started, NULL); + return; + } + + g_tgt.state = NVMF_TGT_INIT_START_ACCEPTOR; + nvmf_tgt_advance_state(NULL, NULL); +} + +static void +nvmf_tgt_subsystem_stopped(struct spdk_nvmf_subsystem *subsystem, + void *cb_arg, int status) +{ + subsystem = spdk_nvmf_subsystem_get_next(subsystem); + + if (subsystem) { + spdk_nvmf_subsystem_stop(subsystem, nvmf_tgt_subsystem_stopped, NULL); + return; + } + + g_tgt.state = NVMF_TGT_FINI_DESTROY_POLL_GROUPS; + nvmf_tgt_advance_state(NULL, NULL); +} + static void nvmf_tgt_advance_state(void *arg1, void *arg2) { @@ -254,6 +284,18 @@ nvmf_tgt_advance_state(void *arg1, void *arg2) NULL, nvmf_tgt_create_poll_group_done); break; + case NVMF_TGT_INIT_START_SUBSYSTEMS: { + struct spdk_nvmf_subsystem *subsystem; + + subsystem = spdk_nvmf_subsystem_get_first(g_tgt.tgt); + + if (subsystem) { + spdk_nvmf_subsystem_start(subsystem, nvmf_tgt_subsystem_started, NULL); + } else { + g_tgt.state = NVMF_TGT_INIT_START_ACCEPTOR; + } + break; + } case NVMF_TGT_INIT_START_ACCEPTOR: g_acceptor_poller = spdk_poller_register(acceptor_poll, g_tgt.tgt, g_spdk_nvmf_tgt_conf.acceptor_poll_rate); @@ -268,8 +310,20 @@ nvmf_tgt_advance_state(void *arg1, void *arg2) break; case NVMF_TGT_FINI_STOP_ACCEPTOR: spdk_poller_unregister(&g_acceptor_poller); - g_tgt.state = NVMF_TGT_FINI_DESTROY_POLL_GROUPS; + g_tgt.state = NVMF_TGT_FINI_STOP_SUBSYSTEMS; break; + case NVMF_TGT_FINI_STOP_SUBSYSTEMS: { + struct spdk_nvmf_subsystem *subsystem; + + subsystem = spdk_nvmf_subsystem_get_first(g_tgt.tgt); + + if (subsystem) { + spdk_nvmf_subsystem_stop(subsystem, nvmf_tgt_subsystem_stopped, NULL); + } else { + g_tgt.state = NVMF_TGT_FINI_DESTROY_POLL_GROUPS; + } + break; + } case NVMF_TGT_FINI_DESTROY_POLL_GROUPS: /* Send a message to each thread and destroy the poll group */ spdk_for_each_thread(nvmf_tgt_destroy_poll_group, diff --git a/app/nvmf_tgt/nvmf_tgt.h b/app/nvmf_tgt/nvmf_tgt.h index 3581919662..b54a4931ab 100644 --- a/app/nvmf_tgt/nvmf_tgt.h +++ b/app/nvmf_tgt/nvmf_tgt.h @@ -55,10 +55,12 @@ enum nvmf_tgt_state { NVMF_TGT_INIT_NONE = 0, NVMF_TGT_INIT_PARSE_CONFIG, NVMF_TGT_INIT_CREATE_POLL_GROUPS, + NVMF_TGT_INIT_START_SUBSYSTEMS, NVMF_TGT_INIT_START_ACCEPTOR, NVMF_TGT_RUNNING, NVMF_TGT_FINI_STOP_ACCEPTOR, NVMF_TGT_FINI_DESTROY_POLL_GROUPS, + NVMF_TGT_FINI_STOP_SUBSYSTEMS, NVMF_TGT_FINI_FREE_RESOURCES, NVMF_TGT_STOPPED, NVMF_TGT_ERROR, @@ -86,11 +88,10 @@ struct spdk_nvmf_ns_params { uint32_t nsid; }; -int -spdk_nvmf_construct_subsystem(const char *name, - int num_listen_addresses, struct rpc_listen_address *addresses, - int num_hosts, char *hosts[], bool allow_any_host, - const char *sn, size_t num_ns, struct spdk_nvmf_ns_params *ns_list); +struct spdk_nvmf_subsystem *spdk_nvmf_construct_subsystem(const char *name, + int num_listen_addresses, struct rpc_listen_address *addresses, + int num_hosts, char *hosts[], bool allow_any_host, + const char *sn, size_t num_ns, struct spdk_nvmf_ns_params *ns_list); int nvmf_tgt_shutdown_subsystem_by_nqn(const char *nqn); diff --git a/include/spdk/nvmf.h b/include/spdk/nvmf.h index 6ab8d0a17e..9e35b668a1 100644 --- a/include/spdk/nvmf.h +++ b/include/spdk/nvmf.h @@ -132,16 +132,86 @@ int spdk_nvmf_poll_group_add(struct spdk_nvmf_poll_group *group, int spdk_nvmf_poll_group_remove(struct spdk_nvmf_poll_group *group, struct spdk_nvmf_qpair *qpair); -/* - * The NVMf subsystem, as indicated in the specification, is a collection - * of controllers. Any individual controller has - * access to all the NVMe device/namespaces maintained by the subsystem. +/** + * Create an NVMe-oF subsystem. + * + * Subsystems are in one of three states: Inactive, Active, Paused. This + * state affects which operations may be performed on the subsystem. Upon + * creation, the subsystem will be in the Inactive state and may be activated + * by calling spdk_nvmf_subsystem_start(). No I/O will be processed in the Inactive + * or Paused states, but changes to the state of the subsystem may be made. + * + * \param tgt The NVMe-oF target that will own this subsystem. + * \param nqn The NVMe qualified name of this subsystem. + * \param type Whether this subsystem is an I/O subsystem or a Discovery subsystem. + * \param num_ns The number of namespaces this subsystem contains. + * + * \return An spdk_nvmf_subsystem or NULL on error. */ -struct spdk_nvmf_subsystem *spdk_nvmf_create_subsystem(struct spdk_nvmf_tgt *tgt, +struct spdk_nvmf_subsystem *spdk_nvmf_subsystem_create(struct spdk_nvmf_tgt *tgt, const char *nqn, enum spdk_nvmf_subtype type, uint32_t num_ns); +/** + * Destroy an NVMe-oF subsystem. A subsystem may only be destroyed when in + * the Inactive state. See spdk_nvmf_subsystem_stop(). + * + * \param subsystem The NVMe-oF subsystem to destroy. + */ +void spdk_nvmf_subsystem_destroy(struct spdk_nvmf_subsystem *subsystem); + +typedef void (*spdk_nvmf_subsystem_state_change_done)(struct spdk_nvmf_subsystem *subsystem, + void *cb_arg, int status); + +/** + * Transition an NVMe-oF subsystem from Inactive to Active state. + * + * \param subsystem The NVMe-oF subsystem. + * \param cb_fn A function that will be called once the subsystem has changed state. + * \param cb_arg Argument passed to cb_fn. + * + */ +void spdk_nvmf_subsystem_start(struct spdk_nvmf_subsystem *subsystem, + spdk_nvmf_subsystem_state_change_done cb_fn, + void *cb_arg); + +/** + * Transition an NVMe-oF subsystem from Active to Inactive state. + * + * \param subsystem The NVMe-oF subsystem. + * \param cb_fn A function that will be called once the subsystem has changed state. + * \param cb_arg Argument passed to cb_fn. + * + */ +void spdk_nvmf_subsystem_stop(struct spdk_nvmf_subsystem *subsystem, + spdk_nvmf_subsystem_state_change_done cb_fn, + void *cb_arg); + +/** + * Transition an NVMe-oF subsystem from Active to Paused state. + * + * \param subsystem The NVMe-oF subsystem. + * \param cb_fn A function that will be called once the subsystem has changed state. + * \param cb_arg Argument passed to cb_fn. + * + */ +void spdk_nvmf_subsystem_pause(struct spdk_nvmf_subsystem *subsystem, + spdk_nvmf_subsystem_state_change_done cb_fn, + void *cb_arg); + +/** + * Transition an NVMe-oF subsystem from Paused to Active state. + * + * \param subsystem The NVMe-oF subsystem. + * \param cb_fn A function that will be called once the subsystem has changed state. + * \param cb_arg Argument passed to cb_fn. + * + */ +void spdk_nvmf_subsystem_resume(struct spdk_nvmf_subsystem *subsystem, + spdk_nvmf_subsystem_state_change_done cb_fn, + void *cb_arg); + /** * Search the target for a subsystem with the given NQN */ @@ -158,8 +228,6 @@ struct spdk_nvmf_subsystem *spdk_nvmf_subsystem_get_first(struct spdk_nvmf_tgt * */ struct spdk_nvmf_subsystem *spdk_nvmf_subsystem_get_next(struct spdk_nvmf_subsystem *subsystem); -void spdk_nvmf_delete_subsystem(struct spdk_nvmf_subsystem *subsystem); - /** * Allow the given host NQN to connect to the given subsystem. * diff --git a/lib/nvmf/nvmf.c b/lib/nvmf/nvmf.c index 73cf15d6f1..159e0a9e06 100644 --- a/lib/nvmf/nvmf.c +++ b/lib/nvmf/nvmf.c @@ -207,7 +207,7 @@ spdk_nvmf_tgt_destroy(struct spdk_nvmf_tgt *tgt) if (tgt->subsystems) { for (i = 0; i < tgt->max_sid; i++) { if (tgt->subsystems[i]) { - spdk_nvmf_delete_subsystem(tgt->subsystems[i]); + spdk_nvmf_subsystem_destroy(tgt->subsystems[i]); } } free(tgt->subsystems); @@ -416,18 +416,19 @@ spdk_nvmf_poll_group_add_transport(struct spdk_nvmf_poll_group *group, return 0; } -int -spdk_nvmf_poll_group_add_subsystem(struct spdk_nvmf_poll_group *group, - struct spdk_nvmf_subsystem *subsystem) +static int +poll_group_update_subsystem(struct spdk_nvmf_poll_group *group, + struct spdk_nvmf_subsystem *subsystem) { struct spdk_nvmf_subsystem_poll_group *sgroup; - struct spdk_nvmf_ns *ns; + uint32_t new_num_channels, old_num_channels; + void *buf; uint32_t i; + struct spdk_nvmf_ns *ns; if (subsystem->id >= group->num_sgroups) { void *buf; - buf = realloc(group->sgroups, (subsystem->id + 1) * sizeof(*sgroup)); if (!buf) { return -ENOMEM; @@ -438,46 +439,92 @@ spdk_nvmf_poll_group_add_subsystem(struct spdk_nvmf_poll_group *group, /* Zero out the newly allocated memory */ memset(&group->sgroups[group->num_sgroups], 0, - (subsystem->id + 1 - group->num_sgroups) * sizeof(struct spdk_nvmf_subsystem_poll_group)); + (subsystem->id + 1 - group->num_sgroups) * sizeof(group->sgroups[0])); group->num_sgroups = subsystem->id + 1; } sgroup = &group->sgroups[subsystem->id]; - sgroup->num_channels = subsystem->max_nsid; - sgroup->channels = calloc(sgroup->num_channels, sizeof(struct spdk_io_channel *)); - if (!sgroup->channels) { - return -1; - } + new_num_channels = subsystem->max_nsid; + old_num_channels = sgroup->num_channels; - for (i = 0; i < sgroup->num_channels; i++) { - ns = &subsystem->ns[i]; - if (ns->allocated && sgroup->channels[i] == NULL) { - sgroup->channels[i] = spdk_bdev_get_io_channel(ns->desc); - if (sgroup->channels[i] == NULL) { - return -1; + if (new_num_channels == old_num_channels) { + /* Nothing to do */ + } else if (old_num_channels == 0) { + /* First allocation */ + sgroup->channels = calloc(new_num_channels, sizeof(sgroup->channels[0])); + if (!sgroup->channels) { + return -ENOMEM; + } + sgroup->num_channels = new_num_channels; + + /* Initialize new channels */ + for (i = old_num_channels; i < new_num_channels; i++) { + ns = &subsystem->ns[i]; + if (ns->allocated) { + sgroup->channels[i] = spdk_bdev_get_io_channel(ns->desc); + } else { + sgroup->channels[i] = NULL; + } + } + } else if (new_num_channels < old_num_channels) { + /* Free the extra I/O channels */ + for (i = new_num_channels; i < old_num_channels; i++) { + if (sgroup->channels[i]) { + spdk_put_io_channel(sgroup->channels[i]); + } + } + + /* Shrink array */ + buf = realloc(sgroup->channels, new_num_channels * sizeof(sgroup->channels[0])); + if (new_num_channels > 0 && !buf) { + return -ENOMEM; + } + + sgroup->channels = buf; + sgroup->num_channels = new_num_channels; + } else { + /* Grow array */ + buf = realloc(sgroup->channels, new_num_channels * sizeof(sgroup->channels[0])); + if (!buf) { + return -ENOMEM; + } + + sgroup->channels = buf; + sgroup->num_channels = new_num_channels; + + /* Initialize new channels */ + for (i = old_num_channels; i < new_num_channels; i++) { + ns = &subsystem->ns[i]; + if (ns->allocated) { + sgroup->channels[i] = spdk_bdev_get_io_channel(ns->desc); + } else { + sgroup->channels[i] = NULL; } } } + /* TODO: Handle namespaces where the bdev was swapped out */ + return 0; } int -spdk_nvmf_poll_group_remove_ns(struct spdk_nvmf_poll_group *group, - struct spdk_nvmf_ns *ns) +spdk_nvmf_poll_group_add_subsystem(struct spdk_nvmf_poll_group *group, + struct spdk_nvmf_subsystem *subsystem) { struct spdk_nvmf_subsystem_poll_group *sgroup; - uint32_t nsid = ns->id - 1; + int rc; - sgroup = &group->sgroups[ns->subsystem->id]; - - if (sgroup->channels[nsid]) { - spdk_put_io_channel(sgroup->channels[nsid]); - sgroup->channels[nsid] = NULL; + rc = poll_group_update_subsystem(group, subsystem); + if (rc) { + return rc; } + sgroup = &group->sgroups[subsystem->id]; + sgroup->state = SPDK_NVMF_SUBSYSTEM_ACTIVE; + return 0; } @@ -505,46 +552,52 @@ spdk_nvmf_poll_group_remove_subsystem(struct spdk_nvmf_poll_group *group, } int -spdk_nvmf_poll_group_add_ns(struct spdk_nvmf_poll_group *group, - struct spdk_nvmf_subsystem *subsystem, - struct spdk_nvmf_ns *ns) +spdk_nvmf_poll_group_pause_subsystem(struct spdk_nvmf_poll_group *group, + struct spdk_nvmf_subsystem *subsystem) { struct spdk_nvmf_subsystem_poll_group *sgroup; - uint32_t ns_idx; - sgroup = &group->sgroups[subsystem->id]; - - /* The index into the channels array is (nsid - 1) */ - ns_idx = ns->id - 1; - - if (ns_idx >= sgroup->num_channels) { - void *buf; - - buf = realloc(sgroup->channels, - ns->id * sizeof(struct spdk_io_channel *)); - if (!buf) { - return -ENOMEM; - } - - /* Zero out the newly allocated memory */ - memset(&sgroup->channels[sgroup->num_channels], - 0, - (ns->id - sgroup->num_channels) * sizeof(struct spdk_io_channel *)); - - sgroup->num_channels = ns->id; - sgroup->channels = buf; - } - - /* The channel could have been created in response to a subsystem creation - * event already propagating through the system */ - if (sgroup->channels[ns_idx] == NULL) { - sgroup->channels[ns_idx] = spdk_bdev_get_io_channel(ns->desc); - } - - if (sgroup->channels[ns_idx] == NULL) { + if (subsystem->id >= group->num_sgroups) { return -1; } + sgroup = &group->sgroups[subsystem->id]; + if (sgroup == NULL) { + return -1; + } + + assert(sgroup->state == SPDK_NVMF_SUBSYSTEM_ACTIVE); + /* TODO: This currently does not quiesce I/O */ + sgroup->state = SPDK_NVMF_SUBSYSTEM_PAUSED; + + return 0; +} + +int +spdk_nvmf_poll_group_resume_subsystem(struct spdk_nvmf_poll_group *group, + struct spdk_nvmf_subsystem *subsystem) +{ + struct spdk_nvmf_subsystem_poll_group *sgroup; + int rc; + + if (subsystem->id >= group->num_sgroups) { + return -1; + } + + sgroup = &group->sgroups[subsystem->id]; + if (sgroup == NULL) { + return -1; + } + + assert(sgroup->state == SPDK_NVMF_SUBSYSTEM_PAUSED); + + rc = poll_group_update_subsystem(group, subsystem); + if (rc) { + return rc; + } + + sgroup->state = SPDK_NVMF_SUBSYSTEM_ACTIVE; + return 0; } diff --git a/lib/nvmf/nvmf_internal.h b/lib/nvmf/nvmf_internal.h index 665adb6695..4fb29ca78f 100644 --- a/lib/nvmf/nvmf_internal.h +++ b/lib/nvmf/nvmf_internal.h @@ -45,6 +45,16 @@ #define SPDK_NVMF_DEFAULT_NUM_CTRLRS_PER_LCORE 1 +enum spdk_nvmf_subsystem_state { + SPDK_NVMF_SUBSYSTEM_INACTIVE = 0, + SPDK_NVMF_SUBSYSTEM_ACTIVATING, + SPDK_NVMF_SUBSYSTEM_ACTIVE, + SPDK_NVMF_SUBSYSTEM_PAUSING, + SPDK_NVMF_SUBSYSTEM_PAUSED, + SPDK_NVMF_SUBSYSTEM_RESUMING, + SPDK_NVMF_SUBSYSTEM_DEACTIVATING, +}; + struct spdk_nvmf_tgt { struct spdk_nvmf_tgt_opts opts; @@ -81,6 +91,8 @@ struct spdk_nvmf_subsystem_poll_group { /* Array of channels for each namespace indexed by nsid - 1 */ struct spdk_io_channel **channels; uint32_t num_channels; + + enum spdk_nvmf_subsystem_state state; }; struct spdk_nvmf_poll_group { @@ -91,7 +103,6 @@ struct spdk_nvmf_poll_group { /* Array of poll groups indexed by subsystem id (sid) */ struct spdk_nvmf_subsystem_poll_group *sgroups; uint32_t num_sgroups; - }; typedef enum _spdk_nvmf_request_exec_status { @@ -185,7 +196,9 @@ struct spdk_nvmf_ctrlr { }; struct spdk_nvmf_subsystem { - uint32_t id; + uint32_t id; + enum spdk_nvmf_subsystem_state state; + char subnqn[SPDK_NVMF_NQN_MAX_LEN + 1]; enum spdk_nvmf_subtype subtype; uint16_t next_cntlid; @@ -218,11 +231,10 @@ int spdk_nvmf_poll_group_add_subsystem(struct spdk_nvmf_poll_group *group, struct spdk_nvmf_subsystem *subsystem); int spdk_nvmf_poll_group_remove_subsystem(struct spdk_nvmf_poll_group *group, struct spdk_nvmf_subsystem *subsystem); -int spdk_nvmf_poll_group_add_ns(struct spdk_nvmf_poll_group *group, - struct spdk_nvmf_subsystem *subsystem, - struct spdk_nvmf_ns *ns); -int spdk_nvmf_poll_group_remove_ns(struct spdk_nvmf_poll_group *group, - struct spdk_nvmf_ns *ns); +int spdk_nvmf_poll_group_pause_subsystem(struct spdk_nvmf_poll_group *group, + struct spdk_nvmf_subsystem *subsystem); +int spdk_nvmf_poll_group_resume_subsystem(struct spdk_nvmf_poll_group *group, + struct spdk_nvmf_subsystem *subsystem); void spdk_nvmf_request_exec(struct spdk_nvmf_request *req); int spdk_nvmf_request_complete(struct spdk_nvmf_request *req); int spdk_nvmf_request_abort(struct spdk_nvmf_request *req); diff --git a/lib/nvmf/subsystem.c b/lib/nvmf/subsystem.c index 8e71c3c93a..cd0845052f 100644 --- a/lib/nvmf/subsystem.c +++ b/lib/nvmf/subsystem.c @@ -71,25 +71,8 @@ spdk_nvmf_valid_nqn(const char *nqn) return true; } -static void -spdk_nvmf_subsystem_create_done(struct spdk_io_channel_iter *i, int status) -{ -} - -static void -spdk_nvmf_subsystem_add_to_poll_group(struct spdk_io_channel_iter *i) -{ - struct spdk_nvmf_subsystem *subsystem = spdk_io_channel_iter_get_ctx(i); - struct spdk_io_channel *ch = spdk_io_channel_iter_get_channel(i); - struct spdk_nvmf_poll_group *group = spdk_io_channel_get_ctx(ch); - int rc; - - rc = spdk_nvmf_poll_group_add_subsystem(group, subsystem); - spdk_for_each_channel_continue(i, rc); -} - struct spdk_nvmf_subsystem * -spdk_nvmf_create_subsystem(struct spdk_nvmf_tgt *tgt, +spdk_nvmf_subsystem_create(struct spdk_nvmf_tgt *tgt, const char *nqn, enum spdk_nvmf_subtype type, uint32_t num_ns) @@ -129,6 +112,7 @@ spdk_nvmf_create_subsystem(struct spdk_nvmf_tgt *tgt, return NULL; } + subsystem->state = SPDK_NVMF_SUBSYSTEM_INACTIVE; subsystem->tgt = tgt; subsystem->id = sid; subsystem->subtype = type; @@ -152,67 +136,23 @@ spdk_nvmf_create_subsystem(struct spdk_nvmf_tgt *tgt, tgt->subsystems[sid] = subsystem; tgt->discovery_genctr++; - /* Send a message to each poll group to notify it that a new subsystem - * is available. - * TODO: This call does not currently allow the user to wait for these - * messages to propagate. It also does not protect against two calls - * to this function overlapping - */ - spdk_for_each_channel(tgt, - spdk_nvmf_subsystem_add_to_poll_group, - subsystem, - spdk_nvmf_subsystem_create_done); - return subsystem; } -static void -spdk_nvmf_subsystem_delete_done(struct spdk_io_channel_iter *i, int status) -{ - struct spdk_nvmf_tgt *tgt = spdk_io_channel_iter_get_io_device(i); - struct spdk_nvmf_subsystem *subsystem = spdk_io_channel_iter_get_ctx(i); - struct spdk_nvmf_ns *ns; - - for (ns = spdk_nvmf_subsystem_get_first_ns(subsystem); ns != NULL; - ns = spdk_nvmf_subsystem_get_next_ns(subsystem, ns)) { - if (ns->bdev == NULL) { - continue; - } - spdk_bdev_close(ns->desc); - } - - free(subsystem->ns); - - tgt->subsystems[subsystem->id] = NULL; - tgt->discovery_genctr++; - - free(subsystem); -} - -static void -spdk_nvmf_subsystem_remove_from_poll_group(struct spdk_io_channel_iter *i) -{ - struct spdk_nvmf_subsystem *subsystem = spdk_io_channel_iter_get_ctx(i); - struct spdk_io_channel *ch = spdk_io_channel_iter_get_channel(i); - struct spdk_nvmf_poll_group *group = spdk_io_channel_get_ctx(ch); - int rc; - - rc = spdk_nvmf_poll_group_remove_subsystem(group, subsystem); - - spdk_for_each_channel_continue(i, rc); -} - void -spdk_nvmf_delete_subsystem(struct spdk_nvmf_subsystem *subsystem) +spdk_nvmf_subsystem_destroy(struct spdk_nvmf_subsystem *subsystem) { struct spdk_nvmf_listener *listener, *listener_tmp; struct spdk_nvmf_host *host, *host_tmp; struct spdk_nvmf_ctrlr *ctrlr, *ctrlr_tmp; + struct spdk_nvmf_ns *ns; if (!subsystem) { return; } + assert(subsystem->state == SPDK_NVMF_SUBSYSTEM_INACTIVE); + SPDK_DEBUGLOG(SPDK_LOG_NVMF, "subsystem is %p\n", subsystem); TAILQ_FOREACH_SAFE(listener, &subsystem->listeners, link, listener_tmp) { @@ -230,16 +170,210 @@ spdk_nvmf_delete_subsystem(struct spdk_nvmf_subsystem *subsystem) spdk_nvmf_ctrlr_destruct(ctrlr); } - /* Send a message to each poll group to notify it that a subsystem - * is no longer available. - * TODO: This call does not currently allow the user to wait for these - * messages to propagate. It also does not protect against two calls - * to this function overlapping - */ + for (ns = spdk_nvmf_subsystem_get_first_ns(subsystem); ns != NULL; + ns = spdk_nvmf_subsystem_get_next_ns(subsystem, ns)) { + if (ns->bdev == NULL) { + continue; + } + spdk_bdev_close(ns->desc); + } + + free(subsystem->ns); + + subsystem->tgt->subsystems[subsystem->id] = NULL; + subsystem->tgt->discovery_genctr++; + + free(subsystem); +} + +static int +spdk_nvmf_subsystem_set_state(struct spdk_nvmf_subsystem *subsystem, + enum spdk_nvmf_subsystem_state state) +{ + enum spdk_nvmf_subsystem_state actual_old_state, expected_old_state; + + switch (state) { + case SPDK_NVMF_SUBSYSTEM_INACTIVE: + expected_old_state = SPDK_NVMF_SUBSYSTEM_DEACTIVATING; + break; + case SPDK_NVMF_SUBSYSTEM_ACTIVATING: + expected_old_state = SPDK_NVMF_SUBSYSTEM_INACTIVE; + break; + case SPDK_NVMF_SUBSYSTEM_ACTIVE: + expected_old_state = SPDK_NVMF_SUBSYSTEM_ACTIVATING; + break; + case SPDK_NVMF_SUBSYSTEM_PAUSING: + expected_old_state = SPDK_NVMF_SUBSYSTEM_ACTIVE; + break; + case SPDK_NVMF_SUBSYSTEM_PAUSED: + expected_old_state = SPDK_NVMF_SUBSYSTEM_PAUSING; + break; + case SPDK_NVMF_SUBSYSTEM_RESUMING: + expected_old_state = SPDK_NVMF_SUBSYSTEM_PAUSED; + break; + case SPDK_NVMF_SUBSYSTEM_DEACTIVATING: + expected_old_state = SPDK_NVMF_SUBSYSTEM_ACTIVE; + break; + default: + assert(false); + return -1; + } + + actual_old_state = __sync_val_compare_and_swap(&subsystem->state, expected_old_state, state); + if (actual_old_state != expected_old_state) { + if (actual_old_state == SPDK_NVMF_SUBSYSTEM_RESUMING && + state == SPDK_NVMF_SUBSYSTEM_ACTIVE) { + expected_old_state = SPDK_NVMF_SUBSYSTEM_RESUMING; + } + actual_old_state = __sync_val_compare_and_swap(&subsystem->state, expected_old_state, state); + } + assert(actual_old_state == expected_old_state); + return actual_old_state - expected_old_state; +} + +struct subsystem_state_change_ctx { + struct spdk_nvmf_subsystem *subsystem; + + enum spdk_nvmf_subsystem_state requested_state; + + spdk_nvmf_subsystem_state_change_done cb_fn; + void *cb_arg; +}; + +static void +subsystem_state_change_done(struct spdk_io_channel_iter *i, int status) +{ + struct subsystem_state_change_ctx *ctx = spdk_io_channel_iter_get_ctx(i); + + if (status == 0) { + status = spdk_nvmf_subsystem_set_state(ctx->subsystem, ctx->requested_state); + if (status) { + status = -1; + } + } + + ctx->cb_fn(ctx->subsystem, ctx->cb_arg, status); + free(ctx); +} + +static void +subsystem_state_change_on_pg(struct spdk_io_channel_iter *i) +{ + struct subsystem_state_change_ctx *ctx; + struct spdk_io_channel *ch; + struct spdk_nvmf_poll_group *group; + int rc = -1; + + ctx = spdk_io_channel_iter_get_ctx(i); + ch = spdk_io_channel_iter_get_channel(i); + group = spdk_io_channel_get_ctx(ch); + + switch (ctx->requested_state) { + case SPDK_NVMF_SUBSYSTEM_INACTIVE: + rc = spdk_nvmf_poll_group_remove_subsystem(group, ctx->subsystem); + break; + case SPDK_NVMF_SUBSYSTEM_ACTIVE: + if (ctx->subsystem->state == SPDK_NVMF_SUBSYSTEM_ACTIVATING) { + rc = spdk_nvmf_poll_group_add_subsystem(group, ctx->subsystem); + } else if (ctx->subsystem->state == SPDK_NVMF_SUBSYSTEM_RESUMING) { + rc = spdk_nvmf_poll_group_resume_subsystem(group, ctx->subsystem); + } + break; + case SPDK_NVMF_SUBSYSTEM_PAUSED: + rc = spdk_nvmf_poll_group_pause_subsystem(group, ctx->subsystem); + break; + default: + assert(false); + break; + } + + spdk_for_each_channel_continue(i, rc); +} + +static void +spdk_nvmf_subsystem_state_change(struct spdk_nvmf_subsystem *subsystem, + enum spdk_nvmf_subsystem_state requested_state, + spdk_nvmf_subsystem_state_change_done cb_fn, + void *cb_arg) +{ + struct subsystem_state_change_ctx *ctx; + enum spdk_nvmf_subsystem_state intermediate_state; + int rc; + + switch (requested_state) { + case SPDK_NVMF_SUBSYSTEM_INACTIVE: + intermediate_state = SPDK_NVMF_SUBSYSTEM_DEACTIVATING; + break; + case SPDK_NVMF_SUBSYSTEM_ACTIVE: + if (subsystem->state == SPDK_NVMF_SUBSYSTEM_PAUSED) { + intermediate_state = SPDK_NVMF_SUBSYSTEM_RESUMING; + } else { + intermediate_state = SPDK_NVMF_SUBSYSTEM_ACTIVATING; + } + break; + case SPDK_NVMF_SUBSYSTEM_PAUSED: + intermediate_state = SPDK_NVMF_SUBSYSTEM_PAUSING; + break; + default: + assert(false); + cb_fn(subsystem, cb_arg, -EINVAL); + return; + } + + ctx = calloc(1, sizeof(*ctx)); + if (!ctx) { + cb_fn(subsystem, cb_arg, -ENOMEM); + return; + } + + rc = spdk_nvmf_subsystem_set_state(subsystem, intermediate_state); + if (rc) { + free(ctx); + cb_fn(subsystem, cb_arg, -1); + return; + } + + ctx->subsystem = subsystem; + ctx->requested_state = requested_state; + ctx->cb_fn = cb_fn; + ctx->cb_arg = cb_arg; + spdk_for_each_channel(subsystem->tgt, - spdk_nvmf_subsystem_remove_from_poll_group, - subsystem, - spdk_nvmf_subsystem_delete_done); + subsystem_state_change_on_pg, + ctx, + subsystem_state_change_done); +} + +void +spdk_nvmf_subsystem_start(struct spdk_nvmf_subsystem *subsystem, + spdk_nvmf_subsystem_state_change_done cb_fn, + void *cb_arg) +{ + spdk_nvmf_subsystem_state_change(subsystem, SPDK_NVMF_SUBSYSTEM_ACTIVE, cb_fn, cb_arg); +} + +void +spdk_nvmf_subsystem_stop(struct spdk_nvmf_subsystem *subsystem, + spdk_nvmf_subsystem_state_change_done cb_fn, + void *cb_arg) +{ + spdk_nvmf_subsystem_state_change(subsystem, SPDK_NVMF_SUBSYSTEM_INACTIVE, cb_fn, cb_arg); +} + +void +spdk_nvmf_subsystem_pause(struct spdk_nvmf_subsystem *subsystem, + spdk_nvmf_subsystem_state_change_done cb_fn, + void *cb_arg) +{ + spdk_nvmf_subsystem_state_change(subsystem, SPDK_NVMF_SUBSYSTEM_PAUSED, cb_fn, cb_arg); +} + +void +spdk_nvmf_subsystem_resume(struct spdk_nvmf_subsystem *subsystem, + spdk_nvmf_subsystem_state_change_done cb_fn, + void *cb_arg) +{ + spdk_nvmf_subsystem_state_change(subsystem, SPDK_NVMF_SUBSYSTEM_ACTIVE, cb_fn, cb_arg); } struct spdk_nvmf_subsystem * @@ -427,29 +561,6 @@ spdk_nvmf_listener_get_trid(struct spdk_nvmf_listener *listener) return &listener->trid; } -static void -spdk_nvmf_remove_ns_done(struct spdk_io_channel_iter *i, int status) -{ - struct spdk_nvmf_ns *ns = spdk_io_channel_iter_get_ctx(i); - struct spdk_nvmf_subsystem *subsystem = ns->subsystem; - - spdk_bdev_close(ns->desc); - ns->allocated = false; - subsystem->num_allocated_nsid--; -} - -static void -spdk_nvmf_subsystem_remove_ns_from_poll_group(struct spdk_io_channel_iter *i) -{ - struct spdk_nvmf_ns *ns = spdk_io_channel_iter_get_ctx(i); - struct spdk_io_channel *ch = spdk_io_channel_iter_get_channel(i); - struct spdk_nvmf_poll_group *group = spdk_io_channel_get_ctx(ch); - int rc; - - rc = spdk_nvmf_poll_group_remove_ns(group, ns); - spdk_for_each_channel_continue(i, rc); -} - int spdk_nvmf_subsystem_remove_ns(struct spdk_nvmf_subsystem *subsystem, uint32_t nsid) { @@ -464,31 +575,13 @@ spdk_nvmf_subsystem_remove_ns(struct spdk_nvmf_subsystem *subsystem, uint32_t ns return -1; } - spdk_for_each_channel(ns->subsystem->tgt, - spdk_nvmf_subsystem_remove_ns_from_poll_group, - ns, - spdk_nvmf_remove_ns_done); + spdk_bdev_close(ns->desc); + ns->allocated = false; + subsystem->num_allocated_nsid--; + return 0; } -static void -spdk_nvmf_subsystem_add_ns_done(struct spdk_io_channel_iter *i, int status) -{ - return; -} - -static void -spdk_nvmf_subsystem_ns_update_poll_group(struct spdk_io_channel_iter *i) -{ - struct spdk_nvmf_ns *ns = spdk_io_channel_iter_get_ctx(i); - struct spdk_io_channel *ch = spdk_io_channel_iter_get_channel(i); - struct spdk_nvmf_poll_group *group = spdk_io_channel_get_ctx(ch); - int rc; - - rc = spdk_nvmf_poll_group_add_ns(group, ns->subsystem, ns); - spdk_for_each_channel_continue(i, rc); -} - static void _spdk_nvmf_ns_hot_remove(void *ctx) { @@ -516,6 +609,9 @@ 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 (nsid == SPDK_NVME_GLOBAL_NS_TAG) { SPDK_ERRLOG("Invalid NSID %" PRIu32 "\n", nsid); return 0; @@ -590,17 +686,6 @@ spdk_nvmf_subsystem_add_ns(struct spdk_nvmf_subsystem *subsystem, struct spdk_bd subsystem->max_nsid = spdk_max(subsystem->max_nsid, nsid); subsystem->num_allocated_nsid++; - /* Send a message to each poll group to notify it that a new namespace - * is available. - * TODO: This call does not currently allow the user to wait for these - * messages to propagate. It also does not protect against two calls - * to this function overlapping - */ - spdk_for_each_channel(subsystem->tgt, - spdk_nvmf_subsystem_ns_update_poll_group, - ns, - spdk_nvmf_subsystem_add_ns_done); - return nsid; } diff --git a/test/unit/lib/nvmf/ctrlr_discovery.c/ctrlr_discovery_ut.c b/test/unit/lib/nvmf/ctrlr_discovery.c/ctrlr_discovery_ut.c index c010193fd7..fb2378b759 100644 --- a/test/unit/lib/nvmf/ctrlr_discovery.c/ctrlr_discovery_ut.c +++ b/test/unit/lib/nvmf/ctrlr_discovery.c/ctrlr_discovery_ut.c @@ -160,16 +160,15 @@ spdk_nvmf_poll_group_remove_subsystem(struct spdk_nvmf_poll_group *group, } int -spdk_nvmf_poll_group_remove_ns(struct spdk_nvmf_poll_group *group, - struct spdk_nvmf_ns *ns) +spdk_nvmf_poll_group_pause_subsystem(struct spdk_nvmf_poll_group *group, + struct spdk_nvmf_subsystem *subsystem) { return 0; } int -spdk_nvmf_poll_group_add_ns(struct spdk_nvmf_poll_group *group, - struct spdk_nvmf_subsystem *subsystem, - struct spdk_nvmf_ns *ns) +spdk_nvmf_poll_group_resume_subsystem(struct spdk_nvmf_poll_group *group, + struct spdk_nvmf_subsystem *subsystem) { return 0; } @@ -200,7 +199,7 @@ test_discovery_log(void) struct spdk_nvme_transport_id trid = {}; /* Add one subsystem and verify that the discovery log contains it */ - subsystem = spdk_nvmf_create_subsystem(&tgt, "nqn.2016-06.io.spdk:subsystem1", + subsystem = spdk_nvmf_subsystem_create(&tgt, "nqn.2016-06.io.spdk:subsystem1", SPDK_NVMF_SUBTYPE_NVME, 0); SPDK_CU_ASSERT_FATAL(subsystem != NULL); @@ -249,7 +248,7 @@ test_discovery_log(void) offsetof(struct spdk_nvmf_discovery_log_page, entries[0]), sizeof(*entry)); CU_ASSERT(entry->trtype == 42); - spdk_nvmf_delete_subsystem(subsystem); + spdk_nvmf_subsystem_destroy(subsystem); free(tgt.subsystems); free(tgt.discovery_log_page); } diff --git a/test/unit/lib/nvmf/subsystem.c/subsystem_ut.c b/test/unit/lib/nvmf/subsystem.c/subsystem_ut.c index 5a3c4bbd6e..3942f5cc11 100644 --- a/test/unit/lib/nvmf/subsystem.c/subsystem_ut.c +++ b/test/unit/lib/nvmf/subsystem.c/subsystem_ut.c @@ -117,16 +117,15 @@ spdk_nvmf_poll_group_remove_subsystem(struct spdk_nvmf_poll_group *group, } int -spdk_nvmf_poll_group_remove_ns(struct spdk_nvmf_poll_group *group, - struct spdk_nvmf_ns *ns) +spdk_nvmf_poll_group_pause_subsystem(struct spdk_nvmf_poll_group *group, + struct spdk_nvmf_subsystem *subsystem) { return 0; } int -spdk_nvmf_poll_group_add_ns(struct spdk_nvmf_poll_group *group, - struct spdk_nvmf_subsystem *subsystem, - struct spdk_nvmf_ns *ns) +spdk_nvmf_poll_group_resume_subsystem(struct spdk_nvmf_poll_group *group, + struct spdk_nvmf_subsystem *subsystem) { return 0; } @@ -240,27 +239,27 @@ nvmf_test_create_subsystem(void) struct spdk_nvmf_subsystem *subsystem; strncpy(nqn, "nqn.2016-06.io.spdk:subsystem1", sizeof(nqn)); - subsystem = spdk_nvmf_create_subsystem(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); + subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); SPDK_CU_ASSERT_FATAL(subsystem != NULL); CU_ASSERT_STRING_EQUAL(subsystem->subnqn, nqn); - spdk_nvmf_delete_subsystem(subsystem); + spdk_nvmf_subsystem_destroy(subsystem); /* Longest valid name */ strncpy(nqn, "nqn.2016-06.io.spdk:", sizeof(nqn)); memset(nqn + strlen(nqn), 'a', 223 - strlen(nqn)); nqn[223] = '\0'; CU_ASSERT(strlen(nqn) == 223); - subsystem = spdk_nvmf_create_subsystem(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); + subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); SPDK_CU_ASSERT_FATAL(subsystem != NULL); CU_ASSERT_STRING_EQUAL(subsystem->subnqn, nqn); - spdk_nvmf_delete_subsystem(subsystem); + spdk_nvmf_subsystem_destroy(subsystem); /* Name that is one byte longer than allowed */ strncpy(nqn, "nqn.2016-06.io.spdk:", sizeof(nqn)); memset(nqn + strlen(nqn), 'a', 224 - strlen(nqn)); nqn[224] = '\0'; CU_ASSERT(strlen(nqn) == 224); - subsystem = spdk_nvmf_create_subsystem(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); + subsystem = spdk_nvmf_subsystem_create(&tgt, nqn, SPDK_NVMF_SUBTYPE_NVME, 0); CU_ASSERT(subsystem == NULL); free(tgt.subsystems);