From c9b89ef12828c0dc4003548085846253ad702cbd Mon Sep 17 00:00:00 2001 From: Seth Howell Date: Fri, 13 Sep 2019 14:11:36 -0700 Subject: [PATCH] lib/nvmf: nvmf_create_target rpc used for creating a new spdk_nvmf_tgt structure in the application. Change-Id: Ib0182ea6d935b84b4fe4fcad79e173cb46859669 Signed-off-by: Seth Howell Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/468387 Tested-by: SPDK CI Jenkins Reviewed-by: Paul Luse Reviewed-by: Shuhei Matsumoto Reviewed-by: Alexey Marchuk Reviewed-by: Ben Walker --- doc/jsonrpc.md | 37 ++++++++++++++++++++++++++++++ lib/nvmf/nvmf_rpc.c | 56 ++++++++++++++++++++++++++++++++++++++++++++- scripts/rpc.py | 11 +++++++++ scripts/rpc/nvmf.py | 19 +++++++++++++++ 4 files changed, 122 insertions(+), 1 deletion(-) diff --git a/doc/jsonrpc.md b/doc/jsonrpc.md index 8fa62428b..91ab019cf 100644 --- a/doc/jsonrpc.md +++ b/doc/jsonrpc.md @@ -3654,6 +3654,43 @@ Example response: # NVMe-oF Target {#jsonrpc_components_nvmf_tgt} +## nvmf_create_target method {#rpc_nvmf_create_target} + +Initialize an NVMe-oF target with the given attributes. + +### Parameters + +Name | Optional | Type | Description +--------------------------- | -------- | ------------| ----------- +name | Required | string | Target name (must be unique to application) +max_subsystems | Optional | number | The maximum number of subsystems. default: 0 (Uses SPDK_NVMF_DEFAULT_MAX_SUBSYSTEMS). + +### Example + +Example request: + +~~~ +{ + "jsonrpc": "2.0", + "method": "nvmf_create_target", + "id": 1, + "params": { + "name": "new_tgt", + "max_subsystems": 1024 + } +} +~~~ + +Example response: + +~~~ +{ + "jsonrpc": "2.0", + "id": 1, + "result": "new_tgt" +} +~~~ + ## nvmf_create_transport method {#rpc_nvmf_create_transport} Initialize an NVMe-oF transport with the given options. diff --git a/lib/nvmf/nvmf_rpc.c b/lib/nvmf/nvmf_rpc.c index b77ac00c9..9b660eda0 100644 --- a/lib/nvmf/nvmf_rpc.c +++ b/lib/nvmf/nvmf_rpc.c @@ -1397,6 +1397,61 @@ spdk_rpc_nvmf_subsystem_allow_any_host(struct spdk_jsonrpc_request *request, SPDK_RPC_REGISTER("nvmf_subsystem_allow_any_host", spdk_rpc_nvmf_subsystem_allow_any_host, SPDK_RPC_RUNTIME) +struct nvmf_rpc_target_ctx { + char *name; + uint32_t max_subsystems; +}; + +static const struct spdk_json_object_decoder nvmf_rpc_create_target_decoder[] = { + {"name", offsetof(struct nvmf_rpc_target_ctx, name), spdk_json_decode_string}, + {"max_subsystems", offsetof(struct nvmf_rpc_target_ctx, max_subsystems), spdk_json_decode_uint32, true}, +}; + +static void +spdk_rpc_nvmf_create_target(struct spdk_jsonrpc_request *request, + const struct spdk_json_val *params) +{ + struct spdk_nvmf_target_opts opts; + struct nvmf_rpc_target_ctx ctx = {0}; + struct spdk_nvmf_tgt *tgt; + struct spdk_json_write_ctx *w; + + /* Decode parameters the first time to get the transport type */ + if (spdk_json_decode_object(params, nvmf_rpc_create_target_decoder, + SPDK_COUNTOF(nvmf_rpc_create_target_decoder), + &ctx)) { + SPDK_ERRLOG("spdk_json_decode_object failed\n"); + spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters"); + free(ctx.name); + return; + } + + snprintf(opts.name, NVMF_TGT_NAME_MAX_LENGTH, "%s", ctx.name); + opts.max_subsystems = ctx.max_subsystems; + + if (spdk_nvmf_get_tgt(opts.name) != NULL) { + spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, + "Target already exists."); + free(ctx.name); + return; + } + + tgt = spdk_nvmf_tgt_create(&opts); + + if (tgt == NULL) { + spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, + "Unable to create the requested target."); + free(ctx.name); + return; + } + + w = spdk_jsonrpc_begin_result(request); + spdk_json_write_string(w, spdk_nvmf_tgt_get_name(tgt)); + spdk_jsonrpc_end_result(request, w); + free(ctx.name); +} +SPDK_RPC_REGISTER("nvmf_create_target", spdk_rpc_nvmf_create_target, SPDK_RPC_RUNTIME); + struct nvmf_rpc_create_transport_ctx { char *trtype; char *tgt_name; @@ -1582,7 +1637,6 @@ spdk_rpc_nvmf_create_transport(struct spdk_jsonrpc_request *request, ctx->request = request; spdk_nvmf_tgt_add_transport(tgt, transport, nvmf_rpc_tgt_add_transport_done, ctx); } - SPDK_RPC_REGISTER("nvmf_create_transport", spdk_rpc_nvmf_create_transport, SPDK_RPC_RUNTIME) static void diff --git a/scripts/rpc.py b/scripts/rpc.py index 9a80d2b8d..9e9dee122 100755 --- a/scripts/rpc.py +++ b/scripts/rpc.py @@ -1557,6 +1557,17 @@ Format: 'user:u1 secret:s1 muser:mu1 msecret:ms1,user:u2 secret:s2 muser:mu2 mse robin manner. 'transport' - Schedule the connection according to the transport characteristics.""") p.set_defaults(func=set_nvmf_target_config) + def nvmf_create_target(args): + print_dict(rpc.nvmf.nvmf_create_target(args.client, + name=args.name, + max_subsystems=args.max_subsystems)) + + p = subparsers.add_parser('nvmf_create_target', help='Create a new NVMe-oF target') + p.add_argument('-n', '--name', help='Target name (unique to application)', type=str, required=True) + p.add_argument('-s', '--max-subsystems', help='Max number of NVMf subsystems defaults to SPDK_NVMF_DEFAULT_MAX_SUBSYSTEMS', + type=int, required=False) + p.set_defaults(func=nvmf_create_target) + def nvmf_create_transport(args): rpc.nvmf.nvmf_create_transport(args.client, trtype=args.trtype, diff --git a/scripts/rpc/nvmf.py b/scripts/rpc/nvmf.py index d92a76cb8..53736f5e6 100644 --- a/scripts/rpc/nvmf.py +++ b/scripts/rpc/nvmf.py @@ -35,6 +35,25 @@ def set_nvmf_target_config(client, return client.call('set_nvmf_target_config', params) +def nvmf_create_target(client, + name, + max_subsystems=0): + """Create a new NVMe-oF Target. + + Args: + name: Must be unique within the application + max_subsystems: Maximum number of NVMe-oF subsystems (e.g. 1024). default: 0 (Uses SPDK_NVMF_DEFAULT_MAX_SUBSYSTEMS). + + Returns: + The name of the new target. + """ + params = {} + + params['name'] = name + params['max_subsystems'] = max_subsystems + return client.call("nvmf_create_target", params) + + def nvmf_create_transport(client, trtype, tgt_name=None,