From d9acca71101c4cee19811fea66ac8953faab9d16 Mon Sep 17 00:00:00 2001 From: Alexander Indenbaum Date: Sun, 17 Mar 2024 15:41:25 +0200 Subject: [PATCH] Add bdev_rbd_wait_for_latest_osdmap Signed-off-by: Alexander Indenbaum (cherry picked from commit 2500e6f278ea752c435491ec0220e23239bc7abf) --- module/bdev/rbd/bdev_rbd.c | 39 +++++++++++++++++++++++++++++++ module/bdev/rbd/bdev_rbd.h | 8 +++++++ module/bdev/rbd/bdev_rbd_rpc.c | 42 ++++++++++++++++++++++++++++++++++ python/spdk/rpc/bdev.py | 9 ++++++++ 4 files changed, 98 insertions(+) diff --git a/module/bdev/rbd/bdev_rbd.c b/module/bdev/rbd/bdev_rbd.c index 9027e1ca3d5..0b1e2d9b088 100644 --- a/module/bdev/rbd/bdev_rbd.c +++ b/module/bdev/rbd/bdev_rbd.c @@ -1013,6 +1013,45 @@ dump_single_cluster_entry(struct bdev_rbd_cluster *entry, struct spdk_json_write spdk_json_write_object_end(w); } +static void * +_bdev_rbd_wait_for_latest_osdmap(void *arg) +{ + struct bdev_rbd_cluster *entry; + const char *name = arg; + assert(name != NULL); + void *ret = NULL; // failure by default + + pthread_mutex_lock(&g_map_bdev_rbd_cluster_mutex); + + STAILQ_FOREACH(entry, &g_map_bdev_rbd_cluster, link) { + if (strcmp(name, entry->name) == 0) { + int rc = rados_wait_for_latest_osdmap(entry->cluster); + if (rc) { + SPDK_ERRLOG("Failed to wait for latest osd map, rados cluster=%s, rc=%d\n", + name, rc); + } else { + ret = arg; // non-NULL is returned on success + } + break; + } + } + + pthread_mutex_unlock(&g_map_bdev_rbd_cluster_mutex); + return ret; +} + +int +bdev_rbd_wait_for_latest_osdmap(const char *name) +{ + /* Wait for osd map on cluster name need to be performed in non SPDK-thread to avoid CPU + * resource contention */ + if (spdk_call_unaffinitized(_bdev_rbd_wait_for_latest_osdmap, (void *)name) == NULL) { + return -1; + } + + return 0; +} + int bdev_rbd_get_clusters_info(struct spdk_jsonrpc_request *request, const char *name) { diff --git a/module/bdev/rbd/bdev_rbd.h b/module/bdev/rbd/bdev_rbd.h index 12e259dfcd7..4133e3421c2 100644 --- a/module/bdev/rbd/bdev_rbd.h +++ b/module/bdev/rbd/bdev_rbd.h @@ -71,4 +71,12 @@ int bdev_rbd_unregister_cluster(const char *name); */ int bdev_rbd_get_clusters_info(struct spdk_jsonrpc_request *request, const char *name); +/** + * Wait for latest osd map on cluster identified by name. + * Part of blocklist logic + * + * \param name the name of the cluster. + */ +int bdev_rbd_wait_for_latest_osdmap(const char *name); + #endif /* SPDK_BDEV_RBD_H */ diff --git a/module/bdev/rbd/bdev_rbd_rpc.c b/module/bdev/rbd/bdev_rbd_rpc.c index e61c8692cf5..6db66143ae7 100644 --- a/module/bdev/rbd/bdev_rbd_rpc.c +++ b/module/bdev/rbd/bdev_rbd_rpc.c @@ -341,3 +341,45 @@ rpc_bdev_rbd_get_clusters_info(struct spdk_jsonrpc_request *request, 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) + +struct rpc_bdev_rbd_wait_for_latest_osdmap_cluster { + char *name; +}; + +static void +free_rpc_bdev_rbd_wait_for_latest_osdmap_cluster(struct rpc_bdev_rbd_wait_for_latest_osdmap_cluster *req) +{ + free(req->name); +} + +static const struct spdk_json_object_decoder rpc_bdev_rbd_wait_for_latest_osdmap_cluster_decoders[] = { + {"name", offsetof(struct rpc_bdev_rbd_wait_for_latest_osdmap_cluster, name), spdk_json_decode_string, true}, +}; + +static void +rpc_bdev_rbd_wait_for_latest_osdmap(struct spdk_jsonrpc_request *request, + const struct spdk_json_val *params) +{ + struct rpc_bdev_rbd_wait_for_latest_osdmap_cluster req = {NULL}; + int rc; + + if (spdk_json_decode_object(params, rpc_bdev_rbd_wait_for_latest_osdmap_cluster_decoders, + SPDK_COUNTOF(rpc_bdev_rbd_wait_for_latest_osdmap_cluster_decoders), + &req)) { + spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, + "spdk_json_decode_object failed"); + goto cleanup; + } + + rc = bdev_rbd_wait_for_latest_osdmap(req.name); + if (rc) { + spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc)); + goto cleanup; + } + + spdk_jsonrpc_send_bool_response(request, true); + +cleanup: + free_rpc_bdev_rbd_wait_for_latest_osdmap_cluster(&req); +} +SPDK_RPC_REGISTER("bdev_rbd_wait_for_latest_osdmap", rpc_bdev_rbd_wait_for_latest_osdmap, SPDK_RPC_RUNTIME) diff --git a/python/spdk/rpc/bdev.py b/python/spdk/rpc/bdev.py index 8303dc59e9c..acf3c8547e0 100644 --- a/python/spdk/rpc/bdev.py +++ b/python/spdk/rpc/bdev.py @@ -1189,6 +1189,15 @@ def bdev_rbd_unregister_cluster(client, name): params = {'name': name} return client.call('bdev_rbd_unregister_cluster', params) +def bdev_rbd_wait_for_latest_osdmap(client, name): + """Wait for latest osd map on cluster identified by name. + + Args: + name: name of Rados cluster + """ + params = {'name': name} + return client.call('bdev_rbd_wait_for_latest_osdmap', params) + def bdev_rbd_get_clusters_info(client, name): """Get the cluster(s) info