Commit 698b2423 authored by Shuhei Matsumoto's avatar Shuhei Matsumoto Committed by Jim Harris
Browse files

rpc: Add nvmf_subsystem_set_ns_ana_group RPC



Add nvmf_subsystem_set_ana_group RPC to change ANA group ID of a
namespace in a subsystem dynamically.

Probably, we can change ANA group ID safely without pausing subsystem.
However, we pause subsystem as same as other configuration changes for
now.

Signed-off-by: default avatarShuhei Matsumoto <smatsumoto@nvidia.com>
Suggested-by: default avatarLeonid Chernin <leonidc@il.ibm.com>
Tested-by: default avatarLeonid Chernin <leonidc@il.ibm.com>
Change-Id: I6fa4a9560ef75cdf3abb9428849ee2ffcea85136
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/24060


Community-CI: Mellanox Build Bot
Reviewed-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Reviewed-by: default avatarJim Harris <jim.harris@samsung.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
parent 6a5984e8
Loading
Loading
Loading
Loading
+40 −0
Original line number Diff line number Diff line
@@ -8625,6 +8625,46 @@ Example response:
}
~~~

### nvmf_subsystem_set_ns_ana_group method {#rpc_nvmf_subsystem_set_ns_ana_group}

Change ANA group ID of a namespace in a subsystem.

#### Parameters

Name                    | Optional | Type        | Description
----------------------- | -------- | ----------- | -----------
nqn                     | Required | string      | Subsystem NQN
nsid                    | Required | number      | Namespace ID
anagrpid                | Required | number      | ANA group ID
tgt_name                | Optional | string      | Parent NVMe-oF target name.

#### Example

Example request:

~~~json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "nvmf_subsystem_set_ns_ana_group",
  "params": {
    "nqn": "nqn.2016-06.io.spdk:cnode1",
    "nsid": 1,
    "anagrpid": 2
  }
}
~~~

Example response:

~~~json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": true
}
~~~

### nvmf_subsystem_add_host method {#rpc_nvmf_subsystem_add_host}

Add a host NQN to the list of allowed hosts.  Adding an already allowed host will result in an
+118 −0
Original line number Diff line number Diff line
@@ -1580,6 +1580,124 @@ rpc_nvmf_subsystem_add_ns(struct spdk_jsonrpc_request *request,
}
SPDK_RPC_REGISTER("nvmf_subsystem_add_ns", rpc_nvmf_subsystem_add_ns, SPDK_RPC_RUNTIME)

struct nvmf_rpc_ana_group_ctx {
	char *nqn;
	char *tgt_name;
	uint32_t nsid;
	uint32_t anagrpid;

	struct spdk_jsonrpc_request *request;
	bool response_sent;
};

static const struct spdk_json_object_decoder nvmf_rpc_subsystem_ana_group_decoder[] = {
	{"nqn", offsetof(struct nvmf_rpc_ana_group_ctx, nqn), spdk_json_decode_string},
	{"nsid", offsetof(struct nvmf_rpc_ana_group_ctx, nsid), spdk_json_decode_uint32},
	{"anagrpid", offsetof(struct nvmf_rpc_ana_group_ctx, anagrpid), spdk_json_decode_uint32},
	{"tgt_name", offsetof(struct nvmf_rpc_ana_group_ctx, tgt_name), spdk_json_decode_string, true},
};

static void
nvmf_rpc_ana_group_ctx_free(struct nvmf_rpc_ana_group_ctx *ctx)
{
	free(ctx->nqn);
	free(ctx->tgt_name);
	free(ctx);
}

static void
nvmf_rpc_anagrpid_resumed(struct spdk_nvmf_subsystem *subsystem,
			  void *cb_arg, int status)
{
	struct nvmf_rpc_ana_group_ctx *ctx = cb_arg;
	struct spdk_jsonrpc_request *request = ctx->request;
	bool response_sent = ctx->response_sent;

	nvmf_rpc_ana_group_ctx_free(ctx);

	if (response_sent) {
		return;
	}

	spdk_jsonrpc_send_bool_response(request, true);
}

