rbd/rpc: Add a rpc call to get the info of the clusters.

Purpose: Let the users know the current available registered Rados
cluster and the related info.

Change-Id: I115c129ae6e4b0372579aad168fd88f8be136357
Signed-off-by: Ziye Yang <ziye.yang@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/7990
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
Ziye Yang 2021-05-21 19:24:44 +08:00 committed by Tomasz Zawadzki
parent f90eaf1672
commit c3cf9ec295
8 changed files with 186 additions and 1 deletions

View File

@ -30,6 +30,9 @@ device.
Revised `bdev_rbd_create` parameter, it allows to use an optional parameter --cluster-name
to create a rbd bdev with an already registered Rados Cluster Object.
New RPC `bdev_rbd_get_clusters_info` was added, it allows to get the info of the registered
Rados Cluster names.
## v21.04:
### accel

View File

@ -3405,6 +3405,45 @@ Example response:
}
~~
## bdev_rbd_get_clusters_info {#rpc_bdev_rbd_get_clusters_info}
This method is available only if SPDK was build with Ceph RBD support.
### Result
Returns the cluster info of the Rados Cluster name if provided. Otherwise, it
returns the cluster info of every registered Raods Cluster name.
### Parameters
Name | Optional | Type | Description
----------------------- | -------- | ----------- | -------------------------
name | Optional | string | Rados cluster object name
### Example
Example request:
~~
{
"params": {
"name": "rbd_cluster"
},
"jsonrpc": "2.0",
"method": "bdev_rbd_get_clusters_info",
"id": 1
}
~~
Example response:
~~
{
"jsonrpc": "2.0",
"cluster_name": "rbd_cluster"
}
~~
## bdev_rbd_create {#rpc_bdev_rbd_create}
Create @ref bdev_config_rbd bdev

View File

@ -790,6 +790,76 @@ bdev_rbd_write_config_json(struct spdk_bdev *bdev, struct spdk_json_write_ctx *w
spdk_json_write_object_end(w);
}
static void
dump_single_cluster_entry(struct bdev_rbd_cluster *entry, struct spdk_json_write_ctx *w)
{
assert(entry != NULL);
spdk_json_write_object_begin(w);
spdk_json_write_named_string(w, "cluster_name", entry->name);
if (entry->user_id) {
spdk_json_write_named_string(w, "user_id", entry->user_id);
}
if (entry->config_param) {
char **config_entry = entry->config_param;
spdk_json_write_named_object_begin(w, "config_param");
while (*config_entry) {
spdk_json_write_named_string(w, config_entry[0], config_entry[1]);
config_entry += 2;
}
spdk_json_write_object_end(w);
} else if (entry->config_file) {
spdk_json_write_named_string(w, "config_file", entry->config_file);
}
spdk_json_write_object_end(w);
}
int
bdev_rbd_get_clusters_info(struct spdk_jsonrpc_request *request, const char *name)
{
struct bdev_rbd_cluster *entry;
struct spdk_json_write_ctx *w;
pthread_mutex_lock(&g_map_bdev_rbd_cluster_mutex);
if (STAILQ_EMPTY(&g_map_bdev_rbd_cluster)) {
pthread_mutex_unlock(&g_map_bdev_rbd_cluster_mutex);
return -ENOENT;
}
/* If cluster name is provided */
if (name) {
STAILQ_FOREACH(entry, &g_map_bdev_rbd_cluster, link) {
if (strcmp(name, entry->name) == 0) {
w = spdk_jsonrpc_begin_result(request);
dump_single_cluster_entry(entry, w);
spdk_jsonrpc_end_result(request, w);
pthread_mutex_unlock(&g_map_bdev_rbd_cluster_mutex);
return 0;
}
}
pthread_mutex_unlock(&g_map_bdev_rbd_cluster_mutex);
return -ENOENT;
}
w = spdk_jsonrpc_begin_result(request);
spdk_json_write_array_begin(w);
STAILQ_FOREACH(entry, &g_map_bdev_rbd_cluster, link) {
dump_single_cluster_entry(entry, w);
}
spdk_json_write_array_end(w);
spdk_jsonrpc_end_result(request, w);
pthread_mutex_unlock(&g_map_bdev_rbd_cluster_mutex);
return 0;
}
static const struct spdk_bdev_fn_table rbd_fn_table = {
.destruct = bdev_rbd_destruct,
.submit_request = bdev_rbd_submit_request,

View File

@ -37,6 +37,7 @@
#include "spdk/stdinc.h"
#include "spdk/bdev.h"
#include "spdk/rpc.h"
struct cluster_register_info {
char *name;
@ -86,4 +87,13 @@ int bdev_rbd_register_cluster(struct cluster_register_info *info);
*/
int bdev_rbd_unregister_cluster(const char *name);
/**
* Show the cluster info of a given name. If given name is empty,
* the info of every registered cluster name will be showed.
*
* \param request the json request.
* \param name the name of the cluster.
*/
int bdev_rbd_get_clusters_info(struct spdk_jsonrpc_request *request, const char *name);
#endif /* SPDK_BDEV_RBD_H */

View File

@ -32,7 +32,6 @@
*/
#include "bdev_rbd.h"
#include "spdk/rpc.h"
#include "spdk/util.h"
#include "spdk/string.h"
#include "spdk/log.h"
@ -336,3 +335,43 @@ cleanup:
free_rpc_bdev_cluster_unregister(&req);
}
SPDK_RPC_REGISTER("bdev_rbd_unregister_cluster", rpc_bdev_rbd_unregister_cluster, SPDK_RPC_RUNTIME)
struct rpc_bdev_rbd_get_cluster_info {
char *name;
};
static void
free_rpc_bdev_rbd_get_cluster_info(struct rpc_bdev_rbd_get_cluster_info *req)
{
free(req->name);
}
static const struct spdk_json_object_decoder rpc_bdev_rbd_get_cluster_info_decoders[] = {
{"name", offsetof(struct rpc_bdev_rbd_get_cluster_info, name), spdk_json_decode_string, true},
};
static void
rpc_bdev_rbd_get_clusters_info(struct spdk_jsonrpc_request *request,
const struct spdk_json_val *params)
{
struct rpc_bdev_rbd_get_cluster_info req = {NULL};
int rc;
if (params && spdk_json_decode_object(params, rpc_bdev_rbd_get_cluster_info_decoders,
SPDK_COUNTOF(rpc_bdev_rbd_get_cluster_info_decoders),
&req)) {
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
"spdk_json_decode_object failed");
goto cleanup;
}
rc = bdev_rbd_get_clusters_info(request, req.name);
if (rc) {
spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
goto cleanup;
}
cleanup:
free_rpc_bdev_rbd_get_cluster_info(&req);
}
SPDK_RPC_REGISTER("bdev_rbd_get_clusters_info", rpc_bdev_rbd_get_clusters_info, SPDK_RPC_RUNTIME)

