kvargs: add function to get from key and value
authorOlivier Matz <olivier.matz@6wind.com>
Wed, 29 Sep 2021 21:39:41 +0000 (23:39 +0200)
committerDavid Marchand <david.marchand@redhat.com>
Thu, 30 Sep 2021 15:38:02 +0000 (17:38 +0200)
A quite common scenario with kvargs is to lookup for a <key>=<value> in
a kvlist. For instance, check if name=foo is present in
name=toto,name=foo,name=bar. This is currently done in drivers/bus with
rte_kvargs_process() + the rte_kvargs_strcmp() handler.

This approach is not straightforward, and can be replaced by this new
function.

rte_kvargs_strcmp() is then removed.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
Reviewed-by: Xueming Li <xuemingl@nvidia.com>
Reviewed-by: David Marchand <david.marchand@redhat.com>
Acked-by: Ray Kinsella <mdr@ashroe.eu>
doc/guides/rel_notes/release_21_11.rst
drivers/bus/auxiliary/auxiliary_params.c
drivers/bus/vdev/vdev_params.c
lib/kvargs/rte_kvargs.c
lib/kvargs/rte_kvargs.h
lib/kvargs/version.map

index 73e377a..945a3d4 100644 (file)
@@ -157,6 +157,10 @@ API Changes
    Also, make sure to start the actual text at the margin.
    =======================================================
 
+* kvargs: The experimental function ``rte_kvargs_strcmp()`` has been
+  removed. Its usages have been replaced by a new function
+  ``rte_kvargs_get_with_value()``.
+
 * cryptodev: The API rte_cryptodev_pmd_is_valid_dev is modified to
   rte_cryptodev_is_valid_dev as it can be used by the application as
   well as PMD to check whether the device is valid or not.
index cd3fa56..a9c7853 100644 (file)
@@ -25,13 +25,12 @@ auxiliary_dev_match(const struct rte_device *dev,
              const void *_kvlist)
 {
        const struct rte_kvargs *kvlist = _kvlist;
-       int ret;
+       const char *key = auxiliary_params_keys[RTE_AUXILIARY_PARAM_NAME];
 
-       ret = rte_kvargs_process(kvlist,
-                       auxiliary_params_keys[RTE_AUXILIARY_PARAM_NAME],
-                       rte_kvargs_strcmp, (void *)(uintptr_t)dev->name);
+       if (rte_kvargs_get_with_value(kvlist, key, dev->name) == NULL)
+               return -1;
 
-       return ret != 0 ? -1 : 0;
+       return 0;
 }
 
 void *
index 6f74704..37d9539 100644 (file)
@@ -26,19 +26,10 @@ static int
 vdev_dev_match(const struct rte_device *dev,
               const void *_kvlist)
 {
-       int ret;
        const struct rte_kvargs *kvlist = _kvlist;
-       char *name;
+       const char *key = vdev_params_keys[RTE_VDEV_PARAM_NAME];
 
-       /* cannot pass const dev->name to rte_kvargs_process() */
-       name = strdup(dev->name);
-       if (name == NULL)
-               return -1;
-       ret = rte_kvargs_process(kvlist,
-               vdev_params_keys[RTE_VDEV_PARAM_NAME],
-               rte_kvargs_strcmp, name);
-       free(name);
-       if (ret != 0)
+       if (rte_kvargs_get_with_value(kvlist, key, dev->name) == NULL)
                return -1;
 
        return 0;
index 38e9d5c..11f624e 100644 (file)
@@ -204,21 +204,34 @@ rte_kvargs_free(struct rte_kvargs *kvlist)
        free(kvlist);
 }
 
-/* Lookup a value in an rte_kvargs list by its key. */
+/* Lookup a value in an rte_kvargs list by its key and value. */
 const char *