static void
nvmf_rpc_ana_group(struct spdk_nvmf_subsystem *subsystem,
		   void *cb_arg, int status)
{
	struct nvmf_rpc_ana_group_ctx *ctx = cb_arg;
	int rc;

	rc = spdk_nvmf_subsystem_set_ns_ana_group(subsystem, ctx->nsid, ctx->anagrpid);
	if (rc != 0) {
		SPDK_ERRLOG("Unable to change ANA group ID\n");
		spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
						 "Invalid parameters");
		ctx->response_sent = true;
	}

	if (spdk_nvmf_subsystem_resume(subsystem, nvmf_rpc_anagrpid_resumed, ctx)) {
		if (!ctx->response_sent) {
			spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
							 "Internal error");
		}
		nvmf_rpc_ana_group_ctx_free(ctx);
	}
}

static void
rpc_nvmf_subsystem_set_ns_ana_group(struct spdk_jsonrpc_request *request,
				    const struct spdk_json_val *params)
{
	struct nvmf_rpc_ana_group_ctx *ctx;
	struct spdk_nvmf_subsystem *subsystem;
	struct spdk_nvmf_tgt *tgt;
	int rc;

	ctx = calloc(1, sizeof(*ctx));
	if (!ctx) {
		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Out of memory");
		return;
	}

	if (spdk_json_decode_object(params, nvmf_rpc_subsystem_ana_group_decoder,
				    SPDK_COUNTOF(nvmf_rpc_subsystem_ana_group_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_ana_group_ctx_free(ctx);
		return;
	}

	ctx->request = request;
	ctx->response_sent = false;

	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,
						 "Unable to find a target.");
		nvmf_rpc_ana_group_ctx_free(ctx);
		return;
	}

	subsystem = spdk_nvmf_tgt_find_subsystem(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_ana_group_ctx_free(ctx);
		return;
	}

	rc = spdk_nvmf_subsystem_pause(subsystem, ctx->nsid, nvmf_rpc_ana_group, ctx);
	if (rc != 0) {
		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Internal error");
		nvmf_rpc_ana_group_ctx_free(ctx);
	}
}
SPDK_RPC_REGISTER("nvmf_subsystem_set_ns_ana_group", rpc_nvmf_subsystem_set_ns_ana_group,
		  SPDK_RPC_RUNTIME)

struct nvmf_rpc_remove_ns_ctx {
	char *nqn;
	char *tgt_name;
+22 −0
Original line number Diff line number Diff line
@@ -488,6 +488,28 @@ def nvmf_subsystem_add_ns(client, **params):
    return client.call('nvmf_subsystem_add_ns', params)


def nvmf_subsystem_set_ns_ana_group(client, nqn, nsid, anagrpid, tgt_name=None):
    """Change ANA group ID of a namespace.

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

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

    if tgt_name:
        params['tgt_name'] = tgt_name

    return client.call('nvmf_subsystem_set_ns_ana_group', params)


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

+14 −0
Original line number Diff line number Diff line
@@ -2797,6 +2797,20 @@ Format: 'user:u1 secret:s1 muser:mu1 msecret:ms1,user:u2 secret:s2 muser:mu2 mse
                   help='Do not auto make namespace visible to controllers (optional)')
    p.set_defaults(func=nvmf_subsystem_add_ns)

    def nvmf_subsystem_set_ns_ana_group(args):
        rpc.nvmf.nvmf_subsystem_set_ns_ana_group(args.client,
                                                 nqn=args.nqn,
                                                 nsid=args.nsid,
                                                 anagrpid=args.anagrpid,
                                                 tgt_name=args.tgt_name)

    p = subparsers.add_parser('nvmf_subsystem_set_ns_ana_group', help='Change ANA group ID of a namespace')
    p.add_argument('nqn', help='NVMe-oF subsystem NQN')
    p.add_argument('nsid', help='The requested NSID', type=int)
    p.add_argument('anagrpid', help='ANA group ID', type=int)
    p.add_argument('-t', '--tgt-name', help='The name of the parent NVMe-oF target (optional)', type=str)
    p.set_defaults(func=nvmf_subsystem_set_ns_ana_group)

    def nvmf_subsystem_remove_ns(args):
        rpc.nvmf.nvmf_subsystem_remove_ns(args.client,
                                          nqn=args.nqn,