lib/nvmf: Add nvmf_subsystem_get_listeners RPC
Add an new RPC, nvmf_subsystem_get_listeners. ANA state is per listener and per subsystem, and is stored in subsystem listener. We can return ANA state by the existing nvmf_get_subsystems RPC but it's confusing that listen addresses have ANA states. To change ANA state, we will provide a RPC to change ANA state of only one selected subsystem listener. To query ANA state, it will be convenient to get ANA states of all listeners of one selected subsystem. Signed-off-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Change-Id: Ic3baad6eac65d7af6e0cab2c4059e1458d41e6e2 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4059 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com> Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
parent
a60865bff6
commit
9c1d648315
@ -4823,6 +4823,50 @@ Example response:
|
|||||||
}
|
}
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
|
## nvmf_subsystem_get_listeners {#rpc_nvmf_subsystem_get_listeners}
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
|
||||||
|
Name | Optional | Type | Description
|
||||||
|
----------------------- | -------- | ----------- | -----------
|
||||||
|
nqn | Required | string | Subsystem NQN
|
||||||
|
tgt_name | Optional | string | Parent NVMe-oF target name.
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
Example request:
|
||||||
|
|
||||||
|
~~~
|
||||||
|
{
|
||||||
|
"jsonrpc": "2.0",
|
||||||
|
"id": 1,
|
||||||
|
"method": "nvmf_subsystem_get_listeners",
|
||||||
|
"params": {
|
||||||
|
"nqn": "nqn.2016-06.io.spdk:cnode1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
~~~
|
||||||
|
|
||||||
|
Example response:
|
||||||
|
|
||||||
|
~~~
|
||||||
|
{
|
||||||
|
"jsonrpc": "2.0",
|
||||||
|
"id": 1,
|
||||||
|
"result": [
|
||||||
|
{
|
||||||
|
"address": {
|
||||||
|
"trtype": "RDMA",
|
||||||
|
"adrfam": "IPv4",
|
||||||
|
"traddr": "192.168.0.123",
|
||||||
|
"trsvcid": "4420"
|
||||||
|
},
|
||||||
|
"ana_state": "optimized"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
~~~
|
||||||
|
|
||||||
## nvmf_set_max_subsystems {#rpc_nvmf_set_max_subsystems}
|
## nvmf_set_max_subsystems {#rpc_nvmf_set_max_subsystems}
|
||||||
|
|
||||||
Set the maximum allowed subsystems for the NVMe-oF target. This RPC may only be called
|
Set the maximum allowed subsystems for the NVMe-oF target. This RPC may only be called
|
||||||
|
@ -2136,6 +2136,51 @@ dump_nvmf_qpair(struct spdk_json_write_ctx *w, struct spdk_nvmf_qpair *qpair)
|
|||||||
spdk_json_write_object_end(w);
|
spdk_json_write_object_end(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
nvme_ana_state_str(enum spdk_nvme_ana_state ana_state)
|
||||||
|
{
|
||||||
|
switch (ana_state) {
|
||||||
|
case SPDK_NVME_ANA_OPTIMIZED_STATE:
|
||||||
|
return "optimized";
|
||||||
|
case SPDK_NVME_ANA_NON_OPTIMIZED_STATE:
|
||||||
|
return "non_optimized";
|
||||||
|
case SPDK_NVME_ANA_INACCESSIBLE_STATE:
|
||||||
|
return "inaccessible";
|
||||||
|
case SPDK_NVME_ANA_PERSISTENT_LOSS_STATE:
|
||||||
|
return "persistent_loss";
|
||||||
|
case SPDK_NVME_ANA_CHANGE_STATE:
|
||||||
|
return "change";
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dump_nvmf_subsystem_listener(struct spdk_json_write_ctx *w,
|
||||||
|
struct spdk_nvmf_subsystem_listener *listener)
|
||||||
|
{
|
||||||
|
const struct spdk_nvme_transport_id *trid = listener->trid;
|
||||||
|
const char *adrfam;
|
||||||
|
|
||||||
|
spdk_json_write_object_begin(w);
|
||||||
|
|
||||||
|
spdk_json_write_named_object_begin(w, "address");
|
||||||
|
adrfam = spdk_nvme_transport_id_adrfam_str(trid->adrfam);
|
||||||
|
if (adrfam == NULL) {
|
||||||
|
adrfam = "unknown";
|
||||||
|
}
|
||||||
|
spdk_json_write_named_string(w, "trtype", trid->trstring);
|
||||||
|
spdk_json_write_named_string(w, "adrfam", adrfam);
|
||||||
|
spdk_json_write_named_string(w, "traddr", trid->traddr);
|
||||||
|
spdk_json_write_named_string(w, "trsvcid", trid->trsvcid);
|
||||||
|
spdk_json_write_object_end(w);
|
||||||
|
|
||||||
|
spdk_json_write_named_string(w, "ana_state",
|
||||||
|
nvme_ana_state_str(listener->ana_state));
|
||||||
|
|
||||||
|
spdk_json_write_object_end(w);
|
||||||
|
}
|
||||||
|
|
||||||
struct rpc_subsystem_query_ctx {
|
struct rpc_subsystem_query_ctx {
|
||||||
char *nqn;
|
char *nqn;
|
||||||
char *tgt_name;
|
char *tgt_name;
|
||||||
@ -2235,6 +2280,35 @@ rpc_nvmf_get_qpairs_paused(struct spdk_nvmf_subsystem *subsystem,
|
|||||||
rpc_nvmf_get_qpairs_done);
|
rpc_nvmf_get_qpairs_done);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
rpc_nvmf_get_listeners_paused(struct spdk_nvmf_subsystem *subsystem,
|
||||||
|
void *cb_arg, int status)
|
||||||
|
{
|
||||||
|
struct rpc_subsystem_query_ctx *ctx = cb_arg;
|
||||||
|
struct spdk_json_write_ctx *w;
|
||||||
|
struct spdk_nvmf_subsystem_listener *listener;
|
||||||
|
|
||||||
|
w = spdk_jsonrpc_begin_result(ctx->request);
|
||||||
|
|
||||||
|
spdk_json_write_array_begin(w);
|
||||||
|
|
||||||
|
for (listener = spdk_nvmf_subsystem_get_first_listener(ctx->subsystem);
|
||||||
|
listener != NULL;
|
||||||
|
listener = spdk_nvmf_subsystem_get_next_listener(ctx->subsystem, listener)) {
|
||||||
|
dump_nvmf_subsystem_listener(w, listener);
|
||||||
|
}
|
||||||
|
spdk_json_write_array_end(w);
|
||||||
|
|
||||||
|
spdk_jsonrpc_end_result(ctx->request, w);
|
||||||
|
|
||||||
|
if (spdk_nvmf_subsystem_resume(ctx->subsystem, NULL, NULL)) {
|
||||||
|
SPDK_ERRLOG("Resuming subsystem with NQN %s failed\n", ctx->nqn);
|
||||||
|
/* FIXME: RPC should fail if resuming the subsystem failed. */
|
||||||
|
}
|
||||||
|
|
||||||
|
free_rpc_subsystem_query_ctx(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_rpc_nvmf_subsystem_query(struct spdk_jsonrpc_request *request,
|
_rpc_nvmf_subsystem_query(struct spdk_jsonrpc_request *request,
|
||||||
const struct spdk_json_val *params,
|
const struct spdk_json_val *params,
|
||||||
@ -2307,3 +2381,12 @@ rpc_nvmf_subsystem_get_qpairs(struct spdk_jsonrpc_request *request,
|
|||||||
_rpc_nvmf_subsystem_query(request, params, rpc_nvmf_get_qpairs_paused);
|
_rpc_nvmf_subsystem_query(request, params, rpc_nvmf_get_qpairs_paused);
|
||||||
}
|
}
|
||||||
SPDK_RPC_REGISTER("nvmf_subsystem_get_qpairs", rpc_nvmf_subsystem_get_qpairs, SPDK_RPC_RUNTIME);
|
SPDK_RPC_REGISTER("nvmf_subsystem_get_qpairs", rpc_nvmf_subsystem_get_qpairs, SPDK_RPC_RUNTIME);
|
||||||
|
|
||||||
|
static void
|
||||||
|
rpc_nvmf_subsystem_get_listeners(struct spdk_jsonrpc_request *request,
|
||||||
|
const struct spdk_json_val *params)
|
||||||
|
{
|
||||||
|
_rpc_nvmf_subsystem_query(request, params, rpc_nvmf_get_listeners_paused);
|
||||||
|
}
|
||||||
|
SPDK_RPC_REGISTER("nvmf_subsystem_get_listeners", rpc_nvmf_subsystem_get_listeners,
|
||||||
|
SPDK_RPC_RUNTIME);
|
||||||
|
@ -2012,6 +2012,17 @@ Format: 'user:u1 secret:s1 muser:mu1 msecret:ms1,user:u2 secret:s2 muser:mu2 mse
|
|||||||
p.add_argument('-t', '--tgt-name', help='The name of the parent NVMe-oF target (optional)', type=str)
|
p.add_argument('-t', '--tgt-name', help='The name of the parent NVMe-oF target (optional)', type=str)
|
||||||
p.set_defaults(func=nvmf_subsystem_get_qpairs)
|
p.set_defaults(func=nvmf_subsystem_get_qpairs)
|
||||||
|
|
||||||
|
def nvmf_subsystem_get_listeners(args):
|
||||||
|
print_dict(rpc.nvmf.nvmf_subsystem_get_listeners(args.client,
|
||||||
|
nqn=args.nqn,
|
||||||
|
tgt_name=args.tgt_name))
|
||||||
|
|
||||||
|
p = subparsers.add_parser('nvmf_subsystem_get_listeners',
|
||||||
|
help='Display listeners of an NVMe-oF subsystem.')
|
||||||
|
p.add_argument('nqn', help='NVMe-oF subsystem NQN')
|
||||||
|
p.add_argument('-t', '--tgt-name', help='The name of the parent NVMe-oF target (optional)', type=str)
|
||||||
|
p.set_defaults(func=nvmf_subsystem_get_listeners)
|
||||||
|
|
||||||
def nvmf_get_stats(args):
|
def nvmf_get_stats(args):
|
||||||
print_dict(rpc.nvmf.nvmf_get_stats(args.client, tgt_name=args.tgt_name))
|
print_dict(rpc.nvmf.nvmf_get_stats(args.client, tgt_name=args.tgt_name))
|
||||||
|
|
||||||
|
@ -505,6 +505,24 @@ def nvmf_subsystem_get_qpairs(client, nqn, tgt_name=None):
|
|||||||
return client.call('nvmf_subsystem_get_qpairs', params)
|
return client.call('nvmf_subsystem_get_qpairs', params)
|
||||||
|
|
||||||
|
|
||||||
|
def nvmf_subsystem_get_listeners(client, nqn, tgt_name=None):
|
||||||
|
"""Get list of listeners of an NVMe-oF subsystem.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
nqn: Subsystem NQN.
|
||||||
|
tgt_name: name of the parent NVMe-oF target (optional).
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
List of listener objects of an NVMe-oF subsystem.
|
||||||
|
"""
|
||||||
|
params = {'nqn': nqn}
|
||||||
|
|
||||||
|
if tgt_name:
|
||||||
|
params['tgt_name'] = tgt_name
|
||||||
|
|
||||||
|
return client.call('nvmf_subsystem_get_listeners', params)
|
||||||
|
|
||||||
|
|
||||||
def nvmf_get_stats(client, tgt_name=None):
|
def nvmf_get_stats(client, tgt_name=None):
|
||||||
"""Query NVMf statistics.
|
"""Query NVMf statistics.
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user