我开发了自己的日志处理程序。为了处理源自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()读取并清除了环形缓冲区,我有点相信某些模块会一直向我发送日志。
任何人都可以告诉我 - 读取()清除环形缓冲区吗?
答案 0 :(得分:5)
成为root用户并运行此cat /proc/kmsg >> File1.txt
和cat /proc/kmsg >> File2.txt
。比较File1.txt
和File2.txt
您将立即知道在read()
cos cat
内是否已清除环形缓冲区内部调用read()
!
此处还阅读有关环形缓冲区及其在内核文档中的行为的信息 - http://www.mjmwired.net/kernel/Documentation/trace/ring-buffer-design.txt
编辑:我在Jonathan Corbet的book Linux Device Drivers
中发现了一些有趣的内容 -
printk函数将消息写入循环缓冲区 __ LOG_BUF_LEN 字节长:配置内核时选择 4 KB 到 1 MB 的值。然后该函数唤醒任何进程 等待消息,即任何正在睡觉的进程 syslog 系统调用或正在读取 / proc / kmsg 。这两个接口 到日志引擎几乎相同,但请注意读取 从/ proc / kmsg消耗来自日志缓冲区的数据,而 syslog 系统调用可以选择返回日志数据,同时保留它 其他过程也是如此。通常,阅读 / proc 文件更容易 并且是 klogd 的默认行为。可以使用 dmesg 命令 查看缓冲区的内容而不刷新它;其实, 该命令是否返回 stdout 缓冲区的全部内容 或者它已被阅读
因此,在您的特定情况下,如果您使用普通read()
,我认为缓冲区确实已被清除,并且新数据不断被写入其中,因此您始终可以找到一些数据!内核专家可以在这里纠正我!
答案 1 :(得分:0)
通过阅读do_syslog
功能,消息在阅读时似乎已被清除
根据您的描述,您可以使用klogctl(4)
获得相同的行为,这也会清除缓冲区,因此它是有意义的。
所以也许确实有人不断写信息
你可以通过文本找到它printk
,禁用它,看看你得到了什么。或者您可以在邮件中添加jiffies
值,这样您就可以知道是否继续收到新邮件,或者这些邮件是否相同。