read()清除内核环形缓冲区/ proc / kmsg?

我开发了我自己的日志处理程序。 处理源自printk()的日志,我从内核环形缓冲区中读取,如下所示:

#define _PATH_KLOG "/proc/kmsg" CGR_INT kernelRingBufferFileDescriptor = open(_PATH_KLOG, O_RDONLY|O_NONBLOCK); CGR_CHAR kernelLogMessage[MAX_KERNEL_RING_BUFFER + 1] = {'\0'}; while (1) { ... read(kernelRingBufferFileDescriptor, kernelLogMessage + residueSize, MAX_KERNEL_RING_BUFFER); ... } 

我的程序在用户空间。 我记得有人用read()读取环形缓冲区中的数据(就像我上面所做的那样),读取的部分将从环形缓冲区中清除。 是这样,还是不是?

我对此感到困惑,因为环形缓冲区中总是有一些东西,所以我的程序非常忙于处理所有这些日志。 所以我不确定是因为某些模块正在向我发送日志,或者是因为我一次又一次读取相同的日志,因为日志没有被清除。

要弄清楚,我使用klogctl()来检查环形缓冲区:

 CGR_CHAR buf[MAX_KERNEL_RING_BUFFER] = {0}; int byteCount = klogctl(4, buf, MAX_KERNEL_RING_BUFFER - 1); /* 4 -- Read and clear all messages remaining in the ring buffer */ printf("%s %d: data read from kernel ring buffer = \"%s\"\n",__FILE__, __LINE__, buf); 

我一直在收集数据。 由于带有参数4的klogctl()读取并清除环形缓冲区,所以我相信有些模块会一直向我发送日志。

谁能告诉我 – 读取()清除环形缓冲区?

成为root并运行这个cat /proc/kmsg >> File1.txtcat /proc/kmsg >> File2.txt 。 比较File2.txtFile2.txt您将立即知道在read()上环形缓冲区是否被清除。cos cat内部调用read()

还请阅读关于环形缓冲区以及它们如何在内核文档中的行为 – http://www.mjmwired.net/kernel/Documentation/trace/ring-buffer-design.txt

编辑 :我发现了一些有趣的书籍 Linux Device Drivers由乔纳森科贝特 –

printk函数将消息写入__LOG_BUF_LEN字节长的循环缓冲区:配置内核时选择的值为4 KB1 MB 。 然后该函数唤醒正在等待消息的任何进程,即在syslog系统调用中正在休眠或正在读取/ proc / kmsg的进程。 这两个接口与日志记录引擎几乎是等价的,但是请注意, 从/ proc / kmsg中读取消耗了日志缓冲区中的数据 ,而syslog系统调用可以选择性地返回日志数据,而将其留给其他进程使用。 通常,读取/ proc文件比较容易,而且是klogd的默认行为。 dmesg命令可以用来查看缓冲区的内容而不用清除它; 实际上,该命令返回标准输出缓冲区的全部内容,不管它是否已被读取

所以在你的特殊情况下,如果你正在使用一个简单的read() ,我认为缓冲区确实已经被清除了,并且新的数据被不断的写入,所以你总是可以找到一些数据! 内核专家可以在这里纠正我!

从阅读do_syslog函数看来,消息在读取时被清除。
通过你的描述,你会得到与klogctl(4)相同的行为,这也清除了缓冲区,所以它是有道理的。

所以也许确实有人不断写信息。
你可以通过文本找到它是哪个printk ,禁用它,看看你得到了什么。 或者你可以把jiffies值添加到消息中,所以你会知道你是否继续收到新消息,或者这些消息是相同的。