14.3. Генерация события горячего подключения |
Событие горячего подключения является уведомлением пользовательского пространства от ядра, что в конфигурации системы что-то изменилось. Они генерируются при создании или уничтожении 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; любая ненулевое возвращаемое значение прерывает генерацию события горячего подключения.
Генерация событий горячего подключения (как значительная часть работы в модели устройства), как правило, обрабатываться с помощью логики на уровне шины драйвера.
Комментариев нет:
Отправить комментарий
Примечание. Отправлять комментарии могут только участники этого блога.