diff --git a/lib/bdev/lvol/vbdev_lvol.c b/lib/bdev/lvol/vbdev_lvol.c index 02e46174c..eb6cf3ac9 100644 --- a/lib/bdev/lvol/vbdev_lvol.c +++ b/lib/bdev/lvol/vbdev_lvol.c @@ -44,7 +44,7 @@ SPDK_DECLARE_BDEV_MODULE(lvol); static TAILQ_HEAD(, lvol_store_bdev) g_spdk_lvol_pairs = TAILQ_HEAD_INITIALIZER( g_spdk_lvol_pairs); -static struct lvol_store_bdev * +struct lvol_store_bdev * vbdev_get_lvs_bdev_by_lvs(struct spdk_lvol_store *lvs_orig) { struct spdk_lvol_store *lvs = NULL; diff --git a/lib/bdev/lvol/vbdev_lvol.h b/lib/bdev/lvol/vbdev_lvol.h index c5bc04f3c..d1abb0496 100644 --- a/lib/bdev/lvol/vbdev_lvol.h +++ b/lib/bdev/lvol/vbdev_lvol.h @@ -71,4 +71,11 @@ struct spdk_lvol_store *vbdev_get_lvol_store_by_uuid(const char *uuid_str); */ struct spdk_lvol_store *vbdev_get_lvol_store_by_name(const char *name); +/** + * \brief Search for handle to lvol_store_bdev + * \param lvs handle to lvolstore + * \return Handle to lvol_store_bdev or NULL if not found. + */ +struct lvol_store_bdev *vbdev_get_lvs_bdev_by_lvs(struct spdk_lvol_store *lvs); + #endif /* SPDK_VBDEV_LVOL_H */ diff --git a/lib/bdev/lvol/vbdev_lvol_rpc.c b/lib/bdev/lvol/vbdev_lvol_rpc.c index 7da858d32..5ca39c9fa 100644 --- a/lib/bdev/lvol/vbdev_lvol_rpc.c +++ b/lib/bdev/lvol/vbdev_lvol_rpc.c @@ -422,20 +422,91 @@ invalid: /* Logical volume resize feature is disabled, as it is currently work in progress SPDK_RPC_REGISTER("resize_lvol_bdev", spdk_rpc_resize_lvol_bdev) */ +struct rpc_get_lvol_stores { + char *uuid; + char *lvs_name; +}; + static void -spdk_rpc_get_lvol_stores(struct spdk_jsonrpc_request *request, - const struct spdk_json_val *params) +free_rpc_get_lvol_stores(struct rpc_get_lvol_stores *req) +{ + free(req->uuid); + free(req->lvs_name); +} + +static const struct spdk_json_object_decoder rpc_get_lvol_stores_decoders[] = { + {"uuid", offsetof(struct rpc_get_lvol_stores, uuid), spdk_json_decode_string, true}, + {"lvs_name", offsetof(struct rpc_get_lvol_stores, lvs_name), spdk_json_decode_string, true}, +}; + +static void +spdk_rpc_dump_lvol_store_info(struct spdk_json_write_ctx *w, struct lvol_store_bdev *lvs_bdev) { - struct spdk_json_write_ctx *w; - struct lvol_store_bdev *lvs_bdev; struct spdk_blob_store *bs; uint64_t cluster_size, block_size; char uuid[UUID_STRING_LEN]; + bs = lvs_bdev->lvs->blobstore; + cluster_size = spdk_bs_get_cluster_size(bs); + /* Block size of lvols is always size of blob store page */ + block_size = spdk_bs_get_page_size(bs); + + spdk_json_write_object_begin(w); + + uuid_unparse(lvs_bdev->lvs->uuid, uuid); + spdk_json_write_name(w, "uuid"); + spdk_json_write_string(w, uuid); + + spdk_json_write_name(w, "name"); + spdk_json_write_string(w, lvs_bdev->lvs->name); + + spdk_json_write_name(w, "base_bdev"); + spdk_json_write_string(w, spdk_bdev_get_name(lvs_bdev->bdev)); + + spdk_json_write_name(w, "total_data_clusters"); + spdk_json_write_uint64(w, spdk_bs_total_data_cluster_count(bs)); + + spdk_json_write_name(w, "free_clusters"); + spdk_json_write_uint64(w, spdk_bs_free_cluster_count(bs)); + + spdk_json_write_name(w, "block_size"); + spdk_json_write_uint64(w, block_size); + + spdk_json_write_name(w, "cluster_size"); + spdk_json_write_uint64(w, cluster_size); + + spdk_json_write_object_end(w); +} + +static void +spdk_rpc_get_lvol_stores(struct spdk_jsonrpc_request *request, + const struct spdk_json_val *params) +{ + struct rpc_get_lvol_stores req = {}; + struct spdk_json_write_ctx *w; + struct lvol_store_bdev *lvs_bdev = NULL; + struct spdk_lvol_store *lvs = NULL; + int rc; + if (params != NULL) { - spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, - "get_lvol_stores requires no parameters"); - return; + if (spdk_json_decode_object(params, rpc_get_lvol_stores_decoders, + SPDK_COUNTOF(rpc_get_lvol_stores_decoders), + &req)) { + SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "spdk_json_decode_object failed\n"); + rc = -EINVAL; + goto invalid; + } + + rc = vbdev_get_lvol_store_by_uuid_xor_name(req.uuid, req.lvs_name, &lvs); + if (rc != 0) { + goto invalid; + } + + lvs_bdev = vbdev_get_lvs_bdev_by_lvs(lvs); + if (lvs_bdev == NULL) { + rc = -ENODEV; + goto invalid; + } } w = spdk_jsonrpc_begin_result(request); @@ -445,43 +516,26 @@ spdk_rpc_get_lvol_stores(struct spdk_jsonrpc_request *request, spdk_json_write_array_begin(w); - for (lvs_bdev = vbdev_lvol_store_first(); lvs_bdev != NULL; - lvs_bdev = vbdev_lvol_store_next(lvs_bdev)) { - - bs = lvs_bdev->lvs->blobstore; - cluster_size = spdk_bs_get_cluster_size(bs); - /* Block size of lvols is always size of blob store page */ - block_size = spdk_bs_get_page_size(bs); - - spdk_json_write_object_begin(w); - - uuid_unparse(lvs_bdev->lvs->uuid, uuid); - spdk_json_write_name(w, "uuid"); - spdk_json_write_string(w, uuid); - - spdk_json_write_name(w, "name"); - spdk_json_write_string(w, lvs_bdev->lvs->name); - - spdk_json_write_name(w, "base_bdev"); - spdk_json_write_string(w, spdk_bdev_get_name(lvs_bdev->bdev)); - - spdk_json_write_name(w, "total_data_clusters"); - spdk_json_write_uint64(w, spdk_bs_total_data_cluster_count(bs)); - - spdk_json_write_name(w, "free_clusters"); - spdk_json_write_uint64(w, spdk_bs_free_cluster_count(bs)); - - spdk_json_write_name(w, "block_size"); - spdk_json_write_uint64(w, block_size); - - spdk_json_write_name(w, "cluster_size"); - spdk_json_write_uint64(w, cluster_size); - - spdk_json_write_object_end(w); + if (lvs_bdev != NULL) { + spdk_rpc_dump_lvol_store_info(w, lvs_bdev); + } else { + for (lvs_bdev = vbdev_lvol_store_first(); lvs_bdev != NULL; + lvs_bdev = vbdev_lvol_store_next(lvs_bdev)) { + spdk_rpc_dump_lvol_store_info(w, lvs_bdev); + } } spdk_json_write_array_end(w); spdk_jsonrpc_end_result(request, w); + + free_rpc_get_lvol_stores(&req); + + return; + +invalid: + spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, + spdk_strerror(-rc)); + free_rpc_get_lvol_stores(&req); } SPDK_RPC_REGISTER("get_lvol_stores", spdk_rpc_get_lvol_stores) diff --git a/scripts/rpc.py b/scripts/rpc.py index d715e66e8..eb01db4a4 100755 --- a/scripts/rpc.py +++ b/scripts/rpc.py @@ -275,6 +275,8 @@ if __name__ == "__main__": p.set_defaults(func=rpc.lvol.destroy_lvol_store) p = subparsers.add_parser('get_lvol_stores', help='Display current logical volume store list') + p.add_argument('-u', '--uuid', help='lvol store UUID', required=False) + p.add_argument('-l', '--lvs_name', help='lvol store name', required=False) p.set_defaults(func=rpc.lvol.get_lvol_stores) # nbd diff --git a/scripts/rpc/lvol.py b/scripts/rpc/lvol.py index ae3ccd1ed..564dfa92b 100755 --- a/scripts/rpc/lvol.py +++ b/scripts/rpc/lvol.py @@ -46,4 +46,11 @@ def destroy_lvol_store(args): def get_lvol_stores(args): - print_dict(args.client.call('get_lvol_stores')) + params = {} + if (args.uuid and args.lvs_name): + print("You can only specify either uuid or name of lvolstore") + if args.uuid: + params['uuid'] = args.uuid + if args.lvs_name: + params['lvs_name'] = args.lvs_name + print_dict(args.client.call('get_lvol_stores', params))