Changes between Version 5 and Version 6 of Howto/UdevCreateDeviceMatchingRules


Ignore:
Timestamp:
22/07/11 21:05:45 (6 years ago)
Author:
tj
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Howto/UdevCreateDeviceMatchingRules

    v5 v6  
    2222dpkg-query -L udev | grep rules 
    2323}}} 
    24  
    25 This will reveal that there are rules in:  
     24This will reveal that there are rules in: 
    2625 
    2726{{{ 
     
    2928/etc/udev/rules.d/ 
    3029}}} 
    31  
    3230The first is the system-wide rules set provided by the distribution - in this case Ubuntu. The second is the local system's user-created rules. /etc/udev/rules.d/ is where you should install any rules of your own. 
    3331 
     
    4240 * Example B is a serial port 
    4341 
    44  
    4542The WH-1081 might be connected at any time whereas a serial port is likely a fixed part of the system that is always there. udev handles them both the same way; what is different is when it processes the rules. 
    4643 
    4744== Removable devices == 
    48 For removable devices (such as USB) ensure the device is disconnected then monitor the kernel log whilst connecting the device:  
     45For removable devices (such as USB) ensure the device is disconnected then monitor the kernel log whilst connecting the device: 
     46 
    4947{{{ 
    5048 tail -f -n 0 /var/log/kern.log  
    5149}}} 
    52 Now connect the device and you'll see some reports as it is recognised by kernel modules  
     50Now connect the device and you'll see some reports as it is recognised by kernel modules 
     51 
    5352{{{ 
    5453 Apr 16 13:05:09 hephaestion kernel: [102070.249075] usb 3-1: new low speed USB device using uhci_hcd and address 9 
     
    5655 Apr 16 13:05:09 hephaestion kernel: [102070.481257] generic-usb 0003:1941:8021.0010: hiddev96,hidraw8: USB HID v1.00 Device [HID 1941:8021] on usb-0000:00:1d.1-1/input0  
    5756}}} 
    58  Interrupt and stop the tail command by pressing Ctrl+C.  Disconnect the device. Now start the udev administration utility to monitor what udev does, then reconnect the device. There'll be several event reports starting with the most basic device recognition and ending with specifics. I'll only show the first and relevant events here to avoid too much noise:  
     57  Interrupt and stop the tail command by pressing Ctrl+C.  Disconnect the device. Now start the udev administration utility to monitor what udev does, then reconnect the device. There'll be several event reports starting with the most basic device recognition and ending with specifics. I'll only show the first and relevant events here to avoid too much noise: 
    5958{{{ 
    6059 udevadm monitor --environment 
     
    7978MINOR=265  
    8079}}} 
    81  ... and this event is significant for us since it declares the DEVNAME which is what the WeatherDisplay application will need to use:  
     80  ... and this event is significant for us since it declares the DEVNAME which is what the WeatherDisplay  application will need to use: 
    8281{{{ 
    8382UDEV  [1239883836.954289] add 
     
    9392DEVLINKS=/dev/char/180:96  
    9493}}} 
     94 
    9595Interrupt and stop udevadm by pressing Ctrl+C. 
    9696 
     
    103103 
    104104=== Examining Removable Devices === 
    105 Give the following shell-script the clue  
     105Give the following shell-script the clue 
     106 
    106107{{{ 
    107108 CLUE=hiddev0 for DEVICE in $(find /sys ! -type l -iname "*${CLUE}*"); do ls -dl $DEVICE; udevadm info -a -p $DEVICE; done  
    108109}}} 
    109  In this case the script does find some relevant information. If your particular clue didn't reveal the device you'll need to alter the clue and explore some more - it is very much down to using your brain to determine what is relevant to the device you are matching. 
    110  
    111 This is the output for the WH-1081:  
     110  In this case the script does find some relevant information. If your particular clue didn't reveal the device you'll need to alter the clue and explore some more - it is very much down to using your brain to determine what is relevant to the device you are matching. 
     111 
     112This is the output for the WH-1081: 
     113 
    112114{{{ 
    113115 drwxr-xr-x 3 root root 0 2009-04-16 13:10 /sys/devices/pci0000:00/0000:00:1d.1/usb3/3-1/3-1:1.0/usb/hiddev0  
    114116}}} 
    115  Udevadm info starts with the device specified by the devpath and then walks up the chain of parent devices. It prints for every device found, all possible attributes in the udev rules key format. 
    116  
    117 A rule to match can be composed by the attributes of the device and the attributes from one single parent device.  
     117  Udevadm info starts with the device specified by the devpath and then walks up the chain of parent devices. It prints for every device found, all possible attributes in the udev rules key format. 
     118 
     119A rule to match can be composed by the attributes of the device and the attributes from one single parent device. 
     120 
    118121{{{ 
    119122Udevadm info starts with the device specified by the devpath and then walks up the chain of parent devices. It prints for every device found, all possible attributes in the udev rules key format. A rule to match, can be composed by the attributes of the device and the attributes from one single parent device. 
     
    213216    DRIVERS=="" 
    214217}}} 
    215  All of these name-value pairs can be used in a udev rule to help target the device. Some will be more specific than others. For example, matching just on SUBSYSTEM=="usb" would not be helpful since that will be matching all USB devices. However, matching against the device's unique Vendor:Product ID would be extremely specific (ATTRS{idVendor}=="1941" and ATTRS{idProduct}=="8021"). 
     218  All of these name-value pairs can be used in a udev rule to help target the device. Some will be more specific than others. For example, matching just on SUBSYSTEM=="usb" would not be helpful since that will be matching all USB devices. However, matching against the device's unique Vendor:Product ID would be extremely specific (ATTRS{idVendor}=="1941" and ATTRS{idProduct}=="8021"). 
    216219 
    217220=== Examining Static Devices === 
    218 Give the following shell-script the clue  
     221Give the following shell-script the clue 
     222 
    219223{{{ 
    220224 CLUE=ttyS0 for DEVICE in $(find /sys ! -type l -iname "*${CLUE}*"); do ls -dl $DEVICE; udevadm info -a -p $DEVICE; done  
    221225}}} 
    222  This is the output on a laptop that has a serial device but no physical port to connect to (in other words, your output might differ significantly from this).  
     226  This is the output on a laptop that has a serial device but no physical port to connect to (in other words, your output might differ significantly from this). 
    223227{{{ 
    224228 drwxr-xr-x 3 root root 0 2009-04-16 12:27 /sys/devices/platform/serial8250/tty/ttyS0  
     
    244248}}} 
    245249 
    246  
    247250== Device Permissions == 
    248 Now we need to decide on what a matching udev rule should do. In general you should leave the specific system-set device permissions as they are since they have been determined to be the best combination over-all. When a non-privileged user account needs access to a privileged device the best way to do it is by assigning a different group as owner, so for example instead of:  
     251Now we need to decide on what a matching udev rule should do. In general you should leave the specific system-set device permissions as they are since they have been determined to be the best combination over-all. When a non-privileged user account needs access to a privileged device the best way to do it is by assigning a different group as owner, so for example instead of: 
     252 
    249253{{{ 
    250254 ls -l /dev/usb/hiddev0 crw-rw---- 1 root root 180, 96 2009-04-16 13:10 /dev/usb/hiddev0  
    251255}}} 
    252  Where "root root" shows the user and group that own this device you would want something like this:  
     256  Where "root root" shows the user and group that own this device you would want something like this: 
    253257{{{ 
    254258 crw-rw---- 1 root weather 180, 96 2009-04-16 13:12 /dev/usb/hiddev0  
    255259}}} 
    256  The permissions on the left of the output ("crw-rw----") can be read as:  
     260  The permissions on the left of the output ("crw-rw----") can be read as: 
    257261{{{ 
    258262 
     
    263267}}} 
    264268 
    265  
    266269== Udev Rules == 
    267 We now have all the ingredients to create a udev rule. I'll show the rule and then explain it. For the removable WH-1081 device:  
    268 {{{ 
    269  # WH-1081 Weather Station ACTION!="add|change", GOTO="weather_station_end" SUBSYSTEM=="usb", ATTRS{idVendor}=="1941", ATTRS{idProduct}=="8021", GROUP="weather" 
     270We now have all the ingredients to create a udev rule. I'll show the rule and then explain it. For the removable WH-1081 device: 
     271 
     272{{{ 
     273# WH-1081 Weather Station 
     274ACTION!="add|change", GOTO="weather_station_end" 
     275SUBSYSTEM=="usb", ATTRS{idVendor}=="1941", ATTRS{idProduct}=="8021", GROUP="weather" 
    270276 
    271277LABEL="weather_station_end"  
    272 }}} 
    273  The first line is a comment (preceeded by #) 
     278 
     279}}} 
     280The first line is a comment (preceeded by #) 
    274281 
    275282"ACTION!=" means if the current udev action isn't add or change, go to the end of the file - in other words, don't try to use these matching rules 
     
    279286The last line is the target label for the earlier GOTO. 
    280287 
    281 For the serial device something like this might be sufficient:  
    282 {{{ 
    283  # Serial-port Weather Station ACTION!="add|change", GOTO="weather_station_end" SUBSYSTEM=="tty", KERNEL=="ttyS0", GROUP="weather" 
     288For the serial device something like this might be sufficient: 
     289 
     290{{{ 
     291# Serial-port Weather Station 
     292ACTION!="add|change", GOTO="weather_station_end" 
     293 
     294SUBSYSTEM=="tty", KERNEL=="ttyS0", GROUP="weather" 
    284295 
    285296LABEL="weather_station_end"  
    286 }}} 
    287  This file is saved to the local udev rules location, usually /etc/udev/rules.d/. I've named it "38-weather-station.rules".  It is perfectly acceptable to have multiple rules in a single file provided you ensure that any GOTOs don't cause one set of rules to be ignored. 
     297 
     298}}} 
     299This file is saved to the local udev rules location, usually /etc/udev/rules.d/. I've named it "38-weather-station.rules".  It is perfectly acceptable to have multiple rules in a single file provided you ensure that any GOTOs don't cause one set of rules to be ignored. 
    288300 
    289301=== Writing to Privileged Locations === 
     
    295307 
    296308== User Group == 
    297 Before testing the rule create the group being assigned if it doesn't already exist, then add the required user(s) to that group: Code: 
    298  
    299 sudo addgroup --system weather Adding group `weather' (GID 127) ... Done. 
    300  
    301 sudo adduser tj weather Adding user `tj' to group `weather' ... Adding user tj to group weather Done. 
    302  
    303 '''Note:'''  addgroup and adduser are Debian-specific commands that simplify the standard useradd and groupadd commands. Additionally, adduser is used in place of usermod for changing an account. On distributions not based on Debian you'll need to figure out and use different commands and options. In particular, do not accidentally remove existing group memberships with the moduser command - make sure to use the append form:  
    304 {{{ 
    305  sudo moduser --append --groups weather tj # equivalent to moduser -aG weather tj  
    306 }}} 
    307  
    308  
    309 If the user is currently logged-in they will need to log-out then log-in before the new group membership will take effect.  
    310 {{{ 
    311  groups 
     309Before testing the rule create the group being assigned if it doesn't already exist, then add the required user(s) to that group: 
     310 
     311{{{ 
     312sudo addgroup --system weather 
     313Adding group `weather' (GID 127) ... Done. 
     314 
     315sudo adduser tj weather 
     316Adding user `tj' to group `weather' ... 
     317Adding user tj to group weather Done. 
     318}}} 
     319'''Note:'''  addgroup and adduser are Debian-specific commands that simplify the standard useradd and groupadd commands. Additionally, adduser is used in place of usermod for changing an account. On distributions not based on Debian you'll need to figure out and use different commands and options. In particular, do not accidentally remove existing group memberships with the moduser command - make sure to use the append form: 
     320{{{ 
     321sudo moduser --append --groups weather tj  
     322# equivalent to moduser -aG weather tj  
     323}}} 
     324If the user is currently logged-in they will need to log-out then log-in before the new group membership will take effect. 
     325 
     326{{{ 
     327groups 
    312328 
    313329tj adm dialout cdrom video plugdev staff users lpadmin admin sambashare weather vm  
    314330}}} 
    315  
    316  
    317331== Testing Udev Rules == 
    318 With everything now ready all that is needed is to disconnect and reconnect the device. For static devices (like serial ports) it means either restarting the PC, or more easily, restarting the udev daemon so it applies the new rules:  
    319 {{{ 
    320  sudo /etc/init.d/udev restart  
    321 }}} 
    322  
    323  
     332With everything now ready all that is needed is to disconnect and reconnect the device. For static devices (like serial ports) it means either restarting the PC, or more easily, restarting the udev daemon so it applies the new rules: 
     333 
     334{{{ 
     335sudo /etc/init.d/udev restart  
     336}}} 
    324337Now start the application from the user account added to the "weather" group and check it can correctly access the device. 
    325338