diff --git a/lib/event/subsystems/nvmf/nvmf_rpc.c b/lib/event/subsystems/nvmf/nvmf_rpc.c index 06e7f5247..e3fae5fea 100644 --- a/lib/event/subsystems/nvmf/nvmf_rpc.c +++ b/lib/event/subsystems/nvmf/nvmf_rpc.c @@ -719,12 +719,18 @@ invalid: } SPDK_RPC_REGISTER("delete_nvmf_subsystem", spdk_rpc_delete_nvmf_subsystem) +enum nvmf_rpc_listen_op { + NVMF_RPC_LISTEN_ADD, + NVMF_RPC_LISTEN_REMOVE, +}; + struct nvmf_rpc_listener_ctx { char *nqn; struct rpc_listen_address address; struct spdk_jsonrpc_request *request; struct spdk_nvme_transport_id trid; + enum nvmf_rpc_listen_op op; bool response_sent; }; @@ -773,21 +779,29 @@ nvmf_rpc_listen_paused(struct spdk_nvmf_subsystem *subsystem, { struct nvmf_rpc_listener_ctx *ctx = cb_arg; - if (spdk_nvmf_tgt_listen(g_tgt.tgt, &ctx->trid)) { - SPDK_ERRLOG("Unable to add listener.\n"); + if (ctx->op == NVMF_RPC_LISTEN_ADD) { + if (spdk_nvmf_tgt_listen(g_tgt.tgt, &ctx->trid)) { + SPDK_ERRLOG("Unable to add listener.\n"); + goto invalid; + } + + if (spdk_nvmf_subsystem_add_listener(subsystem, &ctx->trid)) { + goto invalid; + } + + } else if (ctx->op == NVMF_RPC_LISTEN_REMOVE) { + if (spdk_nvmf_subsystem_remove_listener(subsystem, &ctx->trid)) { + SPDK_ERRLOG("Unable to remove listener.\n"); + goto invalid; + } + } else { goto invalid; } - - if (spdk_nvmf_subsystem_add_listener(subsystem, &ctx->trid)) { - goto invalid; - } - if (spdk_nvmf_subsystem_resume(subsystem, nvmf_rpc_listen_resumed, ctx)) { spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Internal error"); nvmf_rpc_listener_ctx_free(ctx); return; } - return; invalid: @@ -839,6 +853,8 @@ nvmf_rpc_subsystem_add_listener(struct spdk_jsonrpc_request *request, return; } + ctx->op = NVMF_RPC_LISTEN_ADD; + if (spdk_nvmf_subsystem_pause(subsystem, nvmf_rpc_listen_paused, ctx)) { spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Internal error"); nvmf_rpc_listener_ctx_free(ctx); @@ -847,6 +863,55 @@ nvmf_rpc_subsystem_add_listener(struct spdk_jsonrpc_request *request, } SPDK_RPC_REGISTER("nvmf_subsystem_add_listener", nvmf_rpc_subsystem_add_listener); +static void +nvmf_rpc_subsystem_remove_listener(struct spdk_jsonrpc_request *request, + const struct spdk_json_val *params) +{ + struct nvmf_rpc_listener_ctx *ctx; + struct spdk_nvmf_subsystem *subsystem; + + ctx = calloc(1, sizeof(*ctx)); + if (!ctx) { + spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Out of memory"); + return; + } + + ctx->request = request; + + if (spdk_json_decode_object(params, nvmf_rpc_listener_decoder, + SPDK_COUNTOF(nvmf_rpc_listener_decoder), + ctx)) { + SPDK_ERRLOG("spdk_json_decode_object failed\n"); + spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters"); + nvmf_rpc_listener_ctx_free(ctx); + return; + } + + subsystem = spdk_nvmf_tgt_find_subsystem(g_tgt.tgt, ctx->nqn); + if (!subsystem) { + SPDK_ERRLOG("Unable to find subsystem with NQN %s\n", ctx->nqn); + spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters"); + nvmf_rpc_listener_ctx_free(ctx); + return; + } + + if (rpc_listen_address_to_trid(&ctx->address, &ctx->trid)) { + spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, + "Invalid parameters"); + nvmf_rpc_listener_ctx_free(ctx); + return; + } + + ctx->op = NVMF_RPC_LISTEN_REMOVE; + + if (spdk_nvmf_subsystem_pause(subsystem, nvmf_rpc_listen_paused, ctx)) { + spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Internal error"); + nvmf_rpc_listener_ctx_free(ctx); + return; + } + +} +SPDK_RPC_REGISTER("nvmf_subsystem_remove_listener", nvmf_rpc_subsystem_remove_listener); struct nvmf_rpc_ns_ctx { char *nqn;