From 199080cfa2b69d8bb474ea222595974acfe7505d Mon Sep 17 00:00:00 2001 From: Vitaliy Mysak Date: Tue, 22 Jan 2019 21:11:37 +0000 Subject: [PATCH] OCF: rpc: add get_ocf_bdevs method Add new RPC method for OCF bdev: get_ocf_bdevs It is useful in respect to not registered OCF bdevs which do not appear in standard get_bdevs call Change-Id: I8a5fc86a880b04c47d5f139aa5fa4d07ca39c853 Signed-off-by: Vitaliy Mysak Reviewed-on: https://review.gerrithub.io/c/441655 Tested-by: SPDK CI Jenkins Reviewed-by: Darek Stojaczyk Reviewed-by: Jim Harris --- doc/jsonrpc.md | 47 ++++++++++++++++++++++++++ lib/bdev/ocf/vbdev_ocf.c | 15 ++++++++ lib/bdev/ocf/vbdev_ocf.h | 5 +++ lib/bdev/ocf/vbdev_ocf_rpc.c | 40 ++++++++++++++++++++++ scripts/rpc.py | 6 ++++ scripts/rpc/bdev.py | 11 ++++++ test/ocf/management/create-destruct.sh | 6 ++++ 7 files changed, 130 insertions(+) diff --git a/doc/jsonrpc.md b/doc/jsonrpc.md index f3dea7000..8a537bc10 100644 --- a/doc/jsonrpc.md +++ b/doc/jsonrpc.md @@ -1076,6 +1076,53 @@ Example response: } ~~~ +## get_ocf_bdevs {#rpc_get_ocf_bdevs} + +Get list of OCF devices including unregistered ones. + +### Parameters + +This method has no parameters. + +### Response + +Array of OCF devices with their current status, along with core and cache bdevs. + +### Example + +Example request: + +~~~ +{ + "jsonrpc": "2.0", + "method": "get_ocf_bdevs", + "id": 1 +} +~~~ + +Example response: + +~~~ +{ + "jsonrpc": "2.0", + "id": 1, + "result": [ + { + "name": "PartCache", + "started": false, + "cache": { + "name": "Malloc0", + "attached": true + }, + "core": { + "name": "Malloc1", + "attached": false + } + } + ] +} +~~~ + ## construct_malloc_bdev {#rpc_construct_malloc_bdev} Construct @ref bdev_config_malloc diff --git a/lib/bdev/ocf/vbdev_ocf.c b/lib/bdev/ocf/vbdev_ocf.c index 4de998a6f..de6671b34 100644 --- a/lib/bdev/ocf/vbdev_ocf.c +++ b/lib/bdev/ocf/vbdev_ocf.c @@ -228,6 +228,21 @@ vbdev_ocf_get_base_by_name(const char *name) return NULL; } +/* Execute fn for each OCF device that is online or waits for base devices */ +void +vbdev_ocf_foreach(vbdev_ocf_foreach_fn fn, void *ctx) +{ + struct vbdev_ocf *vbdev; + + assert(fn != NULL); + + TAILQ_FOREACH(vbdev, &g_ocf_vbdev_head, tailq) { + if (!vbdev->state.doing_finish) { + fn(vbdev, ctx); + } + } +} + /* Called from OCF when SPDK_IO is completed */ static void vbdev_ocf_io_submit_cb(struct ocf_io *io, int error) diff --git a/lib/bdev/ocf/vbdev_ocf.h b/lib/bdev/ocf/vbdev_ocf.h index 634bf9fd1..93034b173 100644 --- a/lib/bdev/ocf/vbdev_ocf.h +++ b/lib/bdev/ocf/vbdev_ocf.h @@ -154,4 +154,9 @@ struct vbdev_ocf_base *vbdev_ocf_get_base_by_name(const char *name); /* Stop OCF cache and unregister SPDK bdev */ int vbdev_ocf_delete(struct vbdev_ocf *vbdev); +typedef void (*vbdev_ocf_foreach_fn)(struct vbdev_ocf *, void *); + +/* Execute fn for each OCF device that is online or waits for base devices */ +void vbdev_ocf_foreach(vbdev_ocf_foreach_fn fn, void *ctx); + #endif diff --git a/lib/bdev/ocf/vbdev_ocf_rpc.c b/lib/bdev/ocf/vbdev_ocf_rpc.c index 75502b95b..5ad27be8d 100644 --- a/lib/bdev/ocf/vbdev_ocf_rpc.c +++ b/lib/bdev/ocf/vbdev_ocf_rpc.c @@ -218,3 +218,43 @@ end: free_rpc_get_ocf_stats(&req); } SPDK_RPC_REGISTER("get_ocf_stats", spdk_rpc_get_ocf_stats, SPDK_RPC_RUNTIME) + +static void +get_bdevs_fn(struct vbdev_ocf *vbdev, void *ctx) +{ + struct spdk_json_write_ctx *w = ctx; + + spdk_json_write_object_begin(w); + spdk_json_write_named_string(w, "name", vbdev->name); + spdk_json_write_named_bool(w, "started", vbdev->state.started); + + spdk_json_write_named_object_begin(w, "cache"); + spdk_json_write_named_string(w, "name", vbdev->cache.name); + spdk_json_write_named_bool(w, "attached", vbdev->cache.attached); + spdk_json_write_object_end(w); + + spdk_json_write_named_object_begin(w, "core"); + spdk_json_write_named_string(w, "name", vbdev->core.name); + spdk_json_write_named_bool(w, "attached", vbdev->core.attached); + spdk_json_write_object_end(w); + + spdk_json_write_object_end(w); +} + +static void +spdk_rpc_get_ocf_bdevs(struct spdk_jsonrpc_request *request, const struct spdk_json_val *params) +{ + struct spdk_json_write_ctx *w; + + w = spdk_jsonrpc_begin_result(request); + if (w == NULL) { + return; + } + + spdk_json_write_array_begin(w); + vbdev_ocf_foreach(get_bdevs_fn, w); + spdk_json_write_array_end(w); + + spdk_jsonrpc_end_result(request, w); +} +SPDK_RPC_REGISTER("get_ocf_bdevs", spdk_rpc_get_ocf_bdevs, SPDK_RPC_RUNTIME) diff --git a/scripts/rpc.py b/scripts/rpc.py index ba2310d36..ee5f249f8 100755 --- a/scripts/rpc.py +++ b/scripts/rpc.py @@ -175,6 +175,12 @@ if __name__ == "__main__": p.add_argument('name', help='Name of OCF bdev') p.set_defaults(func=get_ocf_stats) + def get_ocf_bdevs(args): + print_dict(rpc.bdev.get_ocf_bdevs(args.client)) + p = subparsers.add_parser('get_ocf_bdevs', + help='Get list of OCF devices including unregistered ones') + p.set_defaults(func=get_ocf_bdevs) + def construct_malloc_bdev(args): num_blocks = (args.total_size * 1024 * 1024) // args.block_size print(rpc.bdev.construct_malloc_bdev(args.client, diff --git a/scripts/rpc/bdev.py b/scripts/rpc/bdev.py index 03b7966c2..8d68512d5 100644 --- a/scripts/rpc/bdev.py +++ b/scripts/rpc/bdev.py @@ -85,6 +85,17 @@ def get_ocf_stats(client, name): return client.call('get_ocf_stats', params) +def get_ocf_bdevs(client): + """Get list of OCF devices including unregistered ones + + Args: + + Returns: + Array of OCF devices with their current status + """ + return client.call('get_ocf_bdevs', None) + + def construct_malloc_bdev(client, num_blocks, block_size, name=None, uuid=None): """Construct a malloc block device. diff --git a/test/ocf/management/create-destruct.sh b/test/ocf/management/create-destruct.sh index 395292c31..72b6c8ed5 100755 --- a/test/ocf/management/create-destruct.sh +++ b/test/ocf/management/create-destruct.sh @@ -27,6 +27,9 @@ $rpc_py construct_malloc_bdev 101 512 -b Malloc1 $rpc_py construct_ocf_bdev PartCache wt Malloc0 NonExisting +$rpc_py get_ocf_bdevs | jq -e \ + 'map(select(.name == "PartCache")) | .[0] | .started == false and .cache.attached and .core.attached == false' + if ! bdev_check_claimed Malloc0; then >&2 echo "Base device expected to be claimed now" exit 1 @@ -40,6 +43,9 @@ fi $rpc_py construct_ocf_bdev FullCache wt Malloc0 Malloc1 +$rpc_py get_ocf_bdevs | jq -e \ + 'map(select(.name == "FullCache")) | .[0] | .started and .cache.attached and .core.attached' + if ! (bdev_check_claimed Malloc0 && bdev_check_claimed Malloc1); then >&2 echo "Base devices expected to be claimed now" exit 1