Правила udev, необходимо получить путь типа /dev/sda.

Вопрос или проблема

Я пытаюсь получить путь последнего подключенного диска через переменную окружения, например, путь вида /dev/sd*. Проблема в том, что DEVNAME или DEVPATH не предоставляет нужный путь.

Цель состоит в том, чтобы сделать echo $...... > /var/..... как только значение сохранено, и выполнить различные действия с RUN +=… Я извлекаю его, когда он мне нужен. Надеюсь, я был ясен в своих объяснениях, спасибо

Я пытаюсь получить путь текущего диска, в данном случае /dev/sd*. Я использую правила udev для выполнения действия

SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", RUN+="/bin/device_added.sh" SUBSYSTEM=="usb", ACTION=="remove", ENV{DEVTYPE}=="usb_device", RUN+="/bin/device_removed.sh" 

Проблема в том, что когда я извлекаю с помощью echo $KERNEL > my-file, я не могу найти путь текущего диска. Мне нужна эта переменная, чтобы выполнять команды smartctl с диска, который только что прибыл.

В device_added.sh цель состоит в том, чтобы запустить команду smartctl -a /dev/sd*, за исключением того, что мы заменяем /dev/sd* на последний подключенный диск, поэтому вот моя проблема сейчас, мне нужно восстановить путь последнего подключенного диска/обнаруженного по правилам udev.

Я все еще не уверен, правильно ли я понимаю вопрос.

Вопрос такой: “когда я выполняю программу с RUN внутри правила udev, как я могу получить доступ к фактическому узлу устройства, который создается ядром для этого события”? Если да, то посмотрите на переменную окружения KERNEL (см. man udev), которая содержит фактическое устройство ядра, например, sda, когда вы подключаете или удаляете жесткий диск.

Если это не то, что вам нужно, пожалуйста, объясните зачем вам это нужно, то есть какие действия вы хотите выполнить с /dev/sda с какой целью. Пожалуйста, также прочитайте про вопросы XY.


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

KERNEL=="sd*", SUBSYSTEMS=="usb", ACTION=="add", ...

либо без DEVTYPE, либо с ENV{DEVTYPE}="disk".

Продолжая читать man udev, есть также переменная окружения DEVNODE, которая должна содержать полный путь к новому узлу (я это не проверял).

Наконец, если вы хотите запускать команды smartctl, помните следующее замечание относительно RUN в man udev:

Это может быть использовано только для очень коротко выполняемых задач. Запуск процесса события на длительное время может заблокировать все последующие события для этого или зависимого устройства.

Запуск демонов или других длительных процессов не подходит для udev; форкнутые процессы, отсоединенные или нет, будут безусловно убиты после завершения обработки события.

Таким образом, в зависимости от того, что вы хотите сделать с smartctl, это может быть или не подходящее для udev место.


Я уже пробовал с вашим правилом, оно не работает, диски не распознаются и скрипт не запускается. Я попробовал с KERNEL=="sd[a-z]", не работает.

Тогда что-то в вашем правиле неверно (например, дополнительное условие, которое не выполняется). Если udev добавляет /dev/sd*, правило с KERNEL=="sd[a-z]" будет соответствовать.

Пожалуйста, отредактируйте свой вопрос и добавьте информацию, полученную с помощью udevadm info -p /sys/class/block/sdx после того, как вы подключили диск и он появился как /dev/sdx (замените sdx по мере необходимости). Сравните с правилом, которое вы использовали и которое не сработало.

Ответ или решение

Для решения задачи получения пути последнего подключенного диска с использованием udev правил, рассмотрим теорию, примеры и применение.

Теория

Udev – это системный демон Linux, ответственный за управление устройствами в режиме пользователя. Он предоставляет динамическую поддержку устройств, создавая и удаляя файлы устройств в каталоге /dev/. Для настройки поведения udev используются правила udev, которые применяются при добавлении или удалении устройств.

Каждое правило udev формируется с использованием пары "ключ-значение". Основные ключи включают KERNEL, SUBSYSTEM, ACTION, ENV{}, и т.д. Эти ключи помогают определить, к каким устройствам и при каких действиях будет применяться правило.

Переменные среды, такие как DEVNAME и DEVPATH, часто использующиеся в udev правилах, обычно содержат путь к устройству или дополнительную информацию о нем. Однако, в некоторых случаях эти переменные могут не предоставлять полный путь к устройству, например, /dev/sda.

Пример

Рассмотрим пример udev правила, которое может использоваться для создания shell-скрипта, обрабатывающего добавление диска:

SUBSYSTEM=="block", KERNEL=="sd[a-z]", ACTION=="add", ENV{ID_BUS}=="usb", RUN+="/bin/device_added.sh $devnode"

В этом правиле:

  • SUBSYSTEM=="block" – правило применяется к блоковым устройствам, таким как диски.
  • KERNEL=="sd[a-z]" – условие на совпадение с именем устройства.
  • ACTION=="add" – правило срабатывает при добавлении устройства.
  • ENV{ID_BUS}=="usb" – применяется к устройствам, подключенным через USB.
  • RUN+="/bin/device_added.sh $devnode" – выполняется скрипт device_added.sh с параметром $devnode, представляющим полный путь устройства.

Применение

  1. Использование KERNEL и DEVNAME: Чтобы получить путь к устройству, можно использовать переменные среды с дополнительным акцентом на правильные фильтры в udev правилах. Переменная KERNEL может содержать базовое имя устройства (например, sda), которое можно объединить со стандартным префиксом /dev/ для получения полного пути. Однако, более надежный подход – использовать DEVNAME, которая должна непосредственно содержать полный путь, при условии, что правило написано правильно.

  2. Корректировка udev правила: Если текущее правило не работает, стоит проверить все условия и убедиться, что они правильно описывают целевое устройство. Убедитесь, что действие связано именно с блоковым устройством, а не только с USB интерфейсом.

  3. Утилита udevadm: Для диагностики и понимания доступных свойств устройства можно воспользоваться командой:

    udevadm info -p /sys/class/block/sdx

    Эта команда предоставит полную информацию о заданном устройстве, что поможет скорректировать условия в udev правилах.

  4. Правильное использование RUN: Важно помнить, что секция RUN предназначена для коротких и быстро выполняемых задач. Если требуется более сложная обработка или длительное выполнение (как, например, команда smartctl), рекомендуется создавать отдельные фоновые процессы или ставить задания в очередь через другие сервисы (например, systemd).

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

Оцените материал
Добавить комментарий

Капча загружается...