LOG(7) LOG(7)
НАЗВАНИЕ
log - интерфейс для регистрации ошибок и трассировки
событий псевдоустройств
ОПИСАНИЕ
Драйвер log обеспечивает интерфейс для процессов ре-
гистрации ошибок и трассировки событий псевдоустройств
[см. strerr(1M), strace(1M)]. Log предоставляет два от-
дельных интерфейса: интерфейс вызова функций из ядра,
через который драйверы и модули псевдоустройств переда-
ют сообщения для регистрации, а также набор команд для
системного вызова ioctl(2) для взаимодействия на прик-
ладном уровне с процессами регистрации и трассировки, а
также для процессов, которым требуется регистрировать
свои собственные сообщения.
Вызов функций из ядра
Сообщения передаются для регистрации путем вызова из
ядра функции strlog:
#include
#include
#include
strlog (mid, sid, level, flags, fmt, arg1, ...)
short mid, sid;
char level;
unsigned short flags;
char *fmt;
unsigned int arg1;
Аргумент mid - это идентификатор модуля для модуля или
драйвера, посылающего сообщение для регистрации. Аргу-
мент sid задает дополнительный внутренний числовой
идентификатор, обычно используемый для идентификации
младшего устройства в драйвере. Аргумент level - это
уровень приоритета трассировки, дающий возможность из-
бирательной трассировки (пропуска сообщений с низким
приоритетом). Аргумент flags представляет собой комби-
нацию следующих значений:
SL_ERROR
Сообщение зарегистрировать, как ошибку.
SL_TRACE
Трассировочное сообщение.
SL_FATAL
Фатальная ошибка.
SL_NOTIFY
Послать сообщение системному администратору через
mail(1).
Аргумент fmt - это цепочка символов, задающая формат в
стиле printf(3S), но спецификаторы %s, %e, %E, %g и %G
не обрабатываются. Количество дополнительных числовых
аргументов (arg1, ...) ограничено величиной NLOGARGS (в
настоящий момент оно равно 3).
Интерфейс пользователя
Доступ к интерфейсу log обеспечивается путем открытия
устройства /dev/log через драйвер clone(7). Каждое отк-
рытие устройства /dev/log образует отдельный поток к
драйверу log. Чтобы получать сообщения от драйвера log,
процесс должен оповестить драйвер с помощью команды
I_STR системного вызова ioctl(2) о своем желании обра-
батывать сообщения об ошибках или трассировочные сооб-
щения, указав в качестве третьего аргумента для систем-
ного вызова ioctl адрес структуры типа struct strioctl.
struct strioctl {
int ic_cmd; /* Команда */
int ic_timout; /* Таймаут */
int ic_len; /* Длина данных */
char *ic_dp; /* Указатель на данные */
};
Для того, чтобы обрабатывать сообщения об ошибках, не-
обходимо в поле ic_cmd передаваемой структуры записать
константу I_ERRLOG, в поле ic_len - 0, а в поле ic_dp -
NULL. Для того, чтобы обрабатывать трассировочные сооб-
щения, необходимо в поле ic_cmd передаваемой структуры
записать константу I_TRCLOG, в поле ic_dp задать адрес
массива структур типа struct trace_ids, а в поле ic_len
- длину этого массива в байтах.
struct trace_ids {
short ti_mid;
short ti_sid;
char ti_level;
};
Каждый элемент массива задает значения идентификатора
модуля, идентификатора устройства и уровня принимаемых
сообщений. Функция strlog будет выдавать только те со-
общения, для которых значения идентификаторов модуля и
устройства совпадают с указанными в массиве, а значение
уровня не превосходит указанного в массиве. Задание
значения -1 в любом из полей ti_mid, ti_sid, ti_level
означает отсутствие соответствующих ограничений.
В каждый момент времени только один процесс может обра-
батывать сообщения об ошибках и только один процесс мо-
жет обрабатывать трассировочные сообщения.
После того, как процесс с помощью системного вызова
ioctl объявил, что он будет обрабатывать сообщения, log
начинает посылать ему все сообщения, удовлетворяющие
указанным ограничениям. Эти сообщения можно получить с
помощью системного вызова getmsg(2).
Управляющая область сообщения содержит структуру типа
struct log_ctl, в которой указаны идентификаторы модуля
и устройства, уровень, флаги, время посылки сообщения в
тактах часов от последней загрузки системы, то же время
в секундах от 1 января 1970 года и порядковый номер.
struct log_ctl {
short mid;
short sid;
char level;
short flags;
long ltime; /* Время в тактах от загрузки */
long ttime; /* Время в секундах от 1.01.1970 */
long seq_no; /* Порядковый номер */
};
Время в секундах от 1 января 1970 года позволяет уз-
нать, когда было послано сообщение, а время в тактах
позволяет получить информацию об интервалах между сооб-
щениями. Поддерживаются два ряда последовательных номе-
ров: для сообщений об ошибках и для трассировочных со-
общений. Пропуски в порядковых номерах позволяют опре-
делить факт потери сообщений при чересчур высокой ин-
тенсивности обменов.
Область данных сообщения содержит формат - цепочку сим-
волов, оканчивающуюся нулем, за которым следуют выров-
ненные по границе слова NLOGARGS слов, представляющих
аргументы для этого формата.
Любой процесс, даже не являющийся обработчиком ошибок
или трассировок, может посылать сообщения подобной
структуры драйверу log. При этом в управляющей области
сообщения в структуре log_ctl можно задать только поля
level и flags, остальные поля перед передачей на обра-
ботку заполняет сам драйвер log. Область данных должна
содержать формат, за которым, выравненные по границе
слова, могут следовать до NLOGARGS слов, представляющих
аргументы.
Попытка задания команд I_ERRLOG или I_TRCLOG, когда уже
существует процесс-обработчик того же типа, приводит к
ошибке с кодом ENXIO. Та же ошибка ENXIO выдается, если
для команды I_TRCLOG не задан массив структур
trace_ids, а также если третий аргумент в команде I_STR
некорректен. Сообщения для драйвера log из программы
пользователя, которые имеют неправильную структуру, иг-
норируются без сообщений об ошибках.
ПРИМЕРЫ
1. Пример запроса на обработку сообщений об ошибках:
struct strioctl ioc;
ic.ic_cmd = IERRLOG;
ic.ic_timeout = 0; /* Таймаут по умолчанию (15 с) */
ic.ic_len = 0;
ic.ic_dp = NULL;
ioctl (log, I_STR, &ioc);
2. Пример запроса на обработку трассировочных сообще-
ний:
struct strioctl ioc;
struct trace_ids tid [2];
tid[0].ti_mid = 2;
tid[0].ti_sid = 0;
tid[0].ti_level = 1;
tid[1].ti_mid = 1002;
tid[1].ti_sid = -1; /* Любой */
tid[1].ti_level = -1; /* Любой */
ic.ic_cmd = ITRCLOG;
ic.ic_timeout = 0;
ic.ic_len = 2 * sizeof (struct trace_ids);
ic.ic_dp = (char *) tid;
ioctl (log, I_STR, &ioc);
3. Пример передачи сообщений драйверу log (без аргумен-
тов):
struct strbuf ctl, dat;
struct log_ctl lc;
char *message = "I am waiting for you";
ctl.len = ctl.maxlen = sizeof (lc);
ctl.buf = (char *) &lc;
dat.len = dat.maxlen = strlen (message) + 1;
dat.buf = message;
lc.level = 0;
lc.flags = SL_ERROR | SL_NOTIFY;
putmsg (log, &ctl, &dat, 0);
ФАЙЛЫ
/dev/log
СМ. ТАКЖЕ
strace(1M), strerr(1M), clone(7).
intro(2), getmsg(2), ioctl(2), putmsg(2) в Справочнике
программиста.
|