Commit 6d87bc7a authored by Jacek Kalwas's avatar Jacek Kalwas Committed by Tomasz Zawadzki
Browse files

nvmf: allow transport specific options within subsystem



Change-Id: Id7b7d5205b468237df4c98715ce8d7bc26145f63
Signed-off-by: default avatarJacek Kalwas <jacek.kalwas@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4246


Community-CI: Broadcom CI
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarAleksey Marchuk <alexeymar@mellanox.com>
parent 90472b86
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -213,6 +213,12 @@ struct spdk_nvmf_transport_ops {
	 */
	void (*opts_init)(struct spdk_nvmf_transport_opts *opts);

	/**
	 * Parse a subsystem opts
	 */
	int (*subsystem_opts_parse)(struct spdk_nvmf_transport *transport,
				    const struct spdk_nvmf_subsystem *subsystem, const struct spdk_json_val *opts);

	/**
	 * Create a transport for the given transport opts
	 */
+89 −0
Original line number Diff line number Diff line
@@ -457,6 +457,95 @@ cleanup:
SPDK_RPC_REGISTER("nvmf_create_subsystem", rpc_nvmf_create_subsystem, SPDK_RPC_RUNTIME)
SPDK_RPC_REGISTER_ALIAS_DEPRECATED(nvmf_create_subsystem, nvmf_subsystem_create)

struct rpc_subsystem_set_options {
	char *nqn;
	char *tgt_name;
	char *trtype;
};

static const struct spdk_json_object_decoder rpc_subsystem_set_options_decoders[] = {
	{"nqn", offsetof(struct rpc_subsystem_set_options, nqn), spdk_json_decode_string},
	{"tgt_name", offsetof(struct rpc_subsystem_set_options, tgt_name), spdk_json_decode_string, true},
	{"trtype", offsetof(struct rpc_subsystem_set_options, trtype), spdk_json_decode_string},
};

static void
rpc_nvmf_subsystem_set_options(struct spdk_jsonrpc_request *request,
			       const struct spdk_json_val *params)
{
	struct rpc_subsystem_set_options *req;
	struct spdk_nvmf_subsystem *subsystem;
	struct spdk_nvmf_transport *transport;
	struct spdk_json_write_ctx *w;
	struct spdk_nvmf_tgt *tgt;
	int rc;

	req = calloc(1, sizeof(*req));
	if (!req) {
		SPDK_ERRLOG("Memory allocation failed\n");
		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
						 "Memory allocation failed");
		return;
	}

	if (spdk_json_decode_object_relaxed(params, rpc_subsystem_set_options_decoders,
					    SPDK_COUNTOF(rpc_subsystem_set_options_decoders), req)) {
		SPDK_ERRLOG("spdk_json_decode_object_relaxed failed\n");
		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
		goto cleanup;
	}

	tgt = spdk_nvmf_get_tgt(req->tgt_name);
	if (!tgt) {
		SPDK_ERRLOG("Unable to find target %s\n", req->tgt_name);
		spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
						     "Unable to find target %s", req->tgt_name);
		goto cleanup;
	}

	subsystem = spdk_nvmf_tgt_find_subsystem(tgt, req->nqn);
	if (!subsystem) {
		SPDK_ERRLOG("Unable to find subsystem with NQN %s\n", req->nqn);
		spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
						     "Unable to find subsystem with NQN %s", req->nqn);
		goto cleanup;
	}

	transport = spdk_nvmf_tgt_get_transport(tgt, req->trtype);
	if (!transport) {
		SPDK_ERRLOG("Unable to find transport with trtype %s\n", req->trtype);
		spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
						     "Unable to find transport with trtype %s", req->trtype);
		goto cleanup;
	}

	if (!transport->ops->subsystem_opts_parse) {
		SPDK_ERRLOG("Unable to find transport ops\n");
		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
						 "Unable to find transport ops");
		goto cleanup;
	}

	rc = transport->ops->subsystem_opts_parse(transport, subsystem, params);
	if (rc) {
		SPDK_ERRLOG("Unable to parse opts %d\n", rc);
		spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
						     "Unable to parse opts %d", rc);
		goto cleanup;
	}

	w = spdk_jsonrpc_begin_result(request);
	spdk_json_write_bool(w, true);
	spdk_jsonrpc_end_result(request, w);

cleanup:
	free(req->nqn);
	free(req->tgt_name);
	free(req->trtype);
	free(req);
}
SPDK_RPC_REGISTER("nvmf_subsystem_set_options", rpc_nvmf_subsystem_set_options, SPDK_RPC_RUNTIME)

struct rpc_delete_subsystem {
	char *nqn;
	char *tgt_name;
+12 −0
Original line number Diff line number Diff line
@@ -1871,6 +1871,18 @@ Format: 'user:u1 secret:s1 muser:mu1 msecret:ms1,user:u2 secret:s2 muser:mu2 mse
    p.add_argument("-r", "--ana-reporting", action='store_true', help="Enable ANA reporting feature")
    p.set_defaults(func=nvmf_create_subsystem)

    def nvmf_subsystem_set_options(args):
        rpc.nvmf.nvmf_subsystem_set_options(args.client,
                                            nqn=args.nqn,
                                            trtype=args.trtype,
                                            tgt_name=args.tgt_name)

    p = subparsers.add_parser('nvmf_subsystem_set_options', help='Set a transport specific options for an NVMe-oF subsystem')
    p.add_argument('nqn', help='Subsystem NQN (ASCII)')
    p.add_argument('-t', '--trtype', help='NVMe-oF transport type: e.g., rdma, tcp, pcie', required=True)
    p.add_argument('-g', '--tgt_name', help='The name of the parent NVMe-oF target (optional)', type=str)
    p.set_defaults(func=nvmf_subsystem_set_options)

    def nvmf_delete_subsystem(args):
        rpc.nvmf.nvmf_delete_subsystem(args.client,
                                       nqn=args.subsystem_nqn,
+20 −0
Original line number Diff line number Diff line
@@ -263,6 +263,26 @@ def nvmf_create_subsystem(client,
    return client.call('nvmf_create_subsystem', params)


def nvmf_subsystem_set_options(client, nqn, trtype, tgt_name=None):
    """Set a transport specific options for an NVMe-oF subsystem.

    Args:
        nqn: Subsystem NQN.
        trtype: NVMe-oF transport type: e.g., rdma, tcp, pcie.
        tgt_name: The name of the parent NVMe-oF target (optional).

    Returns:
        True or False
    """
    params = {'nqn': nqn,
              'trtype': trtype}

    if tgt_name:
        params['tgt_name'] = tgt_name

    return client.call('nvmf_subsystem_set_options', params)


def nvmf_subsystem_add_listener(client, nqn, trtype, traddr, trsvcid, adrfam, tgt_name=None):
    """Add a new listen address to an NVMe-oF subsystem.