Commit f8433aad authored by Seth Howell's avatar Seth Howell Committed by Jim Harris
Browse files

rpc/nvmf: add tgt_name options to relevant RPCs.



All of the RPCs in lib/nvmf/nvmf_rpc.c rely on knowing which nvmf_tgt
they should work with. They have historically relied on the assumption
that there will only be a single target in a given application. This is
true for the example application in the spdk repo, but it is not
necessarily true generally,

By adding an option tgt_name parameter to the RPCs we enable them for
multi-target NVMe-oF applications. We also further reduce the coupling
between the library and the example application.

Change-Id: I03b6695da05a42af3024842ed87d2ce2c296f33f
Signed-off-by: default avatarSeth Howell <seth.howell@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/465442


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarBroadcom SPDK FC-NVMe CI <spdk-ci.pdl@broadcom.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarPaul Luse <paul.e.luse@intel.com>
parent a54a6a26
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -13,6 +13,9 @@ retrieve a pointer to an `spdk_nvmf_tgt` object by supplying its name. In the sp
case where an RPC or application only creates a single target, this function can accept
a null name parameter and will return the only available target.

The majority of the NVMe-oF RPCs now accept an optional tgt_name parameter. This will
allow those RPCs to work with applications that create more than one target.

### nvme

Added `no_shn_notification` to NVMe controller initialization options, users can enable
+18 −3
Original line number Diff line number Diff line
@@ -3648,6 +3648,7 @@ Initialize an NVMe-oF transport with the given options.
Name                        | Optional | Type    | Description
--------------------------- | -------- | --------| -----------
trtype                      | Required | string  | Transport type (ex. RDMA)
tgt_name                    | Optional | string  | Parent NVMe-oF target name.
max_queue_depth             | Optional | number  | Max number of outstanding I/O per queue
max_qpairs_per_ctrlr        | Optional | number  | Max number of SQ and CQ per controller
in_capsule_data_size        | Optional | number  | Max number of in-capsule data size
@@ -3692,7 +3693,9 @@ Example response:

### Parameters

This method has no parameters.
Name                        | Optional | Type        | Description
--------------------------- | -------- | ------------| -----------
tgt_name                    | Optional | string      | Parent NVMe-oF target name.

### Example

@@ -3755,6 +3758,7 @@ Construct an NVMe over Fabrics target subsystem.
Name                    | Optional | Type        | Description
----------------------- | -------- | ----------- | -----------
nqn                     | Required | string      | Subsystem NQN
tgt_name                | Optional | string      | Parent NVMe-oF target name.
serial_number           | Optional | string      | Serial number of virtual controller
model_number            | Optional | string      | Model number of virtual controller
max_namespaces          | Optional | number      | Maximum number of namespaces that can be attached to the subsystem. Default: 0 (Unlimited)
@@ -3797,6 +3801,7 @@ Delete an existing NVMe-oF subsystem.
Parameter              | Optional | Type        | Description
---------------------- | -------- | ----------- | -----------
nqn                    | Required | string      | Subsystem NQN to delete.
tgt_name               | Optional | string      | Parent NVMe-oF target name.

### Example

@@ -3832,6 +3837,7 @@ Add a new listen address to an NVMe-oF subsystem.
Name                    | Optional | Type        | Description
----------------------- | -------- | ----------- | -----------
nqn                     | Required | string      | Subsystem NQN
tgt_name                | Optional | string      | Parent NVMe-oF target name.
listen_address          | Required | object      | @ref rpc_nvmf_listen_address object

### listen_address {#rpc_nvmf_listen_address}
@@ -3884,6 +3890,7 @@ Name | Optional | Type | Description
----------------------- | -------- | ----------- | -----------
nqn                     | Required | string      | Subsystem NQN
namespace               | Required | object      | @ref rpc_nvmf_namespace object
tgt_name                | Optional | string      | Parent NVMe-oF target name.

### namespace {#rpc_nvmf_namespace}

@@ -3936,6 +3943,7 @@ Name | Optional | Type | Description
----------------------- | -------- | ----------- | -----------
nqn                     | Required | string      | Subsystem NQN
nsid                    | Required | number      | Namespace ID
tgt_name                | Optional | string      | Parent NVMe-oF target name.

### Example

