21

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

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

2 回答 2

46

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

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

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

读取内核环缓冲区

dmesg将是您的第一选择!dmesg如何完成它的任务?通过调用syslog()syslog是如何工作的?通过系统调用接口依次调用do_syslog()do_syslog()整理是这样的

这里还有一些资源可以让你获得更多关于/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

于 2012-03-02T19:14:05.930 回答
5

这比 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,
};

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

须藤尾巴 -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 等文件。

于 2015-12-11T00:52:25.203 回答