LINUX.ORG.RU

Чтение и запись файла в модуле ядра

 , ,


0

1

Всем привет, очень нужна помощь с пониманием логики модулей ядра.

Есть одно задание - написать модуль ядра, на входе у него 3 файла. В двух текст, нужно текст склеить и записать его в третий файл. Есть еще упоминание что работать это должно через /proc

Я уже и гугл весь перерыл и книги все доступные перелистал, но я совершенно не понимаю как это делать.

Из того что я понял по книгам: 1) Модуль общается с ядром и все взаимодействие происходит через память 2) Мы можем читать/писать файлы в /proc 3) Мы можем передать параметры при загрузке модуля в систему через moduleparam.h

И вот модуль загружен, вот есть девайс /dev/test1, есть файлы /tmp/test1, /tmp/test2, /tmp/test3. И каким образом можно получить их содержимое? Я нашел что можно читать/писать /proc, /dev, ибо там уже есть связь User Space - Kernel Space. Вся связь к тому же идет через указатели.

Еще, каким образом это хотя бы примерно должно работать? Есть file_operations, и вот создал я девайс, и могу обратиться к нему либо по Open, либо по Write. Соответственно тут какой-то бред - чтоб склеить файлы мне нужно вызывать «cat /dev/test1»?

Возможно немного сумбурно получилось, но я совершенно не могу понять логики. Буду рад абсолютно любой подсказке

Трудно понять, насколько конкретно написано задание, а сколько оставлено «для творчества». Я бы предположил из упомянутого, что через /proc должны передаваться имена файлов для обработки.

Elyas ★★★★★ ()
Ответ на: комментарий от Elyas

Ну тут если с именами файлов еще более менее понятно, их-то я получил, остаются 2 проблемы:

1) Как открыть и считать файл внутри модуля, имея только его имя ( в гугле нашел пару упоминаний о том, что так делать ни в коем случае нельзя, вроде как из lkm рассылки, и какое-то одно странное решение)

2) В какой момент производить чтение и запись, то что я выше описал про «чтоб склеить файлы мне нужно вызывать «cat /dev/test1»?»

Kronick ()
Ответ на: комментарий от I-Love-Microsoft

Вот в гугле все такое и пишут, и по этому заданию я никак понять не могу что именно должно быть, либо лыжи не едут, либо еще что-то. Возможно я тут упускаю что-то фундаментальное. Нашел кое-что про ioctl, но там опять же взаимодействие в памяти и ничего про то что нужно мне.

Kronick ()
Ответ на: комментарий от Kronick

вообще читать системным вызовом в ведре можно. главная проблема в том, что будет ругаться uaccess на ядерные адреса. тебе надо заглушить ругать uaccess на адрес в ядре.

гугли uaccess kernel space address

либо ты можешь покопаться в нутре ядра и посмотреть кого вызывает sys_open.

i36_zubov ()
Ответ на: комментарий от i36_zubov

Ну я так подозреваю что компания та же, но не в Питере. Я вообще не знаю что делать, мне закинули задание и не отвечают, я уже третьи сутки спать нормально не могу

Kronick ()
Ответ на: комментарий от i36_zubov

То есть я правильно понимаю, что это не я что упускаю, а задание странноватое и придется все-таки вкручивать костыли?

Kronick ()

написать модуль ядра, на входе у него 3 файла. В двух текст, нужно текст склеить и записать его в третий файл. Есть еще упоминание что работать это должно через /proc

Должен быть голый модуль, или допускается вспомогательная программа? Иначе дичь какая-то.

I-Love-Microsoft ★★★★★ ()
Ответ на: комментарий от anonymous

Если я все правильно понял, то: extern struct file *filp_open(const char *, int, umode_t);

«const char *» - сюда просто вбить имя файла? Что-то вроде:

filp_open(«/tmp/test1», 80, MODE)

Обязательно попробую чуть позже, спасибо

Kronick ()
Ответ на: комментарий от I-Love-Microsoft

Вот тут не знаю, это все что есть. Я написал разве что init скрипт, чтоб автоматически создавать девайс по номеру из /proc/devices. Вот думаю туда же впилить еще и имена файлов, итого получится шелл скрипт с 4 параметрами( start|stop + файлы ). Звучит так себе, но других вариантов я не вижу

Kronick ()
Ответ на: комментарий от Kronick