@@ -3973,6 +3981,7 @@ Name | Optional | Type | Description
----------------------- | -------- | ----------- | -----------
nqn                     | Required | string      | Subsystem NQN
host                    | Required | string      | Host NQN to add to the list of allowed host NQNs
tgt_name                | Optional | string      | Parent NVMe-oF target name.

### Example

@@ -4010,6 +4019,7 @@ Name | Optional | Type | Description
----------------------- | -------- | ----------- | -----------
nqn                     | Required | string      | Subsystem NQN
host                    | Required | string      | Host NQN to remove from the list of allowed host NQNs
tgt_name                | Optional | string      | Parent NVMe-oF target name.

### Example

@@ -4047,6 +4057,7 @@ Name | Optional | Type | Description
----------------------- | -------- | ----------- | -----------
nqn                     | Required | string      | Subsystem NQN
allow_any_host          | Required | boolean     | Allow any host (`true`) or enforce allowed host whitelist (`false`).
tgt_name                | Optional | string      | Parent NVMe-oF target name.

### Example

@@ -4150,7 +4161,9 @@ Example response:

### Parameters

This method has no parameters.
Name                        | Optional | Type        | Description
--------------------------- | -------- | ------------| -----------
tgt_name                    | Optional | string      | Parent NVMe-oF target name.

### Example

@@ -4189,7 +4202,9 @@ Retrieve current statistics of the NVMf subsystem.

### Parameters

This method has no parameters.
Name                        | Optional | Type        | Description
--------------------------- | -------- | ------------| -----------
tgt_name                    | Optional | string      | Parent NVMe-oF target name.

### Response

+105 −32
Original line number Diff line number Diff line
@@ -182,6 +182,14 @@ decode_ns_uuid(const struct spdk_json_val *val, void *out)
	return rc;
}

struct rpc_get_subsystem {
	char *tgt_name;
};

static const struct spdk_json_object_decoder rpc_get_subsystem_decoders[] = {
	{"tgt_name", offsetof(struct rpc_get_subsystem, tgt_name), spdk_json_decode_string, true},
};

static void
dump_nvmf_subsystem(struct spdk_json_write_ctx *w, struct spdk_nvmf_subsystem *subsystem)
{
@@ -294,20 +302,26 @@ static void
spdk_rpc_get_nvmf_subsystems(struct spdk_jsonrpc_request *request,
			     const struct spdk_json_val *params)
{
	struct rpc_get_subsystem req = { 0 };
	struct spdk_json_write_ctx *w;
	struct spdk_nvmf_subsystem *subsystem;
	struct spdk_nvmf_tgt *tgt;

	if (params != NULL) {
		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
						 "get_nvmf_subsystems requires no parameters");
	if (params) {
		if (spdk_json_decode_object(params, rpc_get_subsystem_decoders,
					    SPDK_COUNTOF(rpc_get_subsystem_decoders),
					    &req)) {
			SPDK_ERRLOG("spdk_json_decode_object failed\n");
			spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
			return;
		}
	}

	tgt = spdk_nvmf_get_tgt(NULL);
	tgt = spdk_nvmf_get_tgt(req.tgt_name);
	if (!tgt) {
		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
						 "Unable to find a target.");
		free(req.tgt_name);
		return;
	}

@@ -320,6 +334,7 @@ spdk_rpc_get_nvmf_subsystems(struct spdk_jsonrpc_request *request,
	}
	spdk_json_write_array_end(w);
	spdk_jsonrpc_end_result(request, w);
	free(req.tgt_name);
}
SPDK_RPC_REGISTER("get_nvmf_subsystems", spdk_rpc_get_nvmf_subsystems, SPDK_RPC_RUNTIME)

