There are two file systems that relate to devices:
/sys/
describe a device./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.
After adding/changing rules you can reload the rules using:
>sudo udevadm control --reload
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.
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
.