ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

vpp中dpdk日志的配置和查看

2021-11-30 13:34:48  阅读:633  来源: 互联网

标签:rte log level 日志 dpdk vpp


        首先在 vpp 配置文件(/etc/vpp/startup.conf) 的 dpdk section 添加 log-level debug 配置项,其中 debug 是日志级别。在 vpp 的 dpdk_config 函数中将 log-level 解析到了整型变量 log_level 中:

else if (unformat (input, "log-level %U", unformat_dpdk_log_level, &x))
        log_level = x;

        然后,通过 dpdk 提供的 rte_log_set_global_level (log_level) 函数,将 log_level 设置到了全局结构体变量 rte_logs 中:

/* Set global log level */
void
rte_log_set_global_level(uint32_t level)
{ 
        rte_logs.level = (uint32_t)level;
}   

        接着,dpdk 在运行过程中产生的日志通过 pipe 方式发送 vpp:

  int log_fds[2] = { 0 };
  if (pipe (log_fds) == 0)
    {
      FILE *f = fdopen (log_fds[1], "a");
      if (f && rte_openlog_stream (f) == 0)
        {
          clib_file_t t = { 0 };
          t.read_function = dpdk_log_read_ready;
          t.file_descriptor = log_fds[0];
          t.description = format (0, "DPDK logging pipe");
          clib_file_add (&file_main, &t);
        }
    }

        然后,vpp 会定期去轮询 dpdk 的日志信息,用户在 vpp 命令行里面可以通过 show log 来查看 dpdk 的日志信息。

        上述方式查看 dpdk 日志的前提是 vpp 启动成功,如果 vpp 在启动过程中因 dpdk 报错而启动失败,那么就无法看到 dpdk 的日志信息。

        解决方法:
        使用 gdb 对 vpp 进行调试,将断点打在 src/plugins/dpdk/device/init.c:1351 行附近,然后当 vpp 执行完第 1354 行的代码:FILE *f = fdopen(log_fds[1], "a"); 后,在 gdb 中通过 "set var f = 0",将 f 强制赋值为空指针,以便跳过对 rte_openlog_stream (f) 的调用,这样 dpdk 在初始化过程中产生的日志就不会写入 pipe 中,而是写入 stdout 和 syslog 中,或是 stderr 中。

        经过上述修改后,依然发现 rte_eal_init() 执行过程中的某些日志没有被打印,这是因为在 dpdk 初始化时 EAL 模块默认的日志级别是:INFO,所以 DEBUG 级别的日志没有被输出,如下代码所示:

/* Logging should be first initializer (before drivers and bus) */
RTE_INIT_PRIO(rte_log_init, LOG);
static void
rte_log_init(void)
{
        uint32_t i;

        rte_log_set_global_level(RTE_LOG_DEBUG);

        rte_logs.dynamic_types = calloc(RTE_LOGTYPE_FIRST_EXT_ID,
                sizeof(struct rte_log_dynamic_type));
        if (rte_logs.dynamic_types == NULL)
                return;

        /* register legacy log types */
        for (i = 0; i < RTE_DIM(logtype_strings); i++)
                __rte_log_register(logtype_strings[i].logtype,
                                logtype_strings[i].log_id);

        rte_logs.dynamic_types_len = RTE_LOGTYPE_FIRST_EXT_ID;
}

        上述代码通过 __rte_log_register() 注册了 EAL 模块的日志级别:

static int
__rte_log_register(const char *name, int id)
{
        char *dup_name = strdup(name);

        if (dup_name == NULL)
                return -ENOMEM;

        rte_logs.dynamic_types[id].name = dup_name;
        rte_logs.dynamic_types[id].loglevel = RTE_LOG_INFO;

        return id;
}

        可以看到默认的日志级别是: RTE_LOG_INFO。

        这个有一个快捷的修改方法,思路和上面的一样,当 gdb 命中上述断点后,手动修改 EAL 模块的日志级别,步骤如下:
        1)修改前确认:

(gdb) p rte_logs.dynamic_types[0]
$4 = {name = 0xaaaab9d3d0 "lib.eal", loglevel = 7}

        从上面的输出可以看到,修改前 EAL 模块的日志信息已经注册成功,该模块对应的下标为 0,loglevel = 7,为 INFO 级别。
        2)进行修改:

(gdb) set rte_logs.dynamic_types[0].loglevel=8
(gdb) p rte_logs.dynamic_types[0]
$5 = {name = 0xaaaab9d3d0 "lib.eal", loglevel = 8}

        确认已经修改成功。依次类推,还可以手动修改其他模块的日志级别。
        最后,在 gdb 中让程序 continue,接下来就能看到 dpdk 在初始化过程中产生的大量日志了。

标签:rte,log,level,日志,dpdk,vpp
来源: https://blog.csdn.net/choumin/article/details/121630307

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有