@@ -327,6 +342,7 @@ struct rpc_subsystem_create {
	char *nqn;
	char *serial_number;
	char *model_number;
	char *tgt_name;
	uint32_t max_namespaces;
	bool allow_any_host;
};
@@ -335,6 +351,7 @@ static const struct spdk_json_object_decoder rpc_subsystem_create_decoders[] = {
	{"nqn", offsetof(struct rpc_subsystem_create, nqn), spdk_json_decode_string},
	{"serial_number", offsetof(struct rpc_subsystem_create, serial_number), spdk_json_decode_string, true},
	{"model_number", offsetof(struct rpc_subsystem_create, model_number), spdk_json_decode_string, true},
	{"tgt_name", offsetof(struct rpc_subsystem_create, tgt_name), spdk_json_decode_string, true},
	{"max_namespaces", offsetof(struct rpc_subsystem_create, max_namespaces), spdk_json_decode_uint32, true},
	{"allow_any_host", offsetof(struct rpc_subsystem_create, allow_any_host), spdk_json_decode_bool, true},
};
@@ -371,7 +388,7 @@ spdk_rpc_nvmf_subsystem_create(struct spdk_jsonrpc_request *request,
		goto invalid;
	}

	tgt = spdk_nvmf_get_tgt(NULL);
	tgt = spdk_nvmf_get_tgt(req->tgt_name);
	if (!tgt) {
		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
						 "Unable to find a target.");
