From 1b5951fa393753b2572dc741bde71fedfd1132b3 Mon Sep 17 00:00:00 2001 From: Jim Harris Date: Fri, 3 May 2019 13:20:42 -0700 Subject: [PATCH] rpc: add SPDK_RPC_REGISTER_ALIAS_DEPRECATED This will be used to help rename our existing RPCs to a standard consistent naming convention. Old names will still be registered with this new macro, to keep backward compatibility. The first time a deprecated alias is used, it will print a warning message. Signed-off-by: Jim Harris Change-Id: Ieaedf86a68531f9d56742fefe272c4d602fce6c7 Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/453032 Tested-by: SPDK CI Jenkins Reviewed-by: Shuhei Matsumoto Reviewed-by: Ben Walker --- include/spdk/rpc.h | 14 ++++++++++++++ lib/rpc/rpc.c | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/include/spdk/rpc.h b/include/spdk/rpc.h index 8e5a52c49..2ffb0e2db 100644 --- a/include/spdk/rpc.h +++ b/include/spdk/rpc.h @@ -81,6 +81,14 @@ typedef void (*spdk_rpc_method_handler)(struct spdk_jsonrpc_request *request, void spdk_rpc_register_method(const char *method, spdk_rpc_method_handler func, uint32_t state_mask); +/** + * Register a deprecated alias for an RPC method. + * + * \param method Name for the registered method. + * \param alias Alias for the registered method. + */ +void spdk_rpc_register_alias_deprecated(const char *method, const char *alias); + /** * Check if \c method is allowed for \c state_mask * @@ -101,6 +109,12 @@ static void __attribute__((constructor)) rpc_register_##func(void) \ spdk_rpc_register_method(method, func, state_mask); \ } +#define SPDK_RPC_REGISTER_ALIAS_DEPRECATED(method, alias) \ +static void __attribute__((constructor)) rpc_register_##alias(void) \ +{ \ + spdk_rpc_register_alias_deprecated(#method, #alias); \ +} + /** * Set the state mask of the RPC server. Any RPC method whose state mask is * equal to the state of the RPC server is allowed. diff --git a/lib/rpc/rpc.c b/lib/rpc/rpc.c index df9d1e55f..6654a4841 100644 --- a/lib/rpc/rpc.c +++ b/lib/rpc/rpc.c @@ -57,6 +57,9 @@ struct spdk_rpc_method { spdk_rpc_method_handler func; SLIST_ENTRY(spdk_rpc_method) slist; uint32_t state_mask; + bool is_deprecated; + struct spdk_rpc_method *is_alias_of; + bool deprecation_warning_printed; }; static SLIST_HEAD(, spdk_rpc_method) g_rpc_methods = SLIST_HEAD_INITIALIZER(g_rpc_methods); @@ -114,6 +117,14 @@ spdk_jsonrpc_handler(struct spdk_jsonrpc_request *request, return; } + if (m->is_alias_of != NULL) { + if (m->is_deprecated && !m->deprecation_warning_printed) { + SPDK_WARNLOG("RPC method %s is deprecated. Use %s instead.\n", m->name, m->is_alias_of->name); + m->deprecation_warning_printed = true; + } + m = m->is_alias_of; + } + if ((m->state_mask & g_rpc_state) == g_rpc_state) { m->func(request, params); } else { @@ -255,6 +266,36 @@ spdk_rpc_register_method(const char *method, spdk_rpc_method_handler func, uint3 SLIST_INSERT_HEAD(&g_rpc_methods, m, slist); } +void +spdk_rpc_register_alias_deprecated(const char *method, const char *alias) +{ + struct spdk_rpc_method *m, *base; + + base = _get_rpc_method_raw(method); + if (base == NULL) { + SPDK_ERRLOG("cannot create alias %s - method %s does not exist\n", + alias, method); + return; + } + + if (base->is_alias_of != NULL) { + SPDK_ERRLOG("cannot create alias %s of alias %s\n", alias, method); + return; + } + + m = calloc(1, sizeof(struct spdk_rpc_method)); + assert(m != NULL); + + m->name = strdup(alias); + assert(m->name != NULL); + + m->is_alias_of = base; + m->is_deprecated = true; + + /* TODO: use a hash table or sorted list */ + SLIST_INSERT_HEAD(&g_rpc_methods, m, slist); +} + int spdk_rpc_is_method_allowed(const char *method, uint32_t state_mask) {