View File

@ -661,6 +661,14 @@ if __name__ == "__main__":
p.add_argument('name', help='Name of the Rados Cluster only known to rbd bdev')
p.set_defaults(func=bdev_rbd_unregister_cluster)
def bdev_rbd_get_clusters_info(args):
print_json(rpc.bdev.bdev_rbd_get_clusters_info(args.client, name=args.name))
p = subparsers.add_parser('bdev_rbd_get_clusters_info',
help='Display registered Rados Cluster names and related info')
p.add_argument('-b', '--name', help="Name of the registered Rados Cluster Name. Example: Cluster1", required=False)
p.set_defaults(func=bdev_rbd_get_clusters_info)
def bdev_rbd_create(args):
config = None
if args.config:

View File

@ -693,6 +693,21 @@ def bdev_rbd_unregister_cluster(client, name):
return client.call('bdev_rbd_unregister_cluster', params)
def bdev_rbd_get_clusters_info(client, name):
"""Get the cluster(s) info
Args:
name: name of Rados cluster object to query (optional; if omitted, query all clusters)
Returns:
List of registered Rados cluster information objects.
"""
params = {}
if name:
params['name'] = name
return client.call('bdev_rbd_get_clusters_info', params)
@deprecated_alias('construct_rbd_bdev')
def bdev_rbd_create(client, pool_name, rbd_name, block_size, name=None, user=None, config=None, cluster_name=None):
"""Create a Ceph RBD block device.

View File

@ -32,6 +32,7 @@ timing_exit start_iscsi_tgt
$rpc_py iscsi_create_portal_group $PORTAL_TAG $TARGET_IP:$ISCSI_PORT
$rpc_py iscsi_create_initiator_group $INITIATOR_TAG $INITIATOR_NAME $NETMASK
rbd_cluster_name="$($rpc_py bdev_rbd_register_cluster iscsi_rbd_cluster)"
$rpc_py bdev_rbd_get_clusters_info -b $rbd_cluster_name
rbd_bdev="$($rpc_py bdev_rbd_create $RBD_POOL $RBD_NAME 4096 -c $rbd_cluster_name)"
$rpc_py bdev_get_bdevs