From 74a28c199f6dba87dee1847267da404bb8de5745 Mon Sep 17 00:00:00 2001 From: wuzhouhui Date: Thu, 13 Sep 2018 11:58:55 +0800 Subject: [PATCH] vhost: rpc: add an optional parameter -n/--name for get_vhost_controllers User can use this optional parameter to get the information of specific vhost controller. Change-Id: I3911c6c7d4e7b75e82277d1e4690d5e40019aa06 Signed-off-by: wuzhouhui Reviewed-on: https://review.gerrithub.io/425451 Reviewed-by: Darek Stojaczyk Reviewed-by: Jim Harris Reviewed-by: Shuhei Matsumoto Chandler-Test-Pool: SPDK Automated Test System Tested-by: SPDK CI Jenkins --- doc/jsonrpc.md | 12 ++++-- lib/vhost/vhost_rpc.c | 95 +++++++++++++++++++++++++++++++++---------- scripts/rpc.py | 5 ++- scripts/rpc/vhost.py | 13 ++++-- 4 files changed, 95 insertions(+), 30 deletions(-) diff --git a/doc/jsonrpc.md b/doc/jsonrpc.md index ec9cac9795..3045e087ed 100644 --- a/doc/jsonrpc.md +++ b/doc/jsonrpc.md @@ -3635,15 +3635,21 @@ Example response: ## get_vhost_controllers {#rpc_get_vhost_controllers} -Display information about all vhost controllers. +Display information about all or specific vhost controller(s). ### Parameters -This method has no parameters. +The user may specify no parameters in order to list all controllers, or a controller may be +specified by name. + +Name | Optional | Type | Description +----------------------- | -------- | ----------- | ----------- +name | Optional | string | Vhost controller name + ### Response {#rpc_get_vhost_controllers_response} -Response is an array of objects describing each controllers. Common fields are: +Response is an array of objects describing requested controller(s). Common fields are: Name | Type | Description ----------------------- | ----------- | ----------- diff --git a/lib/vhost/vhost_rpc.c b/lib/vhost/vhost_rpc.c index cfd6f7e7f0..0e546c365c 100644 --- a/lib/vhost/vhost_rpc.c +++ b/lib/vhost/vhost_rpc.c @@ -451,16 +451,39 @@ invalid: SPDK_RPC_REGISTER("remove_vhost_controller", spdk_rpc_remove_vhost_controller, SPDK_RPC_RUNTIME) struct rpc_get_vhost_ctrlrs { + char *name; struct spdk_json_write_ctx *w; struct spdk_jsonrpc_request *request; }; +static void +_spdk_rpc_get_vhost_controller(struct spdk_json_write_ctx *w, struct spdk_vhost_dev *vdev) +{ + uint32_t delay_base_us, iops_threshold; + + spdk_vhost_get_coalescing(vdev, &delay_base_us, &iops_threshold); + + spdk_json_write_object_begin(w); + + spdk_json_write_named_string(w, "ctrlr", spdk_vhost_dev_get_name(vdev)); + spdk_json_write_named_string_fmt(w, "cpumask", "0x%s", spdk_cpuset_fmt(vdev->cpumask)); + spdk_json_write_named_uint32(w, "delay_base_us", delay_base_us); + spdk_json_write_named_uint32(w, "iops_threshold", iops_threshold); + spdk_json_write_named_string(w, "socket", vdev->path); + + spdk_json_write_named_object_begin(w, "backend_specific"); + spdk_vhost_dump_info_json(vdev, w); + spdk_json_write_object_end(w); + + spdk_json_write_object_end(w); +} + static int spdk_rpc_get_vhost_controllers_cb(struct spdk_vhost_dev *vdev, void *arg) { struct rpc_get_vhost_ctrlrs *ctx = arg; - uint32_t delay_base_us, iops_threshold; + assert(ctx->name == NULL); if (vdev == NULL) { spdk_json_write_array_end(ctx->w); @@ -469,24 +492,43 @@ spdk_rpc_get_vhost_controllers_cb(struct spdk_vhost_dev *vdev, void *arg) return 0; } - spdk_vhost_get_coalescing(vdev, &delay_base_us, &iops_threshold); - - spdk_json_write_object_begin(ctx->w); - - spdk_json_write_named_string(ctx->w, "ctrlr", spdk_vhost_dev_get_name(vdev)); - spdk_json_write_named_string_fmt(ctx->w, "cpumask", "0x%s", spdk_cpuset_fmt(vdev->cpumask)); - spdk_json_write_named_uint32(ctx->w, "delay_base_us", delay_base_us); - spdk_json_write_named_uint32(ctx->w, "iops_threshold", iops_threshold); - spdk_json_write_named_string(ctx->w, "socket", vdev->path); - - spdk_json_write_named_object_begin(ctx->w, "backend_specific"); - spdk_vhost_dump_info_json(vdev, ctx->w); - spdk_json_write_object_end(ctx->w); - - spdk_json_write_object_end(ctx->w); + _spdk_rpc_get_vhost_controller(ctx->w, vdev); return 0; } +static int +spdk_rpc_get_vhost_controller_cb(struct spdk_vhost_dev *vdev, void *arg) +{ + struct rpc_get_vhost_ctrlrs *ctx = arg; + + assert(ctx->name != NULL); + + if (vdev == NULL) { + spdk_jsonrpc_send_error_response(ctx->request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, + spdk_strerror(ENODEV)); + goto free_name_ctx; + } + + ctx->w = spdk_jsonrpc_begin_result(ctx->request); + if (ctx->w == NULL) { + goto free_name_ctx; + } + + spdk_json_write_array_begin(ctx->w); + _spdk_rpc_get_vhost_controller(ctx->w, vdev); + spdk_json_write_array_end(ctx->w); + + spdk_jsonrpc_end_result(ctx->request, ctx->w); + +free_name_ctx: + free(ctx->name); + free(ctx); + return 0; +} + +static const struct spdk_json_object_decoder rpc_get_vhost_ctrlrs_decoders[] = { + {"name", offsetof(struct rpc_get_vhost_ctrlrs, name), spdk_json_decode_string, true}, +}; static void spdk_rpc_get_vhost_controllers(struct spdk_jsonrpc_request *request, @@ -495,12 +537,6 @@ spdk_rpc_get_vhost_controllers(struct spdk_jsonrpc_request *request, struct rpc_get_vhost_ctrlrs *ctx; struct spdk_json_write_ctx *w; - if (params != NULL) { - spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, - "get_vhost_controllers requires no parameters"); - return; - } - ctx = calloc(1, sizeof(*ctx)); if (ctx == NULL) { spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, @@ -508,6 +544,21 @@ spdk_rpc_get_vhost_controllers(struct spdk_jsonrpc_request *request, return; } + if (params && spdk_json_decode_object(params, rpc_get_vhost_ctrlrs_decoders, + SPDK_COUNTOF(rpc_get_vhost_ctrlrs_decoders), ctx)) { + SPDK_ERRLOG("spdk_json_decode_object failed\n"); + free(ctx); + spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, + "Invalid parameters"); + return; + } + + if (ctx->name) { + ctx->request = request; + spdk_vhost_call_external_event(ctx->name, spdk_rpc_get_vhost_controller_cb, ctx); + return; + } + w = spdk_jsonrpc_begin_result(request); if (w == NULL) { free(ctx); diff --git a/scripts/rpc.py b/scripts/rpc.py index 20d9e0f4d2..7db05239c6 100755 --- a/scripts/rpc.py +++ b/scripts/rpc.py @@ -1632,9 +1632,10 @@ Format: 'user:u1 secret:s1 muser:mu1 msecret:ms1,user:u2 secret:s2 muser:mu2 mse @call_cmd def get_vhost_controllers(args): - print_dict(rpc.vhost.get_vhost_controllers(args.client)) + print_dict(rpc.vhost.get_vhost_controllers(args.client, args.name)) - p = subparsers.add_parser('get_vhost_controllers', help='List vhost controllers') + p = subparsers.add_parser('get_vhost_controllers', help='List all or specific vhost controller(s)') + p.add_argument('-n', '--name', help="Name of vhost controller", required=False) p.set_defaults(func=get_vhost_controllers) @call_cmd diff --git a/scripts/rpc/vhost.py b/scripts/rpc/vhost.py index d60f1bec3a..bc97455ac7 100644 --- a/scripts/rpc/vhost.py +++ b/scripts/rpc/vhost.py @@ -106,12 +106,19 @@ def construct_vhost_blk_controller(client, ctrlr, dev_name, cpumask=None, readon return client.call('construct_vhost_blk_controller', params) -def get_vhost_controllers(client): - """Get list of configured vhost controllers. +def get_vhost_controllers(client, name=None): + """Get information about configured vhost controllers. + + Args: + name: controller name to query (optional; if omitted, query all controllers) + Returns: List of vhost controllers. """ - return client.call('get_vhost_controllers') + params = {} + if name: + params['name'] = name + return client.call('get_vhost_controllers', params) def remove_vhost_controller(client, ctrlr):