nvmf: Correct the error path of transport creation.
An error might occur after succesful transport creation when the new transport is added to nvmf poll groups, e.g. in nvmf_transport_poll_group_create. In that case transport is not detroyed and poll groups are not fully functional. To correct this behaviour, destroy transport if spdk_nvmf_tgt_add_transport fails. Also update nvmf_tgt initialization step to check that all poll groups were created. Change-Id: I116e6944729d846c1755c2844c77825f65db8c12 Signed-off-by: Alexey Marchuk <alexeymar@mellanox.com> Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/9255 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com> Community-CI: Mellanox Build Bot Reviewed-by: Jacek Kalwas <jacek.kalwas@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
This commit is contained in:
parent
d409971b79
commit
fb4398ef4b
@ -116,6 +116,7 @@ nvmf_tgt_create_poll_group(void *io_device, void *ctx_buf)
|
||||
struct spdk_nvmf_transport *transport;
|
||||
struct spdk_thread *thread = spdk_get_thread();
|
||||
uint32_t sid;
|
||||
int rc;
|
||||
|
||||
SPDK_DTRACE_PROBE1(nvmf_create_poll_group, spdk_thread_get_id(thread));
|
||||
|
||||
@ -123,7 +124,10 @@ nvmf_tgt_create_poll_group(void *io_device, void *ctx_buf)
|
||||
TAILQ_INIT(&group->qpairs);
|
||||
|
||||
TAILQ_FOREACH(transport, &tgt->transports, link) {
|
||||
nvmf_poll_group_add_transport(group, transport);
|
||||
rc = nvmf_poll_group_add_transport(group, transport);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
group->num_sgroups = tgt->max_subsystems;
|
||||
@ -714,6 +718,9 @@ _nvmf_tgt_add_transport_done(struct spdk_io_channel_iter *i, int status)
|
||||
{
|
||||
struct spdk_nvmf_tgt_add_transport_ctx *ctx = spdk_io_channel_iter_get_ctx(i);
|
||||
|
||||
if (status) {
|
||||
TAILQ_REMOVE(&ctx->tgt->transports, ctx->transport, link);
|
||||
}
|
||||
ctx->cb_fn(ctx->cb_arg, status);
|
||||
|
||||
free(ctx);
|
||||
|
@ -1787,6 +1787,8 @@ struct nvmf_rpc_create_transport_ctx {
|
||||
char *tgt_name;
|
||||
struct spdk_nvmf_transport_opts opts;
|
||||
struct spdk_jsonrpc_request *request;
|
||||
struct spdk_nvmf_transport *transport;
|
||||
int status;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1889,24 +1891,30 @@ nvmf_rpc_create_transport_ctx_free(struct nvmf_rpc_create_transport_ctx *ctx)
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
nvmf_rpc_transport_destroy_done_cb(void *cb_arg)
|
||||
{
|
||||
struct nvmf_rpc_create_transport_ctx *ctx = cb_arg;
|
||||
|
||||
spdk_jsonrpc_send_error_response_fmt(ctx->request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
|
||||
"Failed to add transport to tgt.(%d)", ctx->status);
|
||||
nvmf_rpc_create_transport_ctx_free(ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
nvmf_rpc_tgt_add_transport_done(void *cb_arg, int status)
|
||||
{
|
||||
struct nvmf_rpc_create_transport_ctx *ctx = cb_arg;
|
||||
struct spdk_jsonrpc_request *request;
|
||||
|
||||
request = ctx->request;
|
||||
nvmf_rpc_create_transport_ctx_free(ctx);
|
||||
|
||||
if (status) {
|
||||
SPDK_ERRLOG("Failed to add transport to tgt.(%d)\n", status);
|
||||
spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
|
||||
"Failed to add transport to tgt.(%d)",
|
||||
status);
|
||||
ctx->status = status;
|
||||
spdk_nvmf_transport_destroy(ctx->transport, nvmf_rpc_transport_destroy_done_cb, ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
spdk_jsonrpc_send_bool_response(request, true);
|
||||
spdk_jsonrpc_send_bool_response(ctx->request, true);
|
||||
nvmf_rpc_create_transport_ctx_free(ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1915,7 +1923,6 @@ rpc_nvmf_create_transport(struct spdk_jsonrpc_request *request,
|
||||
{
|
||||
struct nvmf_rpc_create_transport_ctx *ctx;
|
||||
enum spdk_nvme_transport_type trtype;
|
||||
struct spdk_nvmf_transport *transport;
|
||||
struct spdk_nvmf_tgt *tgt;
|
||||
|
||||
ctx = calloc(1, sizeof(*ctx));
|
||||
@ -1985,9 +1992,9 @@ rpc_nvmf_create_transport(struct spdk_jsonrpc_request *request,
|
||||
/* Transport can parse additional params themselves */
|
||||
ctx->opts.transport_specific = params;
|
||||
|
||||
transport = spdk_nvmf_transport_create(ctx->trtype, &ctx->opts);
|
||||
ctx->transport = spdk_nvmf_transport_create(ctx->trtype, &ctx->opts);
|
||||
|
||||
if (!transport) {
|
||||
if (!ctx->transport) {
|
||||
SPDK_ERRLOG("Transport type '%s' create failed\n", ctx->trtype);
|
||||
spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
|
||||
"Transport type '%s' create failed", ctx->trtype);
|
||||
@ -1997,7 +2004,7 @@ rpc_nvmf_create_transport(struct spdk_jsonrpc_request *request,
|
||||
|
||||
/* add transport to target */
|
||||
ctx->request = request;
|
||||
spdk_nvmf_tgt_add_transport(tgt, transport, nvmf_rpc_tgt_add_transport_done, ctx);
|
||||
spdk_nvmf_tgt_add_transport(tgt, ctx->transport, nvmf_rpc_tgt_add_transport_done, ctx);
|
||||
}
|
||||
SPDK_RPC_REGISTER("nvmf_create_transport", rpc_nvmf_create_transport, SPDK_RPC_RUNTIME)
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
*
|
||||
* Copyright (c) Intel Corporation.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -166,12 +167,22 @@ nvmf_tgt_create_poll_group_done(void *ctx)
|
||||
{
|
||||
struct nvmf_tgt_poll_group *pg = ctx;
|
||||
|
||||
assert(pg);
|
||||
|
||||
if (!pg->group) {
|
||||
SPDK_ERRLOG("Failed to create nvmf poll group\n");
|
||||
/* Change the state to error but wait for completions from all other threads */
|
||||
g_tgt_state = NVMF_TGT_ERROR;
|
||||
}
|
||||
|
||||
TAILQ_INSERT_TAIL(&g_poll_groups, pg, link);
|
||||
|
||||
assert(g_num_poll_groups < nvmf_get_cpuset_count());
|
||||
|
||||
if (++g_num_poll_groups == nvmf_get_cpuset_count()) {
|
||||
g_tgt_state = NVMF_TGT_INIT_START_SUBSYSTEMS;
|
||||
if (g_tgt_state != NVMF_TGT_ERROR) {
|
||||
g_tgt_state = NVMF_TGT_INIT_START_SUBSYSTEMS;
|
||||
}
|
||||
nvmf_tgt_advance_state();
|
||||
}
|
||||
}
|
||||
|
@ -169,6 +169,7 @@ test_nvmf_tgt_create_poll_group(void)
|
||||
struct spdk_nvmf_ns ns = {};
|
||||
struct spdk_bdev bdev = {};
|
||||
struct spdk_io_channel ch = {};
|
||||
struct spdk_nvmf_transport_poll_group transport_pg = {};
|
||||
|
||||
thread = spdk_thread_create(NULL, NULL);
|
||||
SPDK_CU_ASSERT_FATAL(thread != NULL);
|
||||
@ -202,7 +203,9 @@ test_nvmf_tgt_create_poll_group(void)
|
||||
transport.tgt = &tgt;
|
||||
TAILQ_INSERT_TAIL(&tgt.transports, &transport, link);
|
||||
|
||||
MOCK_SET(nvmf_transport_poll_group_create, &transport_pg);
|
||||
rc = nvmf_tgt_create_poll_group((void *)&tgt, (void *)&group);
|
||||
MOCK_SET(nvmf_transport_poll_group_create, NULL);
|
||||
CU_ASSERT(rc == 0);
|
||||
CU_ASSERT(group.num_sgroups == 1);
|
||||
CU_ASSERT(group.sgroups != NULL);
|
||||
|
Loading…
Reference in New Issue
Block a user