From 43b961b62562d44b11ccbbb025abe12b4f20e6b2 Mon Sep 17 00:00:00 2001 From: Chengwen Feng Date: Wed, 9 Oct 2024 04:50:27 +0000 Subject: [PATCH] kvargs: rework process API [ upstream commit de89988365a7ca4087dd451c675320c993910332 ] The rte_kvargs_process() was used to handle: - key=value (e.g. socket_id=0), - key (e.g. socket_id). But many drivers callback only handle key=value, which results in crashes if being passed only-key. Rather than go and fix all drivers as proposed in the link mentioned below: - a new API rte_kvargs_process_opt() was introduced: it inherits the function of rte_kvargs_process() which could handle both key=value and only-key cases. - the original rte_kvargs_process() is now limited to the key=value cases, it will return -1 when handle only-key case, This patch also makes sure that both process API reject a NULL kvlist parameter. Link: https://patches.dpdk.org/project/dpdk/patch/20230320092110.37295-1-fengchengwen@huawei.com/ Signed-off-by: Chengwen Feng Acked-by: Ferruh Yigit --- lib/kvargs/rte_kvargs.c | 36 +++++++++++++++++++++++++++--------- lib/kvargs/rte_kvargs.h | 33 ++++++++++++++++++++++++++++++--- lib/kvargs/version.map | 1 + 3 files changed, 58 insertions(+), 12 deletions(-) diff --git a/lib/kvargs/rte_kvargs.c b/lib/kvargs/rte_kvargs.c index c77bb82..1d35551 100644 --- a/lib/kvargs/rte_kvargs.c +++ b/lib/kvargs/rte_kvargs.c @@ -167,31 +167,49 @@ rte_kvargs_count(const struct rte_kvargs *kvlist, const char *key_match) return ret; } -/* - * For each matching key, call the given handler function. - */ -int -rte_kvargs_process(const struct rte_kvargs *kvlist, - const char *key_match, - arg_handler_t handler, - void *opaque_arg) +static int +kvargs_process_common(const struct rte_kvargs *kvlist, const char *key_match, + arg_handler_t handler, void *opaque_arg, bool support_only_key) { const struct rte_kvargs_pair *pair; unsigned i; if (kvlist == NULL) - return 0; + return -1; for (i = 0; i < kvlist->count; i++) { pair = &kvlist->pairs[i]; if (key_match == NULL || strcmp(pair->key, key_match) == 0) { + if (!support_only_key && pair->value == NULL) + return -1; if ((*handler)(pair->key, pair->value, opaque_arg) < 0) return -1; } } + return 0; } +/* + * For each matching key in key=value, call the given handler function. + */ +int +rte_kvargs_process(const struct rte_kvargs *kvlist, const char *key_match, arg_handler_t handler, + void *opaque_arg) +{ + return kvargs_process_common(kvlist, key_match, handler, opaque_arg, false); +} + +/* + * For each matching key in key=value or only-key, call the given handler function. + */ +int +rte_kvargs_process_opt(const struct rte_kvargs *kvlist, const char *key_match, + arg_handler_t handler, void *opaque_arg) +{ + return kvargs_process_common(kvlist, key_match, handler, opaque_arg, true); +} + /* free the rte_kvargs structure */ void rte_kvargs_free(struct rte_kvargs *kvlist) diff --git a/lib/kvargs/rte_kvargs.h b/lib/kvargs/rte_kvargs.h index b0d1301..73fa1e6 100644 --- a/lib/kvargs/rte_kvargs.h +++ b/lib/kvargs/rte_kvargs.h @@ -166,14 +166,17 @@ const char *rte_kvargs_get_with_value(const struct rte_kvargs *kvlist, const char *key, const char *value); /** - * Call a handler function for each key/value matching the key + * Call a handler function for each key=value matching the key * - * For each key/value association that matches the given key, calls the + * For each key=value association that matches the given key, calls the * handler function with the for a given arg_name passing the value on the * dictionary for that key and a given extra argument. * + * @note Compared to @see rte_kvargs_process_opt, this API will return -1 + * when handle only-key case (that is the matched key's value is NULL). + * * @param kvlist - * The rte_kvargs structure. No error if NULL. + * The rte_kvargs structure. * @param key_match * The key on which the handler should be called, or NULL to process handler * on all associations @@ -189,6 +192,30 @@ const char *rte_kvargs_get_with_value(const struct rte_kvargs *kvlist, int rte_kvargs_process(const struct rte_kvargs *kvlist, const char *key_match, arg_handler_t handler, void *opaque_arg); +/** + * Call a handler function for each key=value or only-key matching the key + * + * For each key=value or only-key association that matches the given key, calls + * the handler function with the for a given arg_name passing the value on the + * dictionary for that key and a given extra argument. + * + * @param kvlist + * The rte_kvargs structure. + * @param key_match + * The key on which the handler should be called, or NULL to process handler + * on all associations + * @param handler + * The function to call for each matching key + * @param opaque_arg + * A pointer passed unchanged to the handler + * + * @return + * - 0 on success + * - Negative on error + */ +int rte_kvargs_process_opt(const struct rte_kvargs *kvlist, + const char *key_match, arg_handler_t handler, void *opaque_arg); + /** * Count the number of associations matching the given key * diff --git a/lib/kvargs/version.map b/lib/kvargs/version.map index cda85d1..0720b1b 100644 --- a/lib/kvargs/version.map +++ b/lib/kvargs/version.map @@ -8,6 +8,7 @@ DPDK_24 { rte_kvargs_parse; rte_kvargs_parse_delim; rte_kvargs_process; + rte_kvargs_process_opt; local: *; }; -- 2.33.0