read () очищает кольцевой буфер ядра / proc / kmsg? - PullRequest
3 голосов
/ 28 февраля 2012

Я разработал собственную программу обработки журналов. чтобы обрабатывать журналы, созданные в 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);

и я постоянно получаю данные. Поскольку klogctl () с аргументом 4 считывает и очищает кольцевой буфер, я полагаю, что какой-то модуль ДОЛЖЕН постоянно отправлять мне журналы.

Может кто-нибудь сказать мне - читает () очистить кольцевой буфер?

Ответы [ 2 ]

5 голосов
/ 28 февраля 2012

Зарегистрируйтесь как root и запустите cat /proc/kmsg >> File1.txt и cat /proc/kmsg >> File2.txt.Сравните File1.txt и File2.txt. Вы сразу узнаете, очищается ли кольцевой буфер на read(), потому что cat все равно вызывает внутренне read()!

Также читайте о кольцевых буферах и их поведении в документации по ядру здесь - http://www.mjmwired.net/kernel/Documentation/trace/ring-buffer-design.txt

EDIT : я нашел кое-что интересное в книге 1016* Linux Device Drivers от Jonathan Corbet-

Функция printk записывает сообщения в кольцевой буфер, длина которого __ LOG_BUF_LEN : значение от 4 КБ до 1 МБ выбрано при настройке ядра.Затем функция запускает любой процесс, ожидающий сообщений, то есть любой процесс, который находится в режиме ожидания системного вызова syslog или читает / proc / kmsg .Эти два интерфейса для механизма ведения журнала почти эквивалентны, но обратите внимание, что чтение из / proc / kmsg потребляет данные из буфера журнала , тогда как системный вызов syslog может при желании вернуть данные журналаоставляя это для других процессов, а также.В общем, чтение файла / proc проще и является поведением по умолчанию для klogd .Команда dmesg может использоваться для просмотра содержимого буфера без его очистки;фактически, команда возвращает stdout все содержимое буфера, независимо от того, было ли оно уже прочитано

Так что в вашем конкретном случае, если вы используете простой read(), я думаю, что буфер действительно очищается и в него постоянно записываются новые данные, и, следовательно, вы постоянно находите некоторые данные!Специалисты по ядру могут поправить меня здесь!

0 голосов
/ 28 февраля 2012

При чтении функции do_syslog кажется, что сообщения очищаются при прочтении.
По вашему описанию вы получаете то же поведение с klogctl(4), который также очищает буфер, поэтому имеет смысл.

Так что, возможно, действительно есть кто-то, кто продолжает писать сообщения.
Вы можете найти, какой это printk, по тексту, отключить его и посмотреть, что вы получите.Или вы можете добавить значение jiffies к сообщению, чтобы вы знали, продолжаете ли вы получать новые сообщения, или это те же самые сообщения.

...