lib/bdev: add spdk_bdev_wait_for_examine()

Add spdk_bdev_wait_for_examine() API to be called
in order to report when examine on all registered bdevs finished.
It will be built in to most bdev modules RPC.

New RPC added to allow
- building it into bdev submodule
- user/orchestration to verify examination status manually

Signed-off-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Change-Id: I27db3ae42eea3e692faeea4c2a01d04586bff438
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/5480
Community-CI: Broadcom CI
Community-CI: Mellanox Build Bot
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: <dongx.yi@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
This commit is contained in:
Tomasz Zawadzki 2020-12-08 06:13:05 -05:00
parent cc8e4443e5
commit 77b6f4bc3e
9 changed files with 135 additions and 0 deletions

View File

@ -10,6 +10,9 @@ parameter in spdk_bdev_get_opts function. Two fields `small_buf_pool_size` and
`large_buf_pool_size` were added into spdk_bdev_opts, which were used to determine
the small and large buffer pool size of the whole bdev module.
A new API `spdk_bdev_wait_for_examine` was added to allow for checking state of
examine process. Along with corresponding `bdev_wait_for_examine` RPC.
### blob
An `opts_size` element was added in the `spdk_bs_opts` structure to solve the

View File

@ -1320,6 +1320,40 @@ Example response:
}
~~~
## bdev_wait_for_examine {#rpc_bdev_wait_for_examine}
Report when all bdevs have been examined by every bdev module.
### Parameters
None
### Response
The response is sent when all bdev modules had a chance to examine every bdev.
### Example
Example request:
~~~
{
"jsonrpc": "2.0",
"method": "bdev_wait_for_examine",
"id": 1
}
~~~
Example response:
~~~
{
"jsonrpc": "2.0",
"id": 1,
"result": true
}
~~~
## bdev_get_iostat {#rpc_bdev_get_iostat}
Get I/O statistics of block devices (bdevs).

View File

@ -209,6 +209,20 @@ void spdk_bdev_get_opts(struct spdk_bdev_opts *opts, size_t opts_size);
int spdk_bdev_set_opts(struct spdk_bdev_opts *opts);
typedef void (*spdk_bdev_wait_for_examine_cb)(void *arg);
/**
* Report when all bdevs finished the examine process.
* The registered cb_fn will be called just once.
* This function needs to be called again to receive
* further reports on examine process.
*
* \param cb_fn Callback function.
* \param cb_arg Callback argument.
* \return 0 if function was registered, suitable errno value otherwise
*/
int spdk_bdev_wait_for_examine(spdk_bdev_wait_for_examine_cb cb_fn, void *cb_arg);
/**
* Examine a block device explicitly
*

View File

@ -462,6 +462,47 @@ spdk_bdev_set_opts(struct spdk_bdev_opts *opts)
return 0;
}
struct spdk_bdev_wait_for_examine_ctx {
struct spdk_poller *poller;
spdk_bdev_wait_for_examine_cb cb_fn;
void *cb_arg;
};
static bool
bdev_module_all_actions_completed(void);
static int
bdev_wait_for_examine_cb(void *arg)
{
struct spdk_bdev_wait_for_examine_ctx *ctx = arg;
if (!bdev_module_all_actions_completed()) {
return SPDK_POLLER_IDLE;
}
spdk_poller_unregister(&ctx->poller);
ctx->cb_fn(ctx->cb_arg);
free(ctx);
return SPDK_POLLER_BUSY;
}
int
spdk_bdev_wait_for_examine(spdk_bdev_wait_for_examine_cb cb_fn, void *cb_arg)
{
struct spdk_bdev_wait_for_examine_ctx *ctx;
ctx = calloc(1, sizeof(*ctx));
if (ctx == NULL) {
return -ENOMEM;
}
ctx->cb_fn = cb_fn;
ctx->cb_arg = cb_arg;
ctx->poller = SPDK_POLLER_REGISTER(bdev_wait_for_examine_cb, ctx, 0);
return 0;
}
struct spdk_bdev_examine_item {
char *name;
TAILQ_ENTRY(spdk_bdev_examine_item) link;

View File

@ -110,6 +110,33 @@ rpc_bdev_set_options(struct spdk_jsonrpc_request *request, const struct spdk_jso
SPDK_RPC_REGISTER("bdev_set_options", rpc_bdev_set_options, SPDK_RPC_STARTUP)
SPDK_RPC_REGISTER_ALIAS_DEPRECATED(bdev_set_options, set_bdev_options)
static void
rpc_bdev_wait_for_examine_cpl(void *arg)
{
struct spdk_jsonrpc_request *request = arg;
spdk_jsonrpc_send_bool_response(request, true);
}
static void
rpc_bdev_wait_for_examine(struct spdk_jsonrpc_request *request,
const struct spdk_json_val *params)
{
int rc;
if (params != NULL) {
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
"bdev_wait_for_examine requires no parameters");
return;
}
rc = spdk_bdev_wait_for_examine(rpc_bdev_wait_for_examine_cpl, request);
if (rc != 0) {
spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
}
}
SPDK_RPC_REGISTER("bdev_wait_for_examine", rpc_bdev_wait_for_examine, SPDK_RPC_RUNTIME)
struct rpc_bdev_examine {
char *name;
};

View File

@ -4,6 +4,7 @@
# Public functions in bdev.h
spdk_bdev_get_opts;
spdk_bdev_set_opts;
spdk_bdev_wait_for_examine;
spdk_bdev_examine;
spdk_bdev_initialize;
spdk_bdev_finish;

View File

@ -198,6 +198,13 @@ if __name__ == "__main__":
p.add_argument('-b', '--name', help='Name or alias of the bdev')
p.set_defaults(func=bdev_examine)
def bdev_wait_for_examine(args):
rpc.bdev.bdev_wait_for_examine(args.client)
p = subparsers.add_parser('bdev_wait_for_examine',
help="""Report when all bdevs have been examined""")
p.set_defaults(func=bdev_wait_for_examine)
def bdev_compress_create(args):
print_json(rpc.bdev.bdev_compress_create(args.client,
base_bdev_name=args.base_bdev_name,

View File

@ -41,6 +41,12 @@ def bdev_examine(client, name):
return client.call('bdev_examine', params)
def bdev_wait_for_examine(client):
"""Report when all bdevs have been examined
"""
return client.call('bdev_wait_for_examine')
@deprecated_alias('construct_compress_bdev')
def bdev_compress_create(client, base_bdev_name, pm_path, lb_size):
"""Construct a compress virtual block device.

View File

@ -346,6 +346,8 @@ case "$test_type" in
;;
esac
"$rpc_py" bdev_wait_for_examine
# Generate json config and use it throughout all the tests
cat <<- CONF > "$conf_file"
{"subsystems":[