lvol: display details of single lvol store RPC

New optional argument added to get_lvol_stores RPC.
If lvol store name or uuid is provided, details
for this single lvol store is displayed.

It follows similar logic as in get_bdevs or get_nbd_disks.

Change-Id: I11e71d98f3cde869addf5cedeb4f33e5cebf53ea
Signed-off-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-on: https://review.gerrithub.io/395126
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Maciej Szwed <maciej.szwed@intel.com>
Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
Tomasz Zawadzki 2018-01-29 02:09:35 -05:00 committed by Jim Harris
parent 937f1c2bc3
commit 9856fe06e5
5 changed files with 112 additions and 42 deletions

View File

@ -44,7 +44,7 @@ SPDK_DECLARE_BDEV_MODULE(lvol);
static TAILQ_HEAD(, lvol_store_bdev) g_spdk_lvol_pairs = TAILQ_HEAD_INITIALIZER( static TAILQ_HEAD(, lvol_store_bdev) g_spdk_lvol_pairs = TAILQ_HEAD_INITIALIZER(
g_spdk_lvol_pairs); 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) vbdev_get_lvs_bdev_by_lvs(struct spdk_lvol_store *lvs_orig)
{ {
struct spdk_lvol_store *lvs = NULL; struct spdk_lvol_store *lvs = NULL;

View File

@ -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); 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 */ #endif /* SPDK_VBDEV_LVOL_H */

View File

@ -422,20 +422,91 @@ invalid:
/* Logical volume resize feature is disabled, as it is currently work in progress /* Logical volume resize feature is disabled, as it is currently work in progress
SPDK_RPC_REGISTER("resize_lvol_bdev", spdk_rpc_resize_lvol_bdev) */ SPDK_RPC_REGISTER("resize_lvol_bdev", spdk_rpc_resize_lvol_bdev) */
struct rpc_get_lvol_stores {
char *uuid;
char *lvs_name;
};
static void static void
spdk_rpc_get_lvol_stores(struct spdk_jsonrpc_request *request, free_rpc_get_lvol_stores(struct rpc_get_lvol_stores *req)
const struct spdk_json_val *params) {
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; struct spdk_blob_store *bs;
uint64_t cluster_size, block_size; uint64_t cluster_size, block_size;
char uuid[UUID_STRING_LEN]; 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) { if (params != NULL) {
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, if (spdk_json_decode_object(params, rpc_get_lvol_stores_decoders,
"get_lvol_stores requires no parameters"); SPDK_COUNTOF(rpc_get_lvol_stores_decoders),
return; &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); 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); spdk_json_write_array_begin(w);
for (lvs_bdev = vbdev_lvol_store_first(); lvs_bdev != NULL; if (lvs_bdev != NULL) {
lvs_bdev = vbdev_lvol_store_next(lvs_bdev)) { spdk_rpc_dump_lvol_store_info(w, lvs_bdev);
} else {
bs = lvs_bdev->lvs->blobstore; for (lvs_bdev = vbdev_lvol_store_first(); lvs_bdev != NULL;
cluster_size = spdk_bs_get_cluster_size(bs); lvs_bdev = vbdev_lvol_store_next(lvs_bdev)) {
/* Block size of lvols is always size of blob store page */ spdk_rpc_dump_lvol_store_info(w, lvs_bdev);
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);
} }
spdk_json_write_array_end(w); spdk_json_write_array_end(w);
spdk_jsonrpc_end_result(request, 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) SPDK_RPC_REGISTER("get_lvol_stores", spdk_rpc_get_lvol_stores)

View File

@ -275,6 +275,8 @@ if __name__ == "__main__":
p.set_defaults(func=rpc.lvol.destroy_lvol_store) p.set_defaults(func=rpc.lvol.destroy_lvol_store)
p = subparsers.add_parser('get_lvol_stores', help='Display current logical volume store list') 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) p.set_defaults(func=rpc.lvol.get_lvol_stores)
# nbd # nbd

View File

@ -46,4 +46,11 @@ def destroy_lvol_store(args):
def get_lvol_stores(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))