【问题标题】:How to read ring buffer within linux kernel space?如何在 linux 内核空间中读取环形缓冲区?
【发布时间】:2016-07-28 22:00:34
【问题描述】:

我正在编写一个可以在用户空间打印系统日志的 Linux 字符驱动程序。就像命令“dmesg”一样。 我了解到我们使用“printk”打印的所有日志都将被发送到一个名为环形缓冲区的空间。所以我有问题:

  1. 环形缓冲区是否在内核空间内?
  2. 如果是这样,我如何读取内核空间内的环形缓冲区? (我曾尝试阅读 dmesg.c 的源代码。但没有帮助。)

【问题讨论】:

    标签: linux logging linux-kernel kernel circular-buffer


    【解决方案1】:

    您正在寻找的是/proc/kmsg。这是内核环形缓冲区!

    1. 是的,这是在内核空间内。任何试图读取它的进程都应该具有超级用户权限才能读取它!

    2. 如何读取环形缓冲区?这是来自 IBM Developerworks 的精美插图

    dmesg 将是您的首选! dmesg 是如何完成任务的?致电syslog()syslog 是如何工作的?通过系统调用接口依次调用do_syslog()do_syslog() 的整理行为类似于 this

    这里还有一些资源可让您获得有关 /proc/kmsg 和一般内核日志记录的更多信息-

    1. http://www.makelinux.net/ldd3/chp-4-sect-2

    2. http://www.ibm.com/developerworks/linux/library/l-kernel-logging-apis/index.html

    3. http://oguzhanozmen.blogspot.in/2008/09/kernel-log-buffering-printk-syslog-ng.html

    【讨论】:

    • 太棒了!非常专业和有用的答案!你看,我只是 Linux 内核编程的新手,我不能再感谢你的帮助了。谢谢你。
    • 很高兴能为您提供帮助 :) 欢迎来到 SO!
    【解决方案2】:

    这比 Pavan 的非常好的回答更进一步(教会了我很多):

    不同的发行版可能会将 /proc/kmsg 的输出重定向到他们喜欢的任何物理日志文件或虚拟设备 (/dev/xxx)。但是“/proc/kmsg”是内核日志的原始来源,因为内核在fs/proc/kmsg.c内部实现了它的环形缓冲区操作:

    static const struct file_operations proc_kmsg_operations = {
            .read           = kmsg_read,
            .poll           = kmsg_poll,
            .open           = kmsg_open,
            .release        = kmsg_release,
            .llseek         = generic_file_llseek,
    };
    

    所以你看到的输出是这样的:

    sudo tail -f /proc/kmsg

    但是您只能看到发出此命令后生成的所有消息 - 环形缓冲区中的所有先前消息都不会被打印出来。所以要查看物理文件输出,可以搜索“/proc/kmsg”的用户:

    sudo lsof |grep proc.kmsg

    我的机器表明了这一点:

    rsyslogd  1743               syslog    3r      REG                0,3          0 4026532041 /proc/kmsg
    in:imuxso 1743 1755          syslog    3r      REG                0,3          0 4026532041 /proc/kmsg
    in:imklog 1743 1756          syslog    3r      REG                0,3          0 4026532041 /proc/kmsg
    rs:main   1743 1757          syslog    3r      REG                0,3          0 4026532041 /proc/kmsg
    

    所以现在是pid 1743,让我们看看1743打开的文件fd:

    sudo ls -al /proc/1743/fd

    lrwx------ 1 root   root   64 Dec 11 08:36 0 -> socket:[14472]
    l-wx------ 1 root   root   64 Dec 11 08:36 1 -> /var/log/syslog
    l-wx------ 1 root   root   64 Dec 11 08:36 2 -> /var/log/kern.log
    lr-x------ 1 root   root   64 Dec 11 08:36 3 -> /proc/kmsg
    l-wx------ 1 root   root   64 Dec 11 08:36 4 -> /var/log/auth.log
    

    这样,pid 1743 是 rsyslogd,它将 /proc/kmsg 的输出重定向到 /var/log/syslog 和 /var/log/kern.log 等文件。

    【讨论】:

      猜你喜欢
      • 2017-08-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-10
      • 1970-01-01
      • 2012-03-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多