Я не эксперт, так, слышал кое-что :). Фактически любые файловые операции из юзерспейс все равно выполняются ядром. Другое дело, что для юзерспейс программ ядро неявно выполняет некоторые другие операции, потому корректный код для для копирования одного файла в другой в ядерном модуле будет более многострочным, чем в обычной программе.

Elyas ★★★★★ ()
Ответ на: комментарий от Kronick

ну как тут выше написали, открыть/закрыть файл ты можешь с filp_open/filp_close. читать/писать - вот это делают

// Get current segment descriptor
fs = get_fs();
// Set segment descriptor associated to kernel space
set_fs(get_ds());
// Read the file
f->f_op->read(f, buf, 128, &f->f_pos);
// Restore segment descriptor
set_fs(fs);

это собственно обман uaccess который проверяет, чтоб userspace адрес из ядра не подсунул.

i36_zubov ()
Ответ на: комментарий от i36_zubov

Так вот что это такое, я видел этот код, но не особо понял зачем он нужен. После словесного описания все встало на свои места, большое спасибо.

Kronick ()
Ответ на: комментарий от i36_zubov

это собственно обман uaccess который проверяет, чтоб userspace адрес из ядра не подсунул

Это законно? Так можно делать или это из под вывиха? Может ТС-а проверяют на аккуратность следования канонам и правилам, его склонность поддаваться на соблазн костылевания... :)

I-Love-Microsoft ★★★★★ ()
Ответ на: комментарий от I-Love-Microsoft

Ну а куда деваться? Сам ответа не нашел, спросил там где его могли бы знать если бы он был. Не сказать же мне «Не по канонам, отказываюсь такое писать!». Задачу нужно решить, какая бы странная она ни была, ну а если вариантов действительно нет - то почему бы и не вкрутить костыль

Kronick ()
Ответ на: комментарий от Kronick

К тому же еще непосредственное слияние строк я буду выполнять через 'cat /dev/test1'. Как по мне - это максимально странный вариант, но надо же как-то дернуть этот девайс, других вариантов я особо не вижу.

Kronick ()
Ответ на: комментарий от i36_zubov

Вот это кстати интересная идея. Я конечно понятия не имею что такое poll, но догадываюсь. Можно еще шедулер какой прикрутить, и вообще огонь будет. Спасибо за идею

Kronick ()

Re: The most common question asked in this don't-do-that category is, “How do I read a file from within my kernel module?”

2) Мы можем читать/писать файлы в /proc

Похоже, лучше через sysfs:

http://www.linuxjournal.com/article/8110

Кстати, интересно, тот кто дал задание, заходит на ЛОР?

gag ★★★★★ ()
Ответ на: комментарий от alx777

А вот и человеческое решение, нормальное, без костылей и без всякой ереси. Огромное спасибо, я пожалуй так и сделаю, теперь все точно встало на свои места. Как реализовать я знаю, найти не проблема, просто куча инфы в голове и нет понимания как это склеить по-человечески и вывести все в один солюшн без кучи костылей и странного кода. Я думаю это ровно то что нужно и отвечает на все мои вопросы.

Идеально, я просто счастлив :3

Kronick ()

Я подозреваю что да. Но мне вот по почте не отвечают, а задание надо сделать в любом случае, я уже и спать совсем перестал, если тут ответят - то чем плох такой вариант?

Kronick ()
Ответ на: комментарий от Kronick

нет понимания как это склеить по-человечески

В таком решении требуется буфер в памяти, уж не знаю какой там можно динамический придумать, cat будет тебе выдавать череду записей блоков по 32 Кбайт (например). Если файлы будут по 5 гигабайт, то не знаю что будет.

I-Love-Microsoft ★★★★★ ()
Ответ на: комментарий от I-Love-Microsoft

В таком решении требуется буфер в памяти

Для тестового задания можно и статически определить. И да, в постановке задачи максимальную длину файлов хорошо бы указать

Если файлы будут по 5 гигабайт, то не знаю что будет.

Ничего не будет если в proc_write сделать проверку на остаток места в буфере и возвращать ошибку

Вообще /proc насколько я знаю в основном используется для проверки статуса или конфигурирования, что подразумевает сравнительно небольшие объемы данных. Можно конечно представить что кто-то реально льет гигабайты на/c железа через /proc, но что-то мне подсказывает что для этого существуют более подходящие методы

alx777 ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.