[ovs-dev] [PATCH] dpdk: Add commands to configure log levels.

David Marchand david.marchand at redhat.com
Fri Jun 26 12:27:23 UTC 2020


Enabling debug logs in dpdk can be a challenge to be sure of what is
actually enabled, add commands to list and change those log levels.
This does not help when tracking issues in dpdk init itself: dump log
levels right after init.

Signed-off-by: David Marchand <david.marchand at redhat.com>
---
 lib/dpdk.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 113 insertions(+)

diff --git a/lib/dpdk.c b/lib/dpdk.c
index 31450d4708..98d0e2643e 100644
--- a/lib/dpdk.c
+++ b/lib/dpdk.c
@@ -36,6 +36,7 @@
 #include "ovs-numa.h"
 #include "smap.h"
 #include "svec.h"
+#include "unixctl.h"
 #include "util.h"
 #include "vswitch-idl.h"
 
@@ -261,6 +262,102 @@ static cookie_io_functions_t dpdk_log_func = {
     .write = dpdk_log_write,
 };
 
+static void
+dpdk_unixctl_log_list(struct unixctl_conn *conn, int argc OVS_UNUSED,
+                      const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED)
+{
+    char *response = NULL;
+    FILE *stream;
+    size_t size;
+
+    stream = open_memstream(&response, &size);
+    if (!stream) {
+        response = xasprintf("Unable to open memstream: %s.",
+                             ovs_strerror(errno));
+        unixctl_command_reply_error(conn, response);
+        goto out;
+    }
+
+    rte_log_dump(stream);
+    fclose(stream);
+    unixctl_command_reply(conn, response);
+out:
+    free(response);
+}
+
+static int
+dpdk_parse_log_level(const char *s)
+{
+    static const char * const levels[] = {
+        [RTE_LOG_EMERG]   = "emergency",
+        [RTE_LOG_ALERT]   = "alert",
+        [RTE_LOG_CRIT]    = "critical",
+        [RTE_LOG_ERR]     = "error",
+        [RTE_LOG_WARNING] = "warning",
+        [RTE_LOG_NOTICE]  = "notice",
+        [RTE_LOG_INFO]    = "info",
+        [RTE_LOG_DEBUG]   = "debug",
+    };
+    int i;
+
+    for (i = 1; i < ARRAY_SIZE(levels); ++i) {
+        if (!strcmp(s, levels[i])) {
+            return i;
+        }
+    }
+    return -1;
+}
+
+static void
+dpdk_unixctl_log_set(struct unixctl_conn *conn, int argc, const char *argv[],
+                     void *aux OVS_UNUSED)
+{
+    int i;
+
+    /* With no argument, set all logtypes level to "debug". */
+    if (argc == 1) {
+        rte_log_set_level_pattern("*", RTE_LOG_DEBUG);
+    }
+    for (i = 1; i < argc; i++) {
+        char *level_string;
+        char *pattern;
+        char *s;
+        int level;
+
+        s = xstrdup(argv[i]);
+        level_string = strchr(s, ':');
+        if (level_string == NULL) {
+            pattern = "*";
+            level_string = s;
+        } else {
+            pattern = s;
+            level_string[0] = '\0';
+            level_string++;
+        }
+
+        level = dpdk_parse_log_level(level_string);
+        if (level == -1) {
+            char *msg = xstrdup("invalid level");
+
+            unixctl_command_reply_error(conn, msg);
+            free(s);
+            free(msg);
+            return;
+        }
+
+        if (rte_log_set_level_pattern(pattern, level) < 0) {
+            char *msg = xasprintf("cannot set log level for %s", argv[i]);
+
+            unixctl_command_reply_error(conn, msg);
+            free(s);
+            free(msg);
+            return;
+        }
+        free(s);
+    }
+    unixctl_command_reply(conn, NULL);
+}
+
 static bool
 dpdk_init__(const struct smap *ovs_other_config)
 {
@@ -423,8 +520,24 @@ dpdk_init__(const struct smap *ovs_other_config)
             VLOG_DBG("Could not dump memzone. Unable to open memstream: %s.",
                      ovs_strerror(errno));
         }
+
+        stream = open_memstream(&response, &size);
+        if (stream) {
+            rte_log_dump(stream);
+            fclose(stream);
+            VLOG_DBG("rte_log_dump:\n%s", response);
+            free(response);
+        } else {
+            VLOG_DBG("Could not dump log levels. "
+                     "Unable to open memstream: %s.", ovs_strerror(errno));
+        }
     }
 
+    unixctl_command_register("dpdk/log-list", "", 0, 0,
+                             dpdk_unixctl_log_list, NULL);
+    unixctl_command_register("dpdk/log-set", "pattern:level", 0, INT_MAX,
+                             dpdk_unixctl_log_set, NULL);
+
     /* We are called from the main thread here */
     RTE_PER_LCORE(_lcore_id) = NON_PMD_CORE_ID;
 
-- 
2.23.0



More information about the dev mailing list