Интересное

Сообщение об ошибке

Warning: ini_set(): A session is active. You cannot change the session module's ini settings at this time in drupal_environment_initialize() (line 684 of /home/www/nixtalk.com/includes/bootstrap.inc).

Пишем правила udev

Опубликовано пт, 02/20/2015 - 02:14 пользователем Demontager

udevrules
Udev позволяет динамически изменять свойства подключаемых или отключаемых устройств на лету. Параметры устройств udev берет с ядра и на их основе сверяет список правил.
Сами правила хранятся в текстовых файлах по этому пути:

  1. /etc/udev/rules.d/

к примеру на свежеустановленной Ubuntu в этой директории уже содержится файлик 70-persistent-network.rules. Цифры в начале имени файла показывают в какой последовательности будут применятся правила при запуске системы, меньшие цифры имеют больший приоритет, т.е. файл с именем 10-name.rules применится раньше чем 20-name.rules
Окончание .rules обязательно. покажу что у меня в нем:

  1. # This file was automatically generated by the /lib/udev/write_net_rules
  2. # program, run by the persistent-net-generator.rules rules file.
  3. #
  4. # You can modify it, as long as you keep each rule on a single
  5. # line, and change only the value of the NAME= key.
  6.  
  7. # PCI device 0x8086:0x088e (iwlwifi)
  8. SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="c4:85:08:42:17:83", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="wlan*", NAME="wlan0"
  9.  
  10. # USB device 0x:0x (rtl8187)
  11. SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:c0:ca:54:c1:1f", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="wlan*", NAME="wlan1"
  12.  
  13. # USB device 0x:0x (rtl8192cu)
  14. SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="80:1f:02:11:fd:86", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="wlan*", NAME="wlan2"
  15.  
  16. # USB device 0x:0x (asix)
  17. SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="9c:eb:e8:0b:98:ee", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"
  18.  
  19. # USB device 0x:0x (rtl8187)
  20. SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:c0:ca:23:6f:cd", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="wlan*", NAME="wlan3"

В данном случае здесь у меня находятся правила только для сетевых устройств, могут быть и любые другие, это не столь важно. Видно что для каждого устройства задаются его уникальные характеристики, но тут главным критерием срабатывания правил является MAC адресс устройства, за это отвечает аттрибут ATTR{address}==
как только ядро видит подключенное устройство, а это действие указывается как ACTION=="add" и совпадает MAC, происходит присвоение устройству имени сетевого интерфейса - wlan0,wlan1 и т.д. Таким образом каждое устройство имеет свое постоянное имя интерфейса и оно не меняется после перезагрузки.
Файл 70-persistent-network.rules в Ubuntu/Debian системах создается автоматически и правила туда пишуться тоже, но я заметил что на Raspberry Pi с установленной Debian wheezy этих правил нет, поэтому делал их вручную.

Теперь самое главное, как и откуда брать все эти аттрибуты и свойства устройств ? Для этого была придумана утилита udevadm, наиболее важная команда которая нам нужна это:

  1. udevadm info -a -p $(udevadm info -q path -n /dev/devicepath)

где вместо /dev/devicepath необходимо подставить требуемое устройство, к примеру для моей вебкамеры Webcam C170, которая вставлена в USB, вывод команды будет следующий:

  1. dem@dem-UX32VD:~$ udevadm info -a -p $(udevadm info -q path -n /dev/video0)
  2.  
  3. Udevadm info starts with the device specified by the devpath and then
  4. walks up the chain of parent devices. It prints for every device
  5. found, all possible attributes in the udev rules key format.
  6. A rule to match, can be composed by the attributes of the device
  7. and the attributes from one single parent device.
  8.  
  9. looking at device '/devices/pci0000:00/0000:00:1d.7/usb1/1-6/1-6.4/1-6.4.1/1-6.4.1:1.0/video4linux/video0':
  10. KERNEL=="video0"
  11. SUBSYSTEM=="video4linux"
  12. DRIVER==""
  13. ATTR{name}=="Webcam C170"
  14. ATTR{debug}=="0"
  15. ATTR{index}=="0"
  16.  
  17. looking at parent device '/devices/pci0000:00/0000:00:1d.7/usb1/1-6/1-6.4/1-6.4.1/1-6.4.1:1.0':
  18. KERNELS=="1-6.4.1:1.0"
  19. SUBSYSTEMS=="usb"
  20. DRIVERS=="uvcvideo"
  21. ATTRS{bInterfaceClass}=="0e"
  22. ATTRS{iad_bFunctionClass}=="0e"
  23. ATTRS{iad_bFirstInterface}=="00"
  24. ATTRS{bInterfaceSubClass}=="01"
  25. ATTRS{bInterfaceProtocol}=="00"
  26. ATTRS{bNumEndpoints}=="01"
  27. ATTRS{iad_bFunctionSubClass}=="03"
  28. ATTRS{iad_bFunctionProtocol}=="00"
  29. ATTRS{supports_autosuspend}=="1"
  30. ATTRS{iad_bInterfaceCount}=="02"
  31. ATTRS{bAlternateSetting}==" 0"
  32. ATTRS{bInterfaceNumber}=="00"
  33. ATTRS{interface}=="Webcam C170"
  34.  
  35. looking at parent device '/devices/pci0000:00/0000:00:1d.7/usb1/1-6/1-6.4/1-6.4.1':
  36. KERNELS=="1-6.4.1"
  37. SUBSYSTEMS=="usb"
  38. DRIVERS=="usb"
  39. ATTRS{bDeviceSubClass}=="02"
  40. ATTRS{bDeviceProtocol}=="01"
  41. ATTRS{devpath}=="6.4.1"
  42. ATTRS{idVendor}=="046d"
  43. ATTRS{speed}=="480"
  44. ATTRS{bNumInterfaces}==" 4"
  45. ATTRS{bConfigurationValue}=="1"
  46. ATTRS{bMaxPacketSize0}=="64"
  47. ATTRS{busnum}=="1"
  48. ATTRS{devnum}=="6"
  49. ATTRS{configuration}==""
  50. ATTRS{bMaxPower}=="500mA"
  51. ATTRS{authorized}=="1"
  52. ATTRS{bmAttributes}=="80"
  53. ATTRS{bNumConfigurations}=="1"
  54. ATTRS{maxchild}=="0"
  55. ATTRS{bcdDevice}=="28c5"
  56. ATTRS{avoid_reset_quirk}=="0"
  57. ATTRS{quirks}=="0x2"
  58. ATTRS{version}==" 2.00"
  59. ATTRS{urbnum}=="1027532"
  60. ATTRS{ltm_capable}=="no"
  61. ATTRS{manufacturer}==" "
  62. ATTRS{removable}=="unknown"
  63. ATTRS{idProduct}=="082b"
  64. ATTRS{bDeviceClass}=="ef"
  65. ATTRS{product}=="Webcam C170"
  66.  
  67. looking at parent device '/devices/pci0000:00/0000:00:1d.7/usb1/1-6/1-6.4':
  68. KERNELS=="1-6.4"
  69. SUBSYSTEMS=="usb"
  70. DRIVERS=="usb"
  71. ATTRS{bDeviceSubClass}=="00"
  72. ATTRS{bDeviceProtocol}=="01"
  73. ATTRS{devpath}=="6.4"
  74. ATTRS{idVendor}=="05e3"
  75. ATTRS{speed}=="480"
  76. ATTRS{bNumInterfaces}==" 1"
  77. ATTRS{bConfigurationValue}=="1"
  78. ATTRS{bMaxPacketSize0}=="64"
  79. ATTRS{busnum}=="1"
  80. ATTRS{devnum}=="5"
  81. ATTRS{configuration}==""
  82. ATTRS{bMaxPower}=="100mA"
  83. ATTRS{authorized}=="1"
  84. ATTRS{bmAttributes}=="e0"
  85. ATTRS{bNumConfigurations}=="1"
  86. ATTRS{maxchild}=="4"
  87. ATTRS{bcdDevice}=="0901"
  88. ATTRS{avoid_reset_quirk}=="0"
  89. ATTRS{quirks}=="0x0"
  90. ATTRS{version}==" 2.00"
  91. ATTRS{urbnum}=="41"
  92. ATTRS{ltm_capable}=="no"
  93. ATTRS{removable}=="unknown"
  94. ATTRS{idProduct}=="0608"
  95. ATTRS{bDeviceClass}=="09"
  96. ATTRS{product}=="USB2.0 Hub"
  97.  
  98. looking at parent device '/devices/pci0000:00/0000:00:1d.7/usb1/1-6':
  99. KERNELS=="1-6"
  100. SUBSYSTEMS=="usb"
  101. DRIVERS=="usb"
  102. ATTRS{bDeviceSubClass}=="00"
  103. ATTRS{bDeviceProtocol}=="02"
  104. ATTRS{devpath}=="6"
  105. ATTRS{idVendor}=="1a40"
  106. ATTRS{speed}=="480"
  107. ATTRS{bNumInterfaces}==" 1"
  108. ATTRS{bConfigurationValue}=="1"
  109. ATTRS{bMaxPacketSize0}=="64"
  110. ATTRS{busnum}=="1"
  111. ATTRS{devnum}=="4"
  112. ATTRS{configuration}==""
  113. ATTRS{bMaxPower}=="100mA"
  114. ATTRS{authorized}=="1"
  115. ATTRS{bmAttributes}=="e0"
  116. ATTRS{bNumConfigurations}=="1"
  117. ATTRS{maxchild}=="4"
  118. ATTRS{bcdDevice}=="0100"
  119. ATTRS{avoid_reset_quirk}=="0"
  120. ATTRS{quirks}=="0x0"
  121. ATTRS{version}==" 2.00"
  122. ATTRS{urbnum}=="30"
  123. ATTRS{ltm_capable}=="no"
  124. ATTRS{removable}=="unknown"
  125. ATTRS{idProduct}=="0101"
  126. ATTRS{bDeviceClass}=="09"
  127. ATTRS{product}=="USB 2.0 Hub [MTT]"
  128.  
  129. looking at parent device '/devices/pci0000:00/0000:00:1d.7/usb1':
  130. KERNELS=="usb1"
  131. SUBSYSTEMS=="usb"
  132. DRIVERS=="usb"
  133. ATTRS{bDeviceSubClass}=="00"
  134. ATTRS{bDeviceProtocol}=="00"
  135. ATTRS{devpath}=="0"
  136. ATTRS{idVendor}=="1d6b"
  137. ATTRS{speed}=="480"
  138. ATTRS{bNumInterfaces}==" 1"
  139. ATTRS{bConfigurationValue}=="1"
  140. ATTRS{bMaxPacketSize0}=="64"
  141. ATTRS{authorized_default}=="1"
  142. ATTRS{busnum}=="1"
  143. ATTRS{devnum}=="1"
  144. ATTRS{configuration}==""
  145. ATTRS{bMaxPower}=="0mA"
  146. ATTRS{authorized}=="1"
  147. ATTRS{bmAttributes}=="e0"
  148. ATTRS{bNumConfigurations}=="1"
  149. ATTRS{maxchild}=="6"
  150. ATTRS{bcdDevice}=="0311"
  151. ATTRS{avoid_reset_quirk}=="0"
  152. ATTRS{quirks}=="0x0"
  153. ATTRS{serial}=="0000:00:1d.7"
  154. ATTRS{version}==" 2.00"
  155. ATTRS{urbnum}=="48"
  156. ATTRS{ltm_capable}=="no"
  157. ATTRS{manufacturer}=="Linux 3.11.0-12-generic ehci_hcd"
  158. ATTRS{removable}=="unknown"
  159. ATTRS{idProduct}=="0002"
  160. ATTRS{bDeviceClass}=="09"
  161. ATTRS{product}=="EHCI Host Controller"
  162.  
  163. looking at parent device '/devices/pci0000:00/0000:00:1d.7':
  164. KERNELS=="0000:00:1d.7"
  165. SUBSYSTEMS=="pci"
  166. DRIVERS=="ehci-pci"
  167. ATTRS{irq}=="23"
  168. ATTRS{subsystem_vendor}=="0x1462"
  169. ATTRS{broken_parity_status}=="0"
  170. ATTRS{class}=="0x0c0320"
  171. ATTRS{companion}==""
  172. ATTRS{consistent_dma_mask_bits}=="32"
  173. ATTRS{dma_mask_bits}=="32"
  174. ATTRS{local_cpus}=="ff"
  175. ATTRS{device}=="0x265c"
  176. ATTRS{uframe_periodic_max}=="100"
  177. ATTRS{msi_bus}==""
  178. ATTRS{local_cpulist}=="0-7"
  179. ATTRS{vendor}=="0x8086"
  180. ATTRS{subsystem_device}=="0x0161"
  181. ATTRS{d3cold_allowed}=="1"
  182.  
  183. looking at parent device '/devices/pci0000:00':
  184. KERNELS=="pci0000:00"
  185. SUBSYSTEMS==""
  186. DRIVERS==""

Здесь находятся все аттрибуты и свойства, которые имеет устройство, часть из них может быть использована для написания правил, желательно выбирать аттрибуты с одной секции, каждая секция начинается с "looking at parent device"
Для написания правил для камеры я использовал уникальные аттрибуты idVendor, и idProduct, но следует быть внимательным, если планируется использовать два абсолютно одинаковых устройства, тогда нужно использовать еще дополнительные аттрибуты.
Разберем сами правила, всего их два для этой камеры

  1. $ cat /etc/udev/rules.d/10-camera.rules
  2. ATTRS{idVendor}=="046d", ATTRS{idProduct}=="082b", ACTION=="add", RUN+="/root/cam.sh"
  3. ATTRS{idVendor}=="046d", ATTRS{idProduct}=="082b", ACTION=="remove", RUN+="/usr/bin/pkill ffserver"

Про аттрибуты уже написал выше, плюс добвил действие при котором применять правило -ACTION=="add" соответсвенно когда устройство вставлено и ACTION=="remove" удалено. В конце указана команда, которую необходимо выполнить, а это RUN+="/root/cam.sh" скрипт для запуска ffmpeg+ffserver,
во втором правиле, когда устройство извлечено посылается команда на закрытие ffserver RUN+="/usr/bin/pkill ffserver"

Можно много чего сделать с устройствами на лету, приведу только несколько примеров взятых с просторов интернета:
1. Задаем симлинк для принтера, который определяется незвучным именем /dev/lp0

  1. SUBSYSTEM=="usb", ATTRS{serial}=="L72010011070626380", SYMLINK+="epson_680"

2. Делаем симлинк dvd для /dev/dvd и присваем ему разрешения группы cdrom

  1. SUBSYSTEM=="block", KERNEL=="hdc", SYMLINK+="dvd", GROUP="cdrom"

3. Отключаем usb шину полностью, устройства игнорируются

  1. BUS=="usb", OPTIONS+="ignore_device"

4. Отключаем все блоковые устройства, флешки, внешние usb диски

  1. BUS=="usb", SUBSYSTEM=="block", OPTIONS+="ignore_device"

5. Назначаем имя sdb винтчестеру

  1. KERNEL=="sdb", NAME="MY_DISK"

6. Назначаем устройству права 0666 и переносим его в групу users

  1. # USBtinyISP Programmer rules
  2. SUBSYSTEMS=="usb", ATTRS{idVendor}=="1781", ATTRS{idProduct}=="0c9f", GROUP="users", MODE="0666"

7. Меняем специфические свойства устройства

  1. ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c52b", ATTR{power/wakeup}="enabled", ATTR{driver/usb7/power/wakeup}="enabled"

Чтобы мониторить подключаемые/отключаемые устройства, можно использовать dmesg, но лучше всего

  1. # udevadm monitor

Для того чтобы перезагрузить правила udev, необходимо выполнить:

  1. # udevadm control --reload

Для форсирования срабатывания правил используется команда:

  1. # udevadm trigger

Список аттрибутов, вместо devicepath подставить свое устройство:

  1. udevadm info -a -n /dev/devicepath

Для отладки хорошо работает такая команда:

  1. udevadm monitor --environment --udev

Мануалы по теме:
https://wiki.archlinux.org/index.php/udev
http://www.reactivated.net/writing_udev_rules.html
http://archive.atomicmpc.com.au/forums.asp?s=2&c=16&t=4775

category_index: 
Поделится: 

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