Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Логирование из ядра ОС, аналог printk  (Прочитано 21939 раз)
0 Пользователей и 6 Гостей смотрят эту тему.
den
Интересующийся

ru
Offline Offline

« : 29-10-2008 16:37 » 

Здравствуйте, все.
Короче, есть задача. Есть некий модуль ядра (драйвер), необходимо чтобы сообщения (ошибка ли, предупреждение ли и т.д.) от этого модуля сохранялись в каком-нибудь другом файле нежели стандартный - /var/log/messges например. Сейчас в модуле все сообщения реализованы с помощью функции printk, она конечно хорошая, однако пишет всегда в системный лог, а хотелось бы чтобы можно было бы писать в другой какой-нибудь файл.
Читал про то что можно сделать что-то подобное с помощью netlink сокетов, но успеха не достиг.
Еще можно пропробовать провернуть что-то подобное с помощью файловой системы /proc. Если есть возможность подскажите пожалуйста в каком направлении копать?
Заранее всем благодарен
Записан
McZim
Команда клуба

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #1 : 29-10-2008 21:11 » 

den, зачем такие сложности? Открывай/создавай файл логов в нужном месте и с нужным названием, и пиши в него всю необходимую информацию, на необходимом этапе работы модуля.
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
den
Интересующийся

ru
Offline Offline

« Ответ #2 : 30-10-2008 08:38 » 

В том то все и дело, что из пространства ядра не так то просто создать файл и записать туда что-то, насколько я знаю в ядре линукс это делается через вируальную файловую систему (VFS), она отвечает за все действия с файлами и разделами на жестком диске, и даже использование системных функций таких как sys_open, sys_read, sys_write не дало желаемого результата. Жаль
Записан
McZim
Команда клуба

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #3 : 30-10-2008 08:47 » 

den,  у тебя же сейчас пишется в /var/log/messges посмотри как это реализовано и сделай тоже самое но в другое место.
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #4 : 30-10-2008 11:27 » 

printk() пишет не в лог, а в кольцевой буфер в ядре. Демон klogd читает это добро и передает в syslogd. Далее все определяется правилами syslog - это все в твоих руках.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
den
Интересующийся

ru
Offline Offline

« Ответ #5 : 30-10-2008 14:29 » 

Спасибо всем!
Порылся в инете, почитал доки, наткнулся на интересный код, немного доработав под себя, получил вот что:
Код тестового модуля, который при загрузке пишет что-то в файл "/tmp/file.f". Сейчас сижу тестирую, вроде работает...
Код:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/proc_fs.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/signal.h>
//#include <linux/signalfd.h>
#include <asm/unistd.h>
#include <asm/siginfo.h>
#include <asm/uaccess.h>
#include <linux/fs.h>
#include <linux/syscalls.h>
#include <linux/init.h>
#include <linux/file.h>
#include <linux/mm.h>
#include <linux/slab.h>

#define PROCFS_MAX_SIZE 1024
#define RIGHTS S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH

MODULE_LICENSE("GPL");

static int __open__(void)
{
    int length_read, length_write, length_llseek;
    char buffer[255];
    struct file * f = NULL;
    struct inode *inode;
    mm_segment_t orig_fs;
   
    f = filp_open("/tmp/file.f",O_CREAT | O_RDWR, RIGHTS);
    if (!f || !f->f_op || !f->f_op->read || !f->f_op->write || !f->f_op->llseek) {
printk(KERN_INFO "File (read || write || llseek) object is a null pointer!\n");
return -1;
    }
   
    strcpy(buffer,"YYYY\n");
   
    orig_fs = get_fs();
    set_fs(KERNEL_DS);
   
    inode = f->f_dentry->d_inode;
    printk(KERN_INFO "File size - %u\n", (unsigned int)inode->i_size);
   
   
    //length_llseek = f->f_op->llseek(f, f->f_pos, (int)inode->i_size);
    //printk(KERN_INFO "length_llseek=%d\n", length_llseek);
   
    f->f_pos = f->f_pos + inode->i_size;
   
    length_write = f->f_op->write(f, buffer, strlen(buffer), &f->f_pos);
   
    fput(f);
   
    return 0;
}

//=====================================================================================================
static int file_mod_init(void)
{
    printk(KERN_INFO "file_mod init:\n");
    __open__();
    return 0;
}
//=====================================================================================================
static void file_mod_exit(void)
{
    printk(KERN_ALERT "file_mod exit\n");
}
//=====================================================================================================
module_init(file_mod_init);
module_exit(file_mod_exit);
Если кто найдет какие-нибудь ошибки, или недочеты, буду очень благодарен
« Последнее редактирование: 30-10-2008 19:41 от Finch » Записан
den
Интересующийся

ru
Offline Offline

« Ответ #6 : 30-10-2008 14:33 » 

Теперь надо бы додумать как дату и время записи в файл корретно прилепить, чтобы походил на настоящий лог-файл. А то я не совсем еще хорошо ориентируюсь в kernel programming Улыбаюсь
Записан
Sava
Участник

by
Offline Offline

« Ответ #7 : 11-11-2008 09:43 » new

den, можно вопрос: Как этот код компилировать? я создала Makefile: obj-m:=имя_модуля.ko
и компилирую: make -C /usr/src/..путь./ M=$PWD modules
Где ошибка? plz, help
Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #8 : 11-11-2008 12:26 » 

Sava, не кажется тебе, что телепатов здесь нет? Улыбаюсь
Маловато информации. Покажи Makefile и текст ошибки.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
den
Интересующийся

ru
Offline Offline

« Ответ #9 : 12-11-2008 12:14 » 

Здравствуйте все!
Я оставил эту идею с записью информации в файл прямо из пространства ядра. Причин есть несколько:
1) Ну во-первых так никто не делает, из соображений безопасности и совместимости, так как нарушается абстракция. Ну например /var/log/messages может быть и не смонтирована в системе, или смонтирована по сети.
2) Если возникнет какая-то непредвиденная ошибка, то ядро может лечь, и не подняться больше никогда.
3) Есть уже готовая система логирования - syslog. Зачем изобретать велосипед?

Вот именно с помощью сислога, которая включает в себя демоны klogd, syslogd я и решил свою задачу по логированию сообщений от нужного мне модуля/драйвера. Собственно syslogd я и не трогал, я порылся в исходниках klogd, нашел где и как он ловит и фильтрует сообщения от ядра, немного изменив код, и снабдив свои сообщения уникальным префиксом я заставил klogd не передовать мои сообщения syslogd, а писать их сразу в нужный мне файл. 

Всем еще раз спасибо.
Записан
den
Интересующийся

ru
Offline Offline

« Ответ #10 : 12-11-2008 12:16 » 

А вообще можно наверно было сделать вот так:
tail -f /var/log/chtonado | grep priznak >> kudanado &
Улыбаюсь
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines