OSBoy notes.

Записки обо всём...

Настройка Hotplug на OpenWRT

Ранее я уже затрагивал настройку правил udev в статье по настройке принт-сервера для двух принтеров. Но с обновлением OpenWRT до 18 версии, оказалось, что пакета udev в ней уже нет. Видимо, это связано с внедрением в OpenWRT своей собственной системы инициализации и менеджера процессов - Procd, который, так же, заменил и дополнил функционал более старой системы управления устройствами - Hotplug2.

Как это работает

В директории /etc/hotplug.d расположены несколько поддиректорий, таких как: block, iface, net, usb и т.д., со скриптами для обработки событий. Когда срабатывает событие триггера соответствующего типа, Procd выполнит все сценарии в поддиректории этого триггера в алфавитном порядке. Поэтому в именах скриптов обычно используется числовой префикс.

Пишем скрипты для Hotplug

Итак, к примеру, мы имеем те же два принтера, что и в вышеупомянутой статье: Xerox Workcentre 5020 и HP DesignJet 111 Roll.
При подключении принтеров к роутеру, в директории /dev/usb создаются файлы устройств: lp0, lp1, lp2 и т.д., в том порядке, в котором они были подключены. В конфиге нашего принт-сервера (p910nd) мы указываем, с какого порта на какое устройство отправлять данные на печать. Таким образом, если принтер в системе один - проблем не возникает. Но если принтеров - два и более, то нам придётся подключать их строго в определённом порядке, чтобы каждому принтеру каждый раз соответствовало то же самое устройство в системе, а это довольно неудобно.
Чтобы исключить эти неудобства, напишем hotplug-скрипты, которые будут при подключении принтеров создавать символьные ссылки с фиксированными именами для каждого из них. Создаём поддиректорию /etc/hotplug.d/usb (если ещё не создана), и помещаем в неё скрипт, например 22-xerox5020, примерно такого содержания:

XEROX5020_PRODUCT="924/4271/1"
SYMLINK="xerox5020"

if [ "${PRODUCT}" = "${XEROX5020_PRODUCT}" ];
then
   if [ "${ACTION}" = "add" ];
   then
      DEVICE_NAME=$(ls /sys$DEVPATH/usbmisc | grep lp)
      if [ -z ${DEVICE_NAME} ];
      then
         exit
      fi
      logger -t hotplug Device name of XEROX5020 is $DEVICE_NAME
      ln -s /dev/usb/$DEVICE_NAME /dev/${SYMLINK}
      logger -t hotplug Symlink from /dev/usb/$DEVICE_NAME to /dev/${SYMLINK} created
   fi

   if [ "${ACTION}" = "remove" ];
   then
      if [ -L /dev/${SYMLINK} ];
      then
         rm /dev/${SYMLINK}
         logger -t hotplug Symlink /dev/${SYMLINK} removed
      fi
   fi
fi

Здесь переменные:

  • ACTION - тип события: add - подключение, remove - отключение устройства;
  • PRODUCT - идентификатор устройства вида: vendorid/productid/version;
  • SYMLINK - имя символьной ссылки, которая будет создана для устройства;
  • DEVICE_NAME - имя файла устройства в системе (lp0, lp1 и т.д.);
  • DEVPATH - путь к файлам устройства в директории /sys.

Vendorid и productid устройства можно узнать, например, из вывода dmesg:

root@OpenWrt:~# dmesg | grep usb
.....
[74991.411950] usb 1-1.2: new high-speed USB device number 79 using ehci-platform
[74991.569073] usblp 1-1.2:1.1: usblp1: USB Bidirectional printer dev 79 if 1 alt 0 proto 2 vid 0x0924 pid 0x4271
.....

Или с помощью команды lsusb (входит в состав пакета usbutils):

root@OpenWrt:~# lsusb
Bus 001 Device 079: ID 0924:4271 Xerox
Bus 001 Device 003: ID 1058:25a2 Western Digital Technologies, Inc. Elements 25A2
Bus 001 Device 040: ID 03f0:0314 HP, Inc designjet 30/130 series
Bus 001 Device 002: ID 1a40:0101 Terminus Technology Inc. Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

Видим, что для нашего Xerox: vid - 924, pid - 4271; для HP: vid - 3f0, pid - 314.
А чтобы узнать номер версии устройства, можно посмотреть расширенный вывод lsusb с помощью опции -v :

root@OpenWrt:~# lsusb -v -d 0924:4271

Bus 001 Device 079: ID 0924:4271 Xerox
Device Descriptor:
.....
  idVendor           0x0924 Xerox
  idProduct          0x4271
  bcdDevice            0.01
.....
  
root@OpenWrt:~# lsusb -v -d 03f0:0314

Bus 001 Device 040: ID 03f0:0314 HP, Inc designjet 30/130 series
Device Descriptor:
.....
  idVendor           0x03f0 HP, Inc
  idProduct          0x0314 designjet 30/130 series
  bcdDevice            1.00
.....

Аналогичный скрипт напишем и для нашего второго принтера (HP):

HPdj111roll_PRODUCT="3f0/314/100"
SYMLINK="hpdj111roll"

if [ "${PRODUCT}" = "${HPdj111roll_PRODUCT}" ];
then
   if [ "${ACTION}" = "add" ];
   then
      DEVICE_NAME=$(ls /sys$DEVPATH/usbmisc | grep lp)
      if [ -z ${DEVICE_NAME} ];
      then
         exit
      fi
      logger -t hotplug Device name of HP Designjet 111 roll is $DEVICE_NAME
      ln -s /dev/usb/$DEVICE_NAME /dev/${SYMLINK}
      logger -t hotplug Symlink from /dev/usb/$DEVICE_NAME to /dev/${SYMLINK} created
   fi

   if [ "${ACTION}" = "remove" ];
   then
      if [ -L /dev/${SYMLINK} ];
      then
         rm /dev/${SYMLINK}
         logger -t hotplug Symlink /dev/${SYMLINK} removed
      fi
   fi
fi

Созданные скрипты Procd подхватывает на лету - даже не нужно ничего перезапускать. Давайте убедимся, что всё работает, как надо. Откроем системный лог и переподключим наши принтеры:

root@OpenWrt:~# logread -f
kern.info kernel: [82901.484970] usb 1-1.2: USB disconnect, device number 89
kern.info kernel: [82901.490759] usblp0: removed
user.notice hotplug: Symlink /dev/hpdj111roll removed
kern.info kernel: [82903.276970] usb 1-1.3: USB disconnect, device number 90
kern.info kernel: [82903.283082] usblp1: removed
user.notice hotplug: Symlink /dev/xerox5020 removed
kern.info kernel: [82910.481449] usb 1-1.3: new high-speed USB device number 91 using ehci-platform
kern.info kernel: [82910.638964] usblp 1-1.3:1.1: usblp0: USB Bidirectional printer dev 91 if 1 alt 0 proto 2 vid 0x0924 pid 0x4271
user.notice hotplug: Device name of XEROX5020 is lp0
user.notice hotplug: Symlink from /dev/usb/lp0 to /dev/xerox5020 created
kern.info kernel: [82913.551441] usb 1-1.2: new full-speed USB device number 92 using ehci-platform
kern.info kernel: [82913.714898] usblp 1-1.2:1.0: usblp1: USB Bidirectional printer dev 92 if 0 alt 0 proto 2 vid 0x03F0 pid 0x0314
user.notice hotplug: Device name of HP Designjet 111 roll is lp1
user.notice hotplug: Symlink from /dev/usb/lp1 to /dev/hpdj111roll created

Видим, что всё работает, как и задумано. Причём, обратите внимание, что я специально переподключил принтеры в другой последовательности: Xerox - был lp1, стал lp0; HP - наоборот - был lp0, стал lp1. Но симлинки на принтеры сохранились с фиксированными именами, что нам и требовалось. Теперь можем в конфиге принт-сервера указывать пути к принтерам, как: /dev/xerox5020 и /dev/hpdj111roll.

Подробнее о написании hotplug-скриптов можно почитать на странице документации OpenWRT:
OpenWrt Project » Documentation » User guide » Base system » Hotplug

Теги : openwrt, hotplug, procd

Комментариев: 0

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

Отменить