如何在Linux内核空间读取环形缓冲区?

我正在写一个Linux字符驱动程序,可以在用户空间打印系统日志。 就像命令“dmesg”一样。 我知道所有用printk打印的日志都会被发送到一个名为ring buffer的空间。 所以我有这样的问题:

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

你正在寻找的是/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

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 

所以现在是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 

所以你去了,1743是rsyslogd,它将/ proc / kmsg的输出重定向到/ var / log / syslog和/var/log/kern.log等文件。