@@ -401,6 +418,7 @@ spdk_rpc_nvmf_subsystem_create(struct spdk_jsonrpc_request *request,
	spdk_nvmf_subsystem_set_allow_any_host(subsystem, req->allow_any_host);

	free(req->nqn);
	free(req->tgt_name);
	free(req->serial_number);
	free(req->model_number);
	free(req);
@@ -416,6 +434,7 @@ invalid:
invalid_custom_response:
	if (req) {
		free(req->nqn);
		free(req->tgt_name);
		free(req->serial_number);
		free(req->model_number);
	}
@@ -425,12 +444,14 @@ SPDK_RPC_REGISTER("nvmf_subsystem_create", spdk_rpc_nvmf_subsystem_create, SPDK_

struct rpc_delete_subsystem {
	char *nqn;
	char *tgt_name;
};

static void
free_rpc_delete_subsystem(struct rpc_delete_subsystem *r)
{
	free(r->nqn);
	free(r->tgt_name);
}

static void
@@ -449,13 +470,14 @@ spdk_rpc_nvmf_subsystem_stopped(struct spdk_nvmf_subsystem *subsystem,

static const struct spdk_json_object_decoder rpc_delete_subsystem_decoders[] = {
	{"nqn", offsetof(struct rpc_delete_subsystem, nqn), spdk_json_decode_string},
	{"tgt_name", offsetof(struct rpc_delete_subsystem, tgt_name), spdk_json_decode_string, true},
};

static void
spdk_rpc_delete_nvmf_subsystem(struct spdk_jsonrpc_request *request,
			       const struct spdk_json_val *params)
{
	struct rpc_delete_subsystem req = {};
	struct rpc_delete_subsystem req = { 0 };
	struct spdk_nvmf_subsystem *subsystem;
	struct spdk_nvmf_tgt *tgt;

@@ -471,7 +493,7 @@ spdk_rpc_delete_nvmf_subsystem(struct spdk_jsonrpc_request *request,
		goto invalid;
	}

	tgt = spdk_nvmf_get_tgt(NULL);
	tgt = spdk_nvmf_get_tgt(req.tgt_name);
	if (!tgt) {
		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
						 "Unable to find a target.");
@@ -551,6 +573,7 @@ enum nvmf_rpc_listen_op {

struct nvmf_rpc_listener_ctx {
	char				*nqn;
	char				*tgt_name;
	struct spdk_nvmf_tgt		*tgt;
	struct spdk_nvmf_subsystem	*subsystem;
	struct rpc_listen_address	address;
@@ -564,12 +587,14 @@ struct nvmf_rpc_listener_ctx {
static const struct spdk_json_object_decoder nvmf_rpc_listener_decoder[] = {
	{"nqn", offsetof(struct nvmf_rpc_listener_ctx, nqn), spdk_json_decode_string},
	{"listen_address", offsetof(struct nvmf_rpc_listener_ctx, address), decode_rpc_listen_address},
	{"tgt_name", offsetof(struct nvmf_rpc_listener_ctx, tgt_name), spdk_json_decode_string, true},
};

static void
nvmf_rpc_listener_ctx_free(struct nvmf_rpc_listener_ctx *ctx)
{
	free(ctx->nqn);
	free(ctx->tgt_name);
	free_rpc_listen_address(&ctx->address);
	free(ctx);
}
@@ -719,7 +744,7 @@ spdk_rpc_nvmf_subsystem_add_listener(struct spdk_jsonrpc_request *request,
		return;
	}

	tgt = spdk_nvmf_get_tgt(NULL);
	tgt = spdk_nvmf_get_tgt(ctx->tgt_name);
	if (!tgt) {
		SPDK_ERRLOG("Unable to find a target object.\n");
		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
@@ -782,7 +807,7 @@ spdk_rpc_nvmf_subsystem_remove_listener(struct spdk_jsonrpc_request *request,
		return;
	}

	tgt = spdk_nvmf_get_tgt(NULL);
	tgt = spdk_nvmf_get_tgt(ctx->tgt_name);
	if (!tgt) {
		SPDK_ERRLOG("Unable to find a target object.\n");
		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
@@ -857,6 +882,7 @@ decode_rpc_ns_params(const struct spdk_json_val *val, void *out)

struct nvmf_rpc_ns_ctx {
	char *nqn;
	char *tgt_name;
	struct spdk_nvmf_ns_params ns_params;

	struct spdk_jsonrpc_request *request;
@@ -866,12 +892,14 @@ struct nvmf_rpc_ns_ctx {
static const struct spdk_json_object_decoder nvmf_rpc_subsystem_ns_decoder[] = {
	{"nqn", offsetof(struct nvmf_rpc_ns_ctx, nqn), spdk_json_decode_string},
	{"namespace", offsetof(struct nvmf_rpc_ns_ctx, ns_params), decode_rpc_ns_params},
	{"tgt_name", offsetof(struct nvmf_rpc_ns_ctx, tgt_name), spdk_json_decode_string, true},
};

static void
nvmf_rpc_ns_ctx_free(struct nvmf_rpc_ns_ctx *ctx)
{
	free(ctx->nqn);
	free(ctx->tgt_name);
	free(ctx->ns_params.bdev_name);
	free(ctx->ns_params.ptpl_file);
	free(ctx);
@@ -972,7 +1000,7 @@ spdk_rpc_nvmf_subsystem_add_ns(struct spdk_jsonrpc_request *request,
	ctx->request = request;
	ctx->response_sent = false;

	tgt = spdk_nvmf_get_tgt(NULL);
	tgt = spdk_nvmf_get_tgt(ctx->tgt_name);
	if (!tgt) {
		SPDK_ERRLOG("Unable to find a target object.\n");
		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
@@ -999,6 +1027,7 @@ SPDK_RPC_REGISTER("nvmf_subsystem_add_ns", spdk_rpc_nvmf_subsystem_add_ns, SPDK_

struct nvmf_rpc_remove_ns_ctx {
	char *nqn;
	char *tgt_name;
	uint32_t nsid;

	struct spdk_jsonrpc_request *request;
@@ -1008,12 +1037,14 @@ struct nvmf_rpc_remove_ns_ctx {
static const struct spdk_json_object_decoder nvmf_rpc_subsystem_remove_ns_decoder[] = {
	{"nqn", offsetof(struct nvmf_rpc_remove_ns_ctx, nqn), spdk_json_decode_string},
	{"nsid", offsetof(struct nvmf_rpc_remove_ns_ctx, nsid), spdk_json_decode_uint32},
	{"tgt_name", offsetof(struct nvmf_rpc_remove_ns_ctx, tgt_name), spdk_json_decode_string, true},
};

static void
nvmf_rpc_remove_ns_ctx_free(struct nvmf_rpc_remove_ns_ctx *ctx)
{
	free(ctx->nqn);
	free(ctx->tgt_name);
	free(ctx);
}

@@ -1084,7 +1115,7 @@ spdk_rpc_nvmf_subsystem_remove_ns(struct spdk_jsonrpc_request *request,
		return;
	}

	tgt = spdk_nvmf_get_tgt(NULL);
	tgt = spdk_nvmf_get_tgt(ctx->tgt_name);
	if (!tgt) {
		SPDK_ERRLOG("Unable to find a target object.\n");
		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
@@ -1123,6 +1154,7 @@ struct nvmf_rpc_host_ctx {

	char *nqn;
	char *host;
	char *tgt_name;

	enum nvmf_rpc_host_op op;

@@ -1134,6 +1166,7 @@ struct nvmf_rpc_host_ctx {
static const struct spdk_json_object_decoder nvmf_rpc_subsystem_host_decoder[] = {
	{"nqn", offsetof(struct nvmf_rpc_host_ctx, nqn), spdk_json_decode_string},
	{"host", offsetof(struct nvmf_rpc_host_ctx, host), spdk_json_decode_string},
	{"tgt_name", offsetof(struct nvmf_rpc_host_ctx, tgt_name), spdk_json_decode_string, true},
};

static void
@@ -1141,6 +1174,7 @@ nvmf_rpc_host_ctx_free(struct nvmf_rpc_host_ctx *ctx)
{
	free(ctx->nqn);
	free(ctx->host);
	free(ctx->tgt_name);
	free(ctx);
}

@@ -1221,7 +1255,7 @@ spdk_rpc_nvmf_subsystem_add_host(struct spdk_jsonrpc_request *request,
		return;
	}

	tgt = spdk_nvmf_get_tgt(NULL);
	tgt = spdk_nvmf_get_tgt(ctx->tgt_name);
	if (!tgt) {
		SPDK_ERRLOG("Unable to find a target object.\n");
		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
@@ -1273,7 +1307,7 @@ spdk_rpc_nvmf_subsystem_remove_host(struct spdk_jsonrpc_request *request,
		return;
	}

	tgt = spdk_nvmf_get_tgt(NULL);
	tgt = spdk_nvmf_get_tgt(ctx->tgt_name);
	if (!tgt) {
		SPDK_ERRLOG("Unable to find a target object.\n");
		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
@@ -1307,6 +1341,7 @@ SPDK_RPC_REGISTER("nvmf_subsystem_remove_host", spdk_rpc_nvmf_subsystem_remove_h
static const struct spdk_json_object_decoder nvmf_rpc_subsystem_any_host_decoder[] = {
	{"nqn", offsetof(struct nvmf_rpc_host_ctx, nqn), spdk_json_decode_string},
	{"allow_any_host", offsetof(struct nvmf_rpc_host_ctx, allow_any_host), spdk_json_decode_bool},
	{"tgt_name", offsetof(struct nvmf_rpc_host_ctx, tgt_name), spdk_json_decode_string, true},
};

static void
@@ -1332,7 +1367,7 @@ spdk_rpc_nvmf_subsystem_allow_any_host(struct spdk_jsonrpc_request *request,
		return;
	}

	tgt = spdk_nvmf_get_tgt(NULL);
	tgt = spdk_nvmf_get_tgt(ctx->tgt_name);
	if (!tgt) {
		SPDK_ERRLOG("Unable to find a target object.\n");
		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
@@ -1364,6 +1399,7 @@ SPDK_RPC_REGISTER("nvmf_subsystem_allow_any_host", spdk_rpc_nvmf_subsystem_allow

struct nvmf_rpc_create_transport_ctx {
	char				*trtype;
	char				*tgt_name;
	struct spdk_nvmf_transport_opts	opts;
	struct spdk_jsonrpc_request	*request;
};
@@ -1422,12 +1458,17 @@ static const struct spdk_json_object_decoder nvmf_rpc_create_transport_decoder[]
		"sock_priority", offsetof(struct nvmf_rpc_create_transport_ctx, opts.sock_priority),
		spdk_json_decode_uint32, true
	},
	{
		"tgt_name", offsetof(struct nvmf_rpc_create_transport_ctx, tgt_name),
		spdk_json_decode_string, true
	},
};

static void
nvmf_rpc_create_transport_ctx_free(struct nvmf_rpc_create_transport_ctx *ctx)
{
	free(ctx->trtype);
	free(ctx->tgt_name);
	free(ctx);
}

@@ -1479,7 +1520,7 @@ spdk_rpc_nvmf_create_transport(struct spdk_jsonrpc_request *request,
		return;
	}

	tgt = spdk_nvmf_get_tgt(NULL);
	tgt = spdk_nvmf_get_tgt(ctx->tgt_name);
	if (!tgt) {
		SPDK_ERRLOG("Unable to find a target object.\n");
		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
@@ -1573,24 +1614,38 @@ dump_nvmf_transport(struct spdk_json_write_ctx *w, struct spdk_nvmf_transport *t
	spdk_json_write_object_end(w);
}

struct rpc_get_transport {
	char *tgt_name;
};

static const struct spdk_json_object_decoder rpc_get_transport_decoders[] = {
	{"tgt_name", offsetof(struct rpc_get_transport, tgt_name), spdk_json_decode_string, true},
};

static void
spdk_rpc_get_nvmf_transports(struct spdk_jsonrpc_request *request,
			     const struct spdk_json_val *params)
{
	struct rpc_get_transport req = { 0 };
	struct spdk_json_write_ctx *w;
	struct spdk_nvmf_transport *transport;
	struct spdk_nvmf_tgt *tgt;

	if (params != NULL) {
		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
						 "get_nvmf_transports requires no parameters");
	if (params) {
		if (spdk_json_decode_object(params, rpc_get_transport_decoders,
					    SPDK_COUNTOF(rpc_get_transport_decoders),
					    &req)) {
			SPDK_ERRLOG("spdk_json_decode_object failed\n");
			spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
			return;
		}
	}

	tgt = spdk_nvmf_get_tgt(NULL);
	tgt = spdk_nvmf_get_tgt(req.tgt_name);
	if (!tgt) {
		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
						 "Unable to find a target.");
		free(req.tgt_name);
		return;
	}

@@ -1603,15 +1658,28 @@ spdk_rpc_get_nvmf_transports(struct spdk_jsonrpc_request *request,
	}
	spdk_json_write_array_end(w);
	spdk_jsonrpc_end_result(request, w);
	free(req.tgt_name);
}
SPDK_RPC_REGISTER("get_nvmf_transports", spdk_rpc_get_nvmf_transports, SPDK_RPC_RUNTIME)

struct rpc_nvmf_get_stats_ctx {
	char *tgt_name;
	struct spdk_nvmf_tgt *tgt;
	struct spdk_jsonrpc_request *request;
	struct spdk_json_write_ctx *w;
};

static const struct spdk_json_object_decoder rpc_get_stats_decoders[] = {
	{"tgt_name", offsetof(struct rpc_nvmf_get_stats_ctx, tgt_name), spdk_json_decode_string, true},
};

static void
free_get_stats_ctx(struct rpc_nvmf_get_stats_ctx *ctx)
{
	free(ctx->tgt_name);
	free(ctx);
}

static void
rpc_nvmf_get_stats_done(struct spdk_io_channel_iter *i, int status)
{
@@ -1620,7 +1688,7 @@ rpc_nvmf_get_stats_done(struct spdk_io_channel_iter *i, int status)
	spdk_json_write_array_end(ctx->w);
	spdk_json_write_object_end(ctx->w);
	spdk_jsonrpc_end_result(ctx->request, ctx->w);
	free(ctx);
	free_get_stats_ctx(ctx);
}

static void
@@ -1705,12 +1773,6 @@ spdk_rpc_nvmf_get_stats(struct spdk_jsonrpc_request *request,
{
	struct rpc_nvmf_get_stats_ctx *ctx;

	if (params) {
		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
						 "'nvmf_get_stats' requires no arguments");
		return;
	}

	ctx = calloc(1, sizeof(*ctx));
	if (!ctx) {
		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
@@ -1719,17 +1781,28 @@ spdk_rpc_nvmf_get_stats(struct spdk_jsonrpc_request *request,
	}
	ctx->request = request;

	ctx->tgt = spdk_nvmf_get_tgt(NULL);
	if (params) {
		if (spdk_json_decode_object(params, rpc_get_stats_decoders,
					    SPDK_COUNTOF(rpc_get_stats_decoders),
					    ctx)) {
			SPDK_ERRLOG("spdk_json_decode_object failed\n");
			spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
			free_get_stats_ctx(ctx);
			return;
		}
	}

	ctx->tgt = spdk_nvmf_get_tgt(ctx->tgt_name);
	if (!ctx->tgt) {
		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
						 "Unable to find a target.");
		free(ctx);
		free_get_stats_ctx(ctx);
		return;
	}

	ctx->w = spdk_jsonrpc_begin_result(ctx->request);
	if (NULL == ctx->w) {
		free(ctx);
		free_get_stats_ctx(ctx);
		return;
	}

+31 −8

File changed.

Preview size limit exceeded, changes collapsed.

+87 −14
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ def set_nvmf_target_config(client,

def nvmf_create_transport(client,
                          trtype,
                          tgt_name=None,
                          max_queue_depth=None,
                          max_qpairs_per_ctrlr=None,
                          in_capsule_data_size=None,
@@ -73,6 +74,8 @@ def nvmf_create_transport(client,
    params = {}

    params['trtype'] = trtype
    if tgt_name:
        params['tgt_name'] = tgt_name
    if max_queue_depth:
        params['max_queue_depth'] = max_queue_depth
    if max_qpairs_per_ctrlr:
@@ -102,27 +105,48 @@ def nvmf_create_transport(client,
    return client.call('nvmf_create_transport', params)


def get_nvmf_transports(client):
def get_nvmf_transports(client, tgt_name=None):
    """Get list of NVMe-oF transports.
    Args:
        tgt_name: name of the parent NVMe-oF target (optional).

    Returns:
        List of NVMe-oF transport objects.
    """
    return client.call('get_nvmf_transports')

    params = {}

    if tgt_name:
        params = {
            'tgt_name': tgt_name,
        }

    return client.call('get_nvmf_transports', params)

def get_nvmf_subsystems(client):

def get_nvmf_subsystems(client, tgt_name=None):
    """Get list of NVMe-oF subsystems.
    Args:
        tgt_name: name of the parent NVMe-oF target (optional).

    Returns:
        List of NVMe-oF subsystem objects.
    """
    return client.call('get_nvmf_subsystems')

    params = {}

    if tgt_name:
        params = {
            'tgt_name': tgt_name,
        }

    return client.call('get_nvmf_subsystems', params)


def nvmf_subsystem_create(client,
                          nqn,
                          serial_number,
                          tgt_name=None,
                          model_number='SPDK bdev Controller',
                          allow_any_host=False,
                          max_namespaces=0):
@@ -130,6 +154,7 @@ def nvmf_subsystem_create(client,

    Args:
        nqn: Subsystem NQN.
        tgt_name: name of the parent NVMe-oF target (optional).
        serial_number: Serial number of virtual controller.
        model_number: Model number of virtual controller.
        allow_any_host: Allow any host (True) or enforce allowed host whitelist (False). Default: False.
@@ -154,10 +179,13 @@ def nvmf_subsystem_create(client,
    if max_namespaces:
        params['max_namespaces'] = max_namespaces

    if tgt_name:
        params['tgt_name'] = tgt_name

    return client.call('nvmf_subsystem_create', params)


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

    Args:
@@ -165,6 +193,7 @@ def nvmf_subsystem_add_listener(client, nqn, trtype, traddr, trsvcid, adrfam):
        trtype: Transport type ("RDMA").
        traddr: Transport address.
        trsvcid: Transport service ID.
        tgt_name: name of the parent NVMe-oF target (optional).
        adrfam: Address family ("IPv4", "IPv6", "IB", or "FC").

    Returns:
@@ -180,6 +209,9 @@ def nvmf_subsystem_add_listener(client, nqn, trtype, traddr, trsvcid, adrfam):
    params = {'nqn': nqn,
              'listen_address': listen_address}

    if tgt_name:
        params['tgt_name'] = tgt_name

    return client.call('nvmf_subsystem_add_listener', params)


@@ -189,7 +221,8 @@ def nvmf_subsystem_remove_listener(
        trtype,
        traddr,
        trsvcid,
        adrfam):
        adrfam,
        tgt_name=None):
    """Remove existing listen address from an NVMe-oF subsystem.

    Args:
@@ -197,6 +230,7 @@ def nvmf_subsystem_remove_listener(
        trtype: Transport type ("RDMA").
        traddr: Transport address.
        trsvcid: Transport service ID.
        tgt_name: name of the parent NVMe-oF target (optional).
        adrfam: Address family ("IPv4", "IPv6", "IB", or "FC").

    Returns:
@@ -212,15 +246,19 @@ def nvmf_subsystem_remove_listener(
    params = {'nqn': nqn,
              'listen_address': listen_address}

    if tgt_name:
        params['tgt_name'] = tgt_name

    return client.call('nvmf_subsystem_remove_listener', params)


def nvmf_subsystem_add_ns(client, nqn, bdev_name, ptpl_file=None, nsid=None, nguid=None, eui64=None, uuid=None):
def nvmf_subsystem_add_ns(client, nqn, bdev_name, tgt_name=None, ptpl_file=None, nsid=None, nguid=None, eui64=None, uuid=None):
    """Add a namespace to a subsystem.

    Args:
        nqn: Subsystem NQN.
        bdev_name: Name of bdev to expose as a namespace.
        tgt_name: name of the parent NVMe-oF target (optional).
        nsid: Namespace ID (optional).
        nguid: 16-byte namespace globally unique identifier in hexadecimal (optional).
        eui64: 8-byte namespace EUI-64 in hexadecimal (e.g. "ABCDEF0123456789") (optional).
@@ -249,15 +287,19 @@ def nvmf_subsystem_add_ns(client, nqn, bdev_name, ptpl_file=None, nsid=None, ngu
    params = {'nqn': nqn,
              'namespace': ns}

    if tgt_name:
        params['tgt_name'] = tgt_name

    return client.call('nvmf_subsystem_add_ns', params)


def nvmf_subsystem_remove_ns(client, nqn, nsid):
def nvmf_subsystem_remove_ns(client, nqn, nsid, tgt_name=None):
    """Remove a existing namespace from a subsystem.

    Args:
        nqn: Subsystem NQN.
        nsid: Namespace ID.
        tgt_name: name of the parent NVMe-oF target (optional).

    Returns:
        True or False
@@ -265,15 +307,19 @@ def nvmf_subsystem_remove_ns(client, nqn, nsid):
    params = {'nqn': nqn,
              'nsid': nsid}

    if tgt_name:
        params['tgt_name'] = tgt_name

    return client.call('nvmf_subsystem_remove_ns', params)


def nvmf_subsystem_add_host(client, nqn, host):
def nvmf_subsystem_add_host(client, nqn, host, tgt_name=None):
    """Add a host NQN to the whitelist of allowed hosts.

    Args:
        nqn: Subsystem NQN.
        host: Host NQN to add to the list of allowed host NQNs
        tgt_name: name of the parent NVMe-oF target (optional).

    Returns:
        True or False
@@ -281,15 +327,19 @@ def nvmf_subsystem_add_host(client, nqn, host):
    params = {'nqn': nqn,
              'host': host}

    if tgt_name:
        params['tgt_name'] = tgt_name

    return client.call('nvmf_subsystem_add_host', params)


def nvmf_subsystem_remove_host(client, nqn, host):
def nvmf_subsystem_remove_host(client, nqn, host, tgt_name=None):
    """Remove a host NQN from the whitelist of allowed hosts.

    Args:
        nqn: Subsystem NQN.
        host: Host NQN to remove to the list of allowed host NQNs
        tgt_name: name of the parent NVMe-oF target (optional).

    Returns:
        True or False
@@ -297,41 +347,64 @@ def nvmf_subsystem_remove_host(client, nqn, host):
    params = {'nqn': nqn,
              'host': host}

    if tgt_name:
        params['tgt_name'] = tgt_name

    return client.call('nvmf_subsystem_remove_host', params)


def nvmf_subsystem_allow_any_host(client, nqn, disable):
def nvmf_subsystem_allow_any_host(client, nqn, disable, tgt_name=None):
    """Configure a subsystem to allow any host to connect or to enforce the host NQN whitelist.

    Args:
        nqn: Subsystem NQN.
        disable: Allow any host (true) or enforce allowed host whitelist (false).
        tgt_name: name of the parent NVMe-oF target (optional).

    Returns:
        True or False
    """
    params = {'nqn': nqn, 'allow_any_host': False if disable else True}

    if tgt_name:
        params['tgt_name'] = tgt_name

    return client.call('nvmf_subsystem_allow_any_host', params)


def delete_nvmf_subsystem(client, nqn):
def delete_nvmf_subsystem(client, nqn, tgt_name=None):
    """Delete an existing NVMe-oF subsystem.

    Args:
        nqn: Subsystem NQN.
        tgt_name: name of the parent NVMe-oF target (optional).

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

    if tgt_name:
        params['tgt_name'] = tgt_name

    return client.call('delete_nvmf_subsystem', params)


def nvmf_get_stats(client):
def nvmf_get_stats(client, tgt_name=None):
    """Query NVMf statistics.

    Args:
        tgt_name: name of the parent NVMe-oF target (optional).

    Returns:
        Current NVMf statistics.
    """
    return client.call('nvmf_get_stats')

    params = {}

    if tgt_name:
        params = {
            'tgt_name': tgt_name,
        }

    return client.call('nvmf_get_stats', params)