Генерация события горячего подключения

Предыдущая  Содержание  Следующая V*D*V

Событие горячего подключения является уведомлением пользовательского пространства от ядра, что в конфигурации системы что-то изменилось. Они генерируются при создании или уничтожении kobject-а. Такие события генерируются, например, когда цифровая камера подключается при помощи кабеля USB, когда пользователь переключает режимы консоли, или когда диск заново разбит на разделы. События горячего подключения превращаются в вызов /sbin/hotplug, который может реагировать на каждое событие загрузкой драйверов, созданием узлов устройств, монтированием разделов, или любыми другими действиями, которые являются необходимыми.

 

Последней важной функцией kobject-а, которую мы рассмотрим, является генерация этих событий. Фактическая генерация события имеет место, когда kobject передаётся в kobject_add или kobject_del. Перед тем, как событие передано в пространство пользователя, код, связанный с kobject (или, более конкретно, kset, к которому он принадлежит), имеет возможность добавить информацию для пространства пользователя или полностью запретить генерацию события.

Операции горячего подключения

Фактический контроль событий горячего подключения осуществляется путём набора методов, хранящихся в структуре kset_hotplug_ops:

 

struct kset_hotplug_ops {

    int (*filter)(struct kset *kset, struct kobject *kobj);

    char *(*name)(struct kset *kset, struct kobject *kobj);

    int (*hotplug)(struct kset *kset, struct kobject *kobj,

                   char **envp, int num_envp, char *buffer,

                   int buffer_size);

};

 

Указатель на эту структуру можно найти в поле hotplug_ops структуры kset-а. Если данный kobject не содержится в kset-е, ядро осуществляет поиск вверх по иерархии (с помощью указателя parent), пока не найдёт kobject, который имеет kset; затем используются операции горячего подключения этого kset-а.

 

Операция filter горячего подключения вызывается всякий раз, когда ядро рассматривает возможность генерации события для данного kobject-а. Если filter возвращает 0, событие не создаётся. Этот метод, таким образом, даёт коду kset-а возможность определить, какие события следует передать в пользовательское пространство, а какие нет.

 

В качестве примера того, как может быть использован этот метод, рассмотрим блочную подсистему. Есть по крайней мере три типа используемых в ней kobject-ов, представляющих диски, разделы и очереди запросов. Пользовательское пространство может захотеть реагировать на добавление диска или раздела, но оно обычно не заботится об очередях запросов. Таким образом, метод filter разрешает  генерацию события только для kobject-ов, представляющих диски и разделы. Выглядит это примерно так:

 

static int block_hotplug_filter(struct kset *kset, struct kobject *kobj)

{

    struct kobj_type *ktype = get_ktype(kobj);

 

    return ((ktype == &ktype_block) || (ktype == &ktype_part));

}

 

Здесь достаточно быстрого теста на тип kobject, чтобы решить, должно ли событие быть сгенерированным или нет.

 

При вызове программы горячего подключения пользовательского пространства, в качестве единственного параметра ей передаётся имя соответствующей подсистемы. Метод name горячего подключения отвечает за предоставление этого имени. Он должен возвращать простую строку, подходящую для передачи в пространство пользователя.

 

Всё остальное, что скрипт горячего подключения может захотеть узнать, передаётся в окружении. Последний метод горячего подключения (hotplug) даёт возможность добавлять полезные переменные окружения перед вызовом этого скрипта. Повторим, что прототипом метода является:

 

int (*hotplug)(struct kset *kset, struct kobject *kobj,

               char **envp, int num_envp, char *buffer,

               int buffer_size);

 

Как обычно, kset и kobject описывают объект, для которого генерируется событие. Массив envp является местом для сохранения дополнительных определений переменных окружения (в обычном формате ИМЯ=значение); в нём доступны записи num_envp. Сами переменные должны быть закодированы в буфере размером buffer_size байт. Если вы добавляете любую переменную к envp, не забудьте после вашего последнего добавления добавить запись NULL, чтобы ядро знало, где находится конец. Возвращаемое значение, как правило, 0; любая ненулевое возвращаемое значение прерывает генерацию события горячего подключения.

 

Генерация событий горячего подключения (как значительная часть работы в модели устройства), как правило, обрабатываться с помощью логики на уровне шины драйвера.

Предыдущая  Содержание  Следующая