rpc: Add nvmf_get_stats RPC method
This patch adds nvmf_get_stats RPC method and basic infrastructure to report NVMf global and per poll group statistics in JSON format. Signed-off-by: Evgeniy Kochetov <evgeniik@mellanox.com> Change-Id: I13b83e28b75a02bc1dcb7b95cbce52ae10ff0f7b Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/452298 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Reviewed-by: Darek Stojaczyk <dariusz.stojaczyk@intel.com>
This commit is contained in:
parent
02f147567c
commit
fca6ff8f75
@ -30,6 +30,8 @@ poll group for the qpair. And `ConnectionScheduler` configuration is added into
|
||||
[Nvmf] section in etc/spdk/nvmf.conf.in to demonstrate how to configure the connection
|
||||
scheduling strategy among different spdk threads.
|
||||
|
||||
Added infrastructure to retrieve global and per poll group NVMf statistics.
|
||||
|
||||
### notify
|
||||
|
||||
The function `spdk_notify_get_types()` and `spdk_notify_get_events()` were
|
||||
@ -99,6 +101,8 @@ spdk_sock_group_create() is updated to allow input the user provided ctx.
|
||||
|
||||
Added thread_get_stats RPC method to retrieve existing statistics.
|
||||
|
||||
Added nvmf_get_stats RPC method to retrieve NVMf susbsystem statistics.
|
||||
|
||||
## v19.04:
|
||||
|
||||
### nvme
|
||||
|
@ -4138,6 +4138,44 @@ Example response:
|
||||
}
|
||||
~~~
|
||||
|
||||
## nvmf_get_stats method {#rpc_nvmf_get_stats}
|
||||
|
||||
Retrieve current statistics of the NVMf subsystem.
|
||||
|
||||
### Parameters
|
||||
|
||||
This method has no parameters.
|
||||
|
||||
### Response
|
||||
|
||||
The response is an object containing NVMf subsystem statistics.
|
||||
|
||||
### Example
|
||||
|
||||
Example request:
|
||||
~~~
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
"method": "nvmf_get_stats",
|
||||
"id": 1
|
||||
}
|
||||
~~~
|
||||
|
||||
Example response:
|
||||
~~~
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
"id": 1,
|
||||
"result": {
|
||||
"poll_groups": [
|
||||
{
|
||||
"name": "app_thread"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
~~~
|
||||
|
||||
# Vhost Target {#jsonrpc_components_vhost_tgt}
|
||||
|
||||
The following common preconditions need to be met in all target types.
|
||||
|
@ -2,7 +2,7 @@
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright (c) Intel Corporation. All rights reserved.
|
||||
* Copyright (c) 2018 Mellanox Technologies LTD. All rights reserved.
|
||||
* Copyright (c) 2018-2019 Mellanox Technologies LTD. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -78,6 +78,10 @@ struct spdk_nvmf_transport_opts {
|
||||
bool dif_insert_or_strip;
|
||||
};
|
||||
|
||||
struct spdk_nvmf_poll_group_stat {
|
||||
int dummy;
|
||||
};
|
||||
|
||||
/**
|
||||
* Construct an NVMe-oF target.
|
||||
*
|
||||
@ -190,6 +194,18 @@ void spdk_nvmf_poll_group_destroy(struct spdk_nvmf_poll_group *group);
|
||||
int spdk_nvmf_poll_group_add(struct spdk_nvmf_poll_group *group,
|
||||
struct spdk_nvmf_qpair *qpair);
|
||||
|
||||
/**
|
||||
* Get current poll group statistics.
|
||||
*
|
||||
* \param tgt The NVMf target.
|
||||
* \param stat Pointer to allocated statistics structure to fill with values.
|
||||
*
|
||||
* \return 0 upon success.
|
||||
* \return -EINVAL if either group or stat is NULL.
|
||||
*/
|
||||
int spdk_nvmf_poll_group_get_stat(struct spdk_nvmf_tgt *tgt,
|
||||
struct spdk_nvmf_poll_group_stat *stat);
|
||||
|
||||
typedef void (*nvmf_qpair_disconnect_cb)(void *ctx);
|
||||
|
||||
/**
|
||||
|
@ -2,7 +2,7 @@
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright (c) Intel Corporation. All rights reserved.
|
||||
* Copyright (c) 2018 Mellanox Technologies LTD. All rights reserved.
|
||||
* Copyright (c) 2018-2019 Mellanox Technologies LTD. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -1628,3 +1628,72 @@ spdk_rpc_get_nvmf_transports(struct spdk_jsonrpc_request *request,
|
||||
spdk_jsonrpc_end_result(request, w);
|
||||
}
|
||||
SPDK_RPC_REGISTER("get_nvmf_transports", spdk_rpc_get_nvmf_transports, SPDK_RPC_RUNTIME)
|
||||
|
||||
struct rpc_nvmf_get_stats_ctx {
|
||||
struct spdk_jsonrpc_request *request;
|
||||
struct spdk_json_write_ctx *w;
|
||||
};
|
||||
|
||||
static void
|
||||
rpc_nvmf_get_stats_done(struct spdk_io_channel_iter *i, int status)
|
||||
{
|
||||
struct rpc_nvmf_get_stats_ctx *ctx = spdk_io_channel_iter_get_ctx(i);
|
||||
|
||||
spdk_json_write_array_end(ctx->w);
|
||||
spdk_json_write_object_end(ctx->w);
|
||||
spdk_jsonrpc_end_result(ctx->request, ctx->w);
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
rpc_nvmf_get_stats(struct spdk_io_channel_iter *i)
|
||||
{
|
||||
struct rpc_nvmf_get_stats_ctx *ctx = spdk_io_channel_iter_get_ctx(i);
|
||||
struct spdk_nvmf_poll_group_stat stat;
|
||||
|
||||
if (0 == spdk_nvmf_poll_group_get_stat(g_spdk_nvmf_tgt, &stat)) {
|
||||
spdk_json_write_object_begin(ctx->w);
|
||||
spdk_json_write_named_string(ctx->w, "name", spdk_thread_get_name(spdk_get_thread()));
|
||||
spdk_json_write_object_end(ctx->w);
|
||||
}
|
||||
|
||||
spdk_for_each_channel_continue(i, 0);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
spdk_rpc_nvmf_get_stats(struct spdk_jsonrpc_request *request,
|
||||
const struct spdk_json_val *params)
|
||||
{
|
||||
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,
|
||||
"Memory allocation error");
|
||||
return;
|
||||
}
|
||||
ctx->request = request;
|
||||
|
||||
ctx->w = spdk_jsonrpc_begin_result(ctx->request);
|
||||
if (NULL == ctx->w) {
|
||||
free(ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
spdk_json_write_object_begin(ctx->w);
|
||||
spdk_json_write_named_array_begin(ctx->w, "poll_groups");
|
||||
|
||||
spdk_for_each_channel(g_spdk_nvmf_tgt,
|
||||
rpc_nvmf_get_stats,
|
||||
ctx,
|
||||
rpc_nvmf_get_stats_done);
|
||||
}
|
||||
|
||||
SPDK_RPC_REGISTER("nvmf_get_stats", spdk_rpc_nvmf_get_stats, SPDK_RPC_RUNTIME)
|
||||
|
@ -2,7 +2,7 @@
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright (c) Intel Corporation. All rights reserved.
|
||||
* Copyright (c) 2018 Mellanox Technologies LTD. All rights reserved.
|
||||
* Copyright (c) 2018-2019 Mellanox Technologies LTD. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -1227,3 +1227,20 @@ spdk_nvmf_get_optimal_poll_group(struct spdk_nvmf_qpair *qpair)
|
||||
|
||||
return tgroup->group;
|
||||
}
|
||||
|
||||
int
|
||||
spdk_nvmf_poll_group_get_stat(struct spdk_nvmf_tgt *tgt,
|
||||
struct spdk_nvmf_poll_group_stat *stat)
|
||||
{
|
||||
struct spdk_io_channel *ch;
|
||||
struct spdk_nvmf_poll_group *group;
|
||||
|
||||
if (tgt == NULL || stat == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ch = spdk_get_io_channel(tgt);
|
||||
group = spdk_io_channel_get_ctx(ch);
|
||||
*stat = group->stat;
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
/*-
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright (c) Intel Corporation.
|
||||
* All rights reserved.
|
||||
* Copyright (c) Intel Corporation. All rights reserved.
|
||||
* Copyright (c) 2019 Mellanox Technologies LTD. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -172,6 +172,9 @@ struct spdk_nvmf_poll_group {
|
||||
|
||||
/* All of the queue pairs that belong to this poll group */
|
||||
TAILQ_HEAD(, spdk_nvmf_qpair) qpairs;
|
||||
|
||||
/* Statistics */
|
||||
struct spdk_nvmf_poll_group_stat stat;
|
||||
};
|
||||
|
||||
typedef enum _spdk_nvmf_request_exec_status {
|
||||
|
@ -1575,6 +1575,13 @@ Format: 'user:u1 secret:s1 muser:mu1 msecret:ms1,user:u2 secret:s2 muser:mu2 mse
|
||||
p.add_argument('-d', '--disable', action='store_true', help='Disable allowing any host')
|
||||
p.set_defaults(func=nvmf_subsystem_allow_any_host)
|
||||
|
||||
def nvmf_get_stats(args):
|
||||
print_dict(rpc.nvmf.nvmf_get_stats(args.client))
|
||||
|
||||
p = subparsers.add_parser(
|
||||
'nvmf_get_stats', help='Display current statistics for NVMf subsystem')
|
||||
p.set_defaults(func=nvmf_get_stats)
|
||||
|
||||
# pmem
|
||||
def create_pmem_pool(args):
|
||||
num_blocks = int((args.total_size * 1024 * 1024) / args.block_size)
|
||||
|
@ -323,3 +323,12 @@ def delete_nvmf_subsystem(client, nqn):
|
||||
"""
|
||||
params = {'nqn': nqn}
|
||||
return client.call('delete_nvmf_subsystem', params)
|
||||
|
||||
|
||||
def nvmf_get_stats(client):
|
||||
"""Query NVMf statistics.
|
||||
|
||||
Returns:
|
||||
Current NVMf statistics.
|
||||
"""
|
||||
return client.call('nvmf_get_stats')
|
||||
|
Loading…
Reference in New Issue
Block a user