Лучший способ связи от KEXT к Daemon и блокировки, пока результат не будет возвращен от Daemon

В KEXT я прослушиваю закрытие файла через прослушиватель vnode или файловой области. Для определенных (очень немногих) файлов мне нужно отправить путь к моему системному демону, который выполняет некоторую обработку (это должно происходить в демоне) и возвращает результат обратно в KEXT. Вызов закрытия файла должен быть заблокирован, пока я не получу ответ от демона. В зависимости от результата мне нужно выполнить некоторую операцию в закрытом вызове и успешно вернуть закрытый вызов. На форуме много дискуссий по теме, связанной с коммуникацией KEXT. Но они не являются окончательными и выглядят очень старыми (приблизительно 2002 года). Это требование может быть выполнено с помощью FtlSendMessage(...) Win32 API. Я ищу эквивалент этого на Mac

Вот что я посмотрел и хочу обобщить свое понимание:

  1. Машинное сообщение: обеспечивает очень хороший способ двунаправленной связи с использованием портов отправителя и ответа с механизмом очередей. Однако API-интерфейсы сообщений Mach (например, mach_msg, mach_port_allocate, bootstrap_look_up) не являются ключевыми показателями эффективности. Mach API mach_msg_send_from_kernel можно использовать, но само по себе это не поможет в двунаправленной связи. Правильно ли я понимаю?
  2. IOUserClient: похоже, это больше связано с общением из пользовательского пространства с KEXT, а затем с некоторыми обратными вызовами из KEXT. Я не нашел способа инициировать связь KEXT с демоном, а затем дождаться результата от демона. Я что-то упускаю?
  3. Сокеты: это может быть последний вариант, поскольку мне придется реализовать весь двунаправленный канал связи от KEXT до Daemon.
  4. ioctl/sysctl: Я мало о них знаю. Из того, что я прочитал, это не рекомендуемый вариант, особенно для двунаправленной связи.
  5. RPC-Mig: Опять же, я мало о них знаю. Выглядит сложным из того, что я видел. Не уверен, что это рекомендуемый способ.
  6. KUNCUserNotification: похоже, это просто уведомление пользователя от KEXT. Это не соответствует моему требованию.

Поддерживаемая платформа (10.5 и далее). Итак, глядя на требование, может ли кто-нибудь предложить и дать несколько советов по этой теме?

Заранее спасибо.


person RHK    schedule 25.04.2012    source источник
comment
Вы нашли пример того, как реализовать это с помощью сокетов?   -  person gbdavid    schedule 05.02.2016


Ответы (3)


Шаблон, который я использовал для этого процесса, состоит в том, чтобы процесс пользовательского пространства инициировал сокетное соединение с KEXT; KEXT создает новый поток для обработки сообщений через этот сокет и приостанавливает поток. Когда KEXT обнаруживает событие, на которое ему нужно отреагировать, он пробуждает поток сообщений и использует существующий сокет для отправки данных демону. При получении ответа управление возвращается запрашивающему потоку, чтобы решить, следует ли наложить вето на операцию.

Я не знаю ни одного ресурса, который полностью описывает этот шаблон, но соответствующие ключевые показатели эффективности обсуждаются в внутренних компонентах Mac OS X (который кажется старым, но KPI не сильно изменились с момента его написания) и Программирование ядра OS X и iOS (в котором я был техническим обозревателем).

person Community    schedule 25.04.2012
comment
Спасибо, Грэм, за ваш вклад. Я рассмотрю использование опции сокета ядра для связи между KEXT и Daemon. Еще раз спасибо. - person RHK; 03.05.2012
comment
Как вам удалось получить соединение сокета с Kext? Насколько я знаю, вам нужно использовать bootstrap.h, которого нет в ядре. Из-за необходимости mach_port_allocate и bootstrap_register. - person unixb0y; 26.06.2020

Что бы это ни стоило, autofs использует то, что, как я предполагаю, вы подразумеваете под " RPC-Mig", так что это не слишком сложно (MIG используется для описания вызовов RPC, а генерируемый им код-заглушка обрабатывает вызов соответствующего кода отправки и получения сообщений Mach; существуют специальные параметры для генерации режима ядра. заглушки).

Однако ему не нужно выполнять какие-либо поиски, поскольку automountd (демон пользовательского режима, которому autofs kext отправляет сообщения) имеет назначенный ему «специальный порт хоста». Выполнение поиска для поиска произвольного сервиса будет сложнее.

person Community    schedule 28.02.2013

Если вы хотите использовать сокет, установленный с помощью ctl_register() на стороне KExt, будьте осторожны: связь из kext в пространство пользователя (через ctl_enqueuedata()) работает нормально. Однако противоположное направление содержит ошибки на 10.5.x и 10.6.x.

Примерно после 70 000 или 80 000 вызовов send() с SOCK_DGRAM в домене PF_SYSTEM полный сетевой стек ломается с катастрофическими последствиями для всей системы (единственный выход - резкое отключение). Это было исправлено в 10.7.0. Я обходной путь, используя setsockopt() в нашем проекте для направления из пользовательского пространства в kext, поскольку мы отправляем только очень маленькие данные (просто чтобы разрешить/запретить какую-то операцию).

person mity    schedule 24.05.2012