Page History

udev

Mark George edited this page on 18 Jul 2019

Clone this wiki locally

Basics

There are two file systems that relate to devices:

  • Files in /sys/ describe a device.
  • Files in /dev/ are the actual device nodes.

Finding the paths for a device:

# device not yet plugged in

>udevadm monitor --property

# plug in device

KERNEL[866554.157695] add      /devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.6 (usb)
ACTION=add
DEVPATH=/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.6
SUBSYSTEM=usb
DEVNAME=/dev/bus/usb/001/007
DEVTYPE=usb_device
PRODUCT=2a70/4ee7/404
TYPE=0/0/0
BUSNUM=001
DEVNUM=007
SEQNUM=3207
MAJOR=189
MINOR=6

The DEVNAME property has the /dev path for the actual device node.

The DEVPATH property has the location in the /sys filesystem.

You can view all of the properties for a device using either:

udevadm info --attribute-walk --path <DEVPATH>

or

udevadm info --attribute-walk --name <DEVNAME>

So:

>udevadm info --attribute-walk --name /dev/bus/usb/001/007

or 

>udevadm info --attribute-walk --path /devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.6

  looking at device '/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.6':
    KERNEL=="1-1.6"
    SUBSYSTEM=="usb"
    DRIVER=="usb"
    ATTR{devpath}=="1.6"
    ATTR{removable}=="removable"
    ATTR{bmAttributes}=="c0"
    ATTR{maxchild}=="0"
    ATTR{bDeviceProtocol}=="00"
    ATTR{idProduct}=="4ee7"
    ATTR{bDeviceClass}=="00"
    ATTR{bMaxPacketSize0}=="64"
    ATTR{bNumConfigurations}=="1"
    ATTR{bNumInterfaces}==" 1"
    ATTR{quirks}=="0x0"
    ATTR{bMaxPower}=="0mA"
    ATTR{configuration}=="adb"
    ATTR{avoid_reset_quirk}=="0"
    ATTR{product}=="OnePlus"
    ATTR{urbnum}=="12"
    ATTR{bcdDevice}=="0404"
    ATTR{serial}=="4e23f21f"
    ATTR{tx_lanes}=="1"
    ATTR{rx_lanes}=="1"
    ATTR{idVendor}=="2a70"
    ATTR{devnum}=="7"
    ATTR{manufacturer}=="OnePlus"
    ATTR{authorized}=="1"
    ATTR{bDeviceSubClass}=="00"
    ATTR{bConfigurationValue}=="1"
    ATTR{devspec}=="          (null)"
    ATTR{ltm_capable}=="no"
    ATTR{busnum}=="1"
    ATTR{version}==" 2.00"
    ATTR{speed}=="480"

For creating UDEV rules, the SUBSYSTEM, ATTR{idVendor} and ATTR{idProduct} attributes are the most useful.

Reloading UDEV rules

After adding/changing rules you can reload the rules using:

>sudo udevadm control --reload

Groups vs uaccess

Systemd added an on-demand ACL feature a while back as a preferred alternative to using groups for managing device permissions. This should be very handy for the Linux lab since we can't easily modify a student's groups since they are assigned by ADS.

The old way was to to have UDEV rules that looked like:

SUBSYSTEM=="usb", ATTR{idVendor}=="2a70",  ATTR{idProduct}=="4ee7", MODE="0666", GROUP="plugdev"

We would either need to add the user to the plugdev group, or change the rule to use another group.

The new way using uaccess:

SUBSYSTEM=="usb", ATTR{idVendor}=="2a70",  ATTR{idProduct}=="4ee7", MODE="0666", TAG+="uaccess"

You won't see this in effect at the filesystem level:

>ls -lah /dev/bus/usb/001/007

crw-rw-rw-+ 1 root root 189, 6 Jul 18 17:53 /dev/bus/usb/001/007

But, you should see the logged in user in the ACL:

>getfacl  /dev/bus/usb/001/007

getfacl: Removing leading '/' from absolute path names
# file: dev/bus/usb/001/007
# owner: root
# group: root
user::rw-
user:mark:rw-
group::rw-
mask::rw-
other::rw-

The logged in user's username should appear in one of the user attributes which indicates that the user should have access to the /dev device node.

Device Symlinks

Creating /dev/ symlinks is very handy. It gives a way to quickly verify that a device is being picked up and processed by UDEV, and it gives a much nicer device name to use in applications that need it.

The symlinks are created when the device is plugged in and removed when they are unplugged.

Use the SYMLINK key in the UDEV rule:

SUBSYSTEM=="usb", ATTR{idVendor}=="2a70",  ATTR{idProduct}=="4ee7", MODE="0666", SYMLINK+="android%n", TAG+="uaccess"

The %n will use an incrementing counter so that multiple concurrent devices can be used. Sometimes that is annoying --- you always want the path to be the same, so you can drop the %n.