-rte_kvargs_get(const struct rte_kvargs *kvlist, const char *key)
+rte_kvargs_get_with_value(const struct rte_kvargs *kvlist, const char *key,
+                         const char *value)
 {
        unsigned int i;
 
-       if (kvlist == NULL || key == NULL)
+       if (kvlist == NULL)
                return NULL;
        for (i = 0; i < kvlist->count; ++i) {
-               if (strcmp(kvlist->pairs[i].key, key) == 0)
-                       return kvlist->pairs[i].value;
+               if (key != NULL && strcmp(kvlist->pairs[i].key, key) != 0)
+                       continue;
+               if (value != NULL && strcmp(kvlist->pairs[i].value, value) != 0)
+                       continue;
+               return kvlist->pairs[i].value;
        }
        return NULL;
 }
 
+/* Lookup a value in an rte_kvargs list by its key. */
+const char *
+rte_kvargs_get(const struct rte_kvargs *kvlist, const char *key)
+{
+       if (kvlist == NULL || key == NULL)
+               return NULL;
+       return rte_kvargs_get_with_value(kvlist, key, NULL);
+}
+
 /*
  * Parse the arguments "key=value,key=value,..." string and return
  * an allocated structure that contains a key/value list. Also
@@ -270,12 +283,3 @@ rte_kvargs_parse_delim(const char *args, const char * const valid_keys[],
        free(copy);
        return kvlist;
 }
-
-int
-rte_kvargs_strcmp(const char *key __rte_unused,
-                 const char *value, void *opaque)
-{
-       const char *str = opaque;
-
-       return -abs(strcmp(str, value));
-}
index 328f0d3..3c1754c 100644 (file)
@@ -116,7 +116,7 @@ void rte_kvargs_free(struct rte_kvargs *kvlist);
 /**
  * Get the value associated with a given key.
  *
- * If multiple key matches, the value of the first one is returned.
+ * If multiple keys match, the value of the first one is returned.
  *
  * The memory returned is allocated as part of the rte_kvargs structure,
  * it must never be modified.
@@ -132,6 +132,33 @@ void rte_kvargs_free(struct rte_kvargs *kvlist);
  */
 const char *rte_kvargs_get(const struct rte_kvargs *kvlist, const char *key);
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Get the value associated with a given key and value.
+ *
+ * Find the first entry in the kvlist whose key and value match the
+ * ones passed as argument.
+ *
+ * The memory returned is allocated as part of the rte_kvargs structure,
+ * it must never be modified.
+ *
+ * @param kvlist
+ *   A list of rte_kvargs pair of 'key=value'.
+ * @param key
+ *   The matching key. If NULL, any key will match.
+ * @param value
+ *   The matching value. If NULL, any value will match.
+ *
+ * @return
+ *   NULL if no key matches the input,
+ *   a value associated with a matching key otherwise.
+ */
+__rte_experimental
+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
  *
@@ -170,32 +197,6 @@ int rte_kvargs_process(const struct rte_kvargs *kvlist,
 unsigned rte_kvargs_count(const struct rte_kvargs *kvlist,
        const char *key_match);
 
-/**
- * Generic kvarg handler for string comparison.
- *
- * This function can be used for a generic string comparison processing
- * on a list of kvargs.
- *
- * @param key
- *   kvarg pair key.
- *
- * @param value
- *   kvarg pair value.
- *
- * @param opaque
- *   Opaque pointer to a string.
- *
- * @return
- *   0 if the strings match.
- *   !0 otherwise or on error.
- *
- *   Unlike strcmp, comparison ordering is not kept.
- *   In order for rte_kvargs_process to stop processing on match error,
- *   a negative value is returned even if strcmp had returned a positive one.
- */
-__rte_experimental
-int rte_kvargs_strcmp(const char *key, const char *value, void *opaque);
-
 #ifdef __cplusplus
 }
 #endif
index 236f35c..0d42cd5 100644 (file)
@@ -14,6 +14,6 @@ DPDK_22 {
 EXPERIMENTAL {
        global:
 
-       rte_kvargs_strcmp;
-
+       # added in 21.11
+       rte_kvargs_get_with_value;
 };