Модераторы: xvr

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Тема вопросов и ответов по ядру 
:(
    Опции темы
konshyn
Дата 26.1.2015, 12:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 295
Регистрация: 19.9.2013

Репутация: нет
Всего: нет



Надеюсь, модераторы не против:)

Суть: отдельная тема, чтобы не создавать каждый раз новую, где я, а может и другие, будут задавать общие вопросы по ядру linux (НЕ решение какой-то определенной проблемы)

Итак, первый вопрос:
раньше (предполагаю версию ядра меньше 2.16.0) в файле cat /proc/kallsyms вместе с эксмортируемыми именами выводился в первом столбике абсолютный адрес в пространстве ядра этих имен (точка входа). На моем ядре (3.16.0) все адреса заменены на нули. Мне кажется, что это связано с тем, что ядро перестало экспориторовать функцию sys_call_table(), хотя она в файле /proc/kallsyms все еще есть, но когда загружаю модель, где использую эту функцию, то вылетает ошибка имя неопределено. Правильно ли я понимаю, что отсутствие адресов в файлу связано именно с отсутствием экспорта функции sys_call_table? И как в новых версиях ядра можно перехватывать системные вызовы?


--------------------
«Потому что ценность акта действия в этой стране возрастает в несколько раз».
PM MAIL Skype   Вверх
tzirechnoy
Дата 26.1.2015, 20:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1173
Регистрация: 30.1.2009

Репутация: 3
Всего: 16



Цитата
хотя она в файле /proc/kallsyms все еще есть,


Вы уверены, что в /proc/kallsyms?

Цитата
то отсутствие адресов в файлу связано именно с отсутствием экспорта функции sys_call_table?


Нет, вообще никак не связано. sys_call_table запретили где-то в 2.5, а чтение адресов ядра неруту -- в 2.6.38 (см. kptr_restrict)

Цитата
И как в новых версиях ядра можно перехватывать системные вызовы?


Копайте в сторону lsm. Это совсем другой метод, но для большынства практических задач это дажэ удобнее.
PM MAIL   Вверх
konshyn
Дата 29.1.2015, 19:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 295
Регистрация: 19.9.2013

Репутация: нет
Всего: нет



Код

static int __init lkp_init(void) {
    int ret;
    dev_t dev;

    ret = alloc_chrdev_region ( &dev, DEVICE_FIRST, 1, MODUL_NAME ); 
    major = MAJOR( dev );

    if ( ret < 0 ) {
        printk( KERN_ERR "=== Can not register char device region\n" );
        return ret;
    }

    cdev_init( &hcdev, &dev_fops );
    hcdev.owner = THIS_MODULE;
    ret = cdev_add( &hcdev, dev, 1 );
    if ( ret < 0 ) {
        unregister_chrdev_region( MKDEV( major, DEVICE_FIRST ), 1 );
        printk( KERN_ERR "=== Can not add char device\n" );
        return ret;
    }

    devclass = class_create( THIS_MODULE, CLASS_NAME );
    device_create( devclass, NULL, dev, "%s", DEVICE_NAME );

    printk( KERN_INFO "=========== module installed %d:%d ===========\n", MAJOR( dev ), MINOR( dev ) );

    return EOK;
}


это код регистрации устройства и создания имени в каталоге /dev.
Так вот, после того, как создалось имя, например, example (/dev/example), то он имеет права доступа 600, и получается, что я не могу ничего записать в этой файл, хотя считывать, например через cat  могу (приходится использовать sudo, вроде бы логично, но записать через sudo все равно не могу) . Операции read() и write() поддерживаются. Приходится менять права доступа так, чтобы было разрешение записи "для всех остальных". (например 002). 
Кто может это объяснить? И как сделать так, чтобы файл в /dev создавался с нужными правами?


--------------------
«Потому что ценность акта действия в этой стране возрастает в несколько раз».
PM MAIL Skype   Вверх
konshyn
Дата 29.1.2015, 20:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 295
Регистрация: 19.9.2013

Репутация: нет
Всего: нет



Есть что-нибудь похожее на strerror() в ядре?


--------------------
«Потому что ценность акта действия в этой стране возрастает в несколько раз».
PM MAIL Skype   Вверх
tzirechnoy
Дата 30.1.2015, 01:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1173
Регистрация: 30.1.2009

Репутация: 3
Всего: 16



Цитата
приходится использовать sudo, вроде бы логично, но записать через sudo все равно не могу


Если ты пишэшь sudo cat a >b; то a открывает cat, запущенный от рута, а b -- твой шэлл, поскольку это перенаправление в shell.

Цитата
то он имеет права доступа 600, и получается, что я не могу ничего записать в этой файл


Файл в /dev создаёт udev, он жэ и права ему назначает. Есть, правда, свойство uevent DEVMODE, которое позволяет драйверу указать mode (по умолчанию), но это, по большому счёту, не принято (по сути им только /dev/zero, /dev/random, /dev/tty пользуются).

А так -- пишы GROUP и MODE в правилах udev. Кстати, у него сейчас работает нигде не описанная эвристика (нахера они её написали, если незадокументировали?) -- что если не ставишь ни GROUP ни MODE, то MODE по умолчанию 0600, а если указал GROUP без MODE -- то MODE ужэ станет 0660. Но лучшэ не выпендриваться, и задавать что надо самому.

Цитата
Есть что-нибудь похожее на strerror() в ядре?


Нет, нету. Обычно, если ты хочешь просто strerror() -- то оно и пользовательским кодом или strace замечательно напечатается, просто верни ошыбку.

А если ты пишэшь это в логи ядра -- то тебе нужно что-то заметно более информативное, чем strerror().

Ну, в крайнем случае, если возврат ошыбки не вариант, а у тебя что-то есть -- напишы %d, администратор не идиот, разберётся.
PM MAIL   Вверх
konshyn
Дата 30.1.2015, 10:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 295
Регистрация: 19.9.2013

Репутация: нет
Всего: нет



Цитата(tzirechnoy @  30.1.2015,  01:32 Найти цитируемый пост)

Если ты пишэшь sudo cat a >b; то a открывает cat, запущенный от рута, а b -- твой шэлл, поскольку это перенаправление в shell.

Вот этого не знал. Спасибо)
А как сделать, чтобы и перенаправление было через sudo, если это возможно?

Цитата(tzirechnoy @  30.1.2015,  01:32 Найти цитируемый пост)
(нахера они её написали, если незадокументировали?)

Насколько я понимаю, ядро вообще никто не документирует официально.

Цитата(tzirechnoy @  30.1.2015,  01:32 Найти цитируемый пост)

Нет, нету

Жаль, конечно. кОдов ошибок там куча, и было бы удобно иметь такую штуку.


Цитата(tzirechnoy @  30.1.2015,  01:32 Найти цитируемый пост)
Обычно, если ты хочешь просто strerror() -- то оно и пользовательским кодом или strace замечательно напечатается, просто верни ошыбку.

Суть в том, что я должен вернуть ошибку, если модуль не загрузился. И причину. Получает, что когда модуль загружаю из консоли, то при возврате печатается текст ошибки, а если в логи писать, то нужно самому. Поэтому и сделал такой вариант (с небольшим комментарием от ситуации):

Цитата(tzirechnoy @  30.1.2015,  01:32 Найти цитируемый пост)
Ну, в крайнем случае, если возврат ошыбки не вариант, а у тебя что-то есть -- напишы %d, администратор не идиот, разберётся. 


Но, все-таки, надеялся, что есть что-то информативное.


Это сообщение отредактировал(а) konshyn - 30.1.2015, 10:24


--------------------
«Потому что ценность акта действия в этой стране возрастает в несколько раз».
PM MAIL Skype   Вверх
tzirechnoy
Дата 30.1.2015, 12:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1173
Регистрация: 30.1.2009

Репутация: 3
Всего: 16



Цитата
А как сделать, чтобы и перенаправление было через sudo, если это возможно?


Я обычно делаю sudo sh -c 'cat "$0" >"$1"' a b или как-то так.
Впрочем, вариантов, разумеется, масса -- какой-нибудь, например, pv или tee через sudo, который сам открывает выходной файл, или просто sudo sh и дальшэ делать всё, что хочешь.

Цитата
Насколько я понимаю, ядро вообще никто не документирует официально.


udev -- это не ядро.

(всё собираюсь мигрировать на hotplug2, поскольку udev всё большэ bloated и насыщен такими внезапными приколами).
PM MAIL   Вверх
konshyn
Дата 30.1.2015, 12:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 295
Регистрация: 19.9.2013

Репутация: нет
Всего: нет



Цитата(tzirechnoy @  30.1.2015,  12:29 Найти цитируемый пост)
например, pv или tee через sudo, который сам открывает выходной файл, или просто sudo sh и дальшэ делать всё, что хочешь.

tee вполне подходит, спасибо


Цитата(tzirechnoy @  30.1.2015,  12:29 Найти цитируемый пост)

udev -- это не ядро.

(всё собираюсь мигрировать на hotplug2, поскольку udev всё большэ bloated и насыщен такими внезапными приколами). 

я пока во всем этом, мягко говоря, не разбираюсь, поэтому дельных комментариев сказать не могу:)


--------------------
«Потому что ценность акта действия в этой стране возрастает в несколько раз».
PM MAIL Skype   Вверх
konshyn
Дата 30.1.2015, 13:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 295
Регистрация: 19.9.2013

Репутация: нет
Всего: нет



В /proc я создаю через  proc_create() создаю несколько файлов. В эту самую функцию требуется struct file_operations, я определяю только функцию чтения. Для каждого файла у меня своя структура и соответственно своя функция чтения. Хочется при создании трех файлов отправлять всем одинаковую структуру ( а не создавать три разные) с одной функцией чтения, а для этого нужно как-то в функции чтения различать, какой файл открыт, желательно что-то наподобии дескрипторов (например, в /dev я могу различать все по major и minor). 
В функцию чтения передается  struct file. Какие там поля могут мне помочь в этом, или как вообще делают создание нескольких файлов в одном модуле?


--------------------
«Потому что ценность акта действия в этой стране возрастает в несколько раз».
PM MAIL Skype   Вверх
tzirechnoy
Дата 30.1.2015, 13:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1173
Регистрация: 30.1.2009

Репутация: 3
Всего: 16



inode

Но конкретно с /proc не знаю -- получится ли у тебя его соотнести с чем-то.

Добавлено через 9 минут и 17 секунд
Впрочем, посмотрел -- вроде офицыальный путь -- proc_create_data (последний параметр -- свой указатель), затем PDE_DATA(inode) на пришэдшэе в .open в file_ops.
PM MAIL   Вверх
konshyn
Дата 30.1.2015, 15:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 295
Регистрация: 19.9.2013

Репутация: нет
Всего: нет



Цитата(tzirechnoy @  30.1.2015,  13:23 Найти цитируемый пост)
Впрочем, посмотрел -- вроде офицыальный путь -- proc_create_data (последний параметр -- свой указатель), затем PDE_DATA(inode) на пришэдшэе в .open в file_ops. 

не могу найти это.

например, в структуре file есть поле private_data - туда можно запихнуть указатель на данные.
но я так и не понял, как через inode я могу отличить файлы в /proc, хотя с устройствами в /dev все легко и понятно

Добавлено @ 15:23
Все, нашел. Можно узнать имя файла в .open из структуры file->f_dentry
Код

...
static int device_open( struct inode *inode, struct file *file ) {
...
    printk( KERN_INFO "%s\n", file->f_dentry->d_iname );
...
}


Это сообщение отредактировал(а) konshyn - 30.1.2015, 15:35


--------------------
«Потому что ценность акта действия в этой стране возрастает в несколько раз».
PM MAIL Skype   Вверх
tzirechnoy
Дата 30.1.2015, 16:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1173
Регистрация: 30.1.2009

Репутация: 3
Всего: 16



Код

#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
#include <linux/proc_fs.h>

#define PDE_DATA(inode)    PROC_I(inode)->pde->data

static inline void proc_remove(struct proc_dir_entry *pde)
{
    remove_proc_entry(pde->name, pde->parent);
}

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)
static inline struct proc_dir_entry *
proc_create_data(const char *name, mode_t mode, struct proc_dir_entry *parent,
         const struct file_operations *proc_fops, void *data)
{
    struct proc_dir_entry *pde = create_proc_entry(name, mode, parent);

    if (pde) {
        pde->proc_fops = proc_fops;
        pde->data = data;
    }
    return pde;
}
#endif /* < 2.6.26 */
#endif /* < 3.10 */


(стырену у нормальных людей)
PM MAIL   Вверх
konshyn
Дата 30.1.2015, 16:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 295
Регистрация: 19.9.2013

Репутация: нет
Всего: нет



Цитата(tzirechnoy @  30.1.2015,  16:06 Найти цитируемый пост)
(стырену у нормальных людей) 

а в чем разница этого кода и того, что я сделал (через указатель на данные?)

А проблема была вообще в том, чтобы различить файлы при открытии. В коде я этого не увидел, или просто слепой)


--------------------
«Потому что ценность акта действия в этой стране возрастает в несколько раз».
PM MAIL Skype   Вверх
tzirechnoy
Дата 30.1.2015, 16:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1173
Регистрация: 30.1.2009

Репутация: 3
Всего: 16



Цитата
через указатель на данные?


Указатель на данные -- это нормально, а вот в том, что d_iname там всегда будет тожэ самое, а не изнасилованное каким-нибудь unionfs или ещё как просранное -- я бы не очень надеялся.
Вот в номере inode можно быть более-менее уверенным (в смысле -- что он будет такой жэ, как вернулся в proc_create). В том, что если этот proc_create_data скомпилируется, то будет делать именно то, что нужно -- тожэ. А d_iname не выглядит стабильной вещью.
PM MAIL   Вверх
konshyn
Дата 30.1.2015, 17:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 295
Регистрация: 19.9.2013

Репутация: нет
Всего: нет



Цитата(tzirechnoy @  30.1.2015,  16:47 Найти цитируемый пост)

Указатель на данные -- это нормально, а вот в том, что d_iname там всегда будет тожэ самое, а не изнасилованное каким-нибудь unionfs или ещё как просранное -- я бы не очень надеялся.
Вот в номере inode можно быть более-менее уверенным (в смысле -- что он будет такой жэ, как вернулся в proc_create). В том, что если этот proc_create_data скомпилируется, то будет делать именно то, что нужно -- тожэ. А d_iname не выглядит стабильной вещью. 

Жаль, что я не понимаю, что такое unionfs и как он может покалечить имя файла


--------------------
«Потому что ценность акта действия в этой стране возрастает в несколько раз».
PM MAIL Skype   Вверх
Google
  Дата 26.5.2019, 06:33 (ссылка)  





  Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Программирование под Unix/Linux"
xvr
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • Не забывайте пользоваться кнопкой "Код".
  • Вопросы мобильной разработки тут
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к разделу форума. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, xvr.

 
 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Программирование под Unix/Linux | Следующая тема »


 




[ Время генерации скрипта: 0.1400 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.