https://wiki.archlinux.org/api.php?action=feedcontributions&user=Spbkaizo&feedformat=atomArchWiki - User contributions [en]2024-03-29T09:50:09ZUser contributionsMediaWiki 1.41.0https://wiki.archlinux.org/index.php?title=Map_Custom_Device_Entries_with_udev&diff=66223Map Custom Device Entries with udev2009-04-04T14:20:16Z<p>Spbkaizo: /* Get the udev info for your USB device */</p>
<hr />
<div>[[Category:Hardware detection and troubleshooting (English)]]<br />
[[Category:HOWTOs (English)]]<br />
<br />
{{i18n_links_start}}<br />
{{i18n_entry|English|Using udev to map multiple entries to a device}}<br />
{{i18n_entry|Español|Utilizando udev para relacionar múltiples entradas a un dispositivo (Español)}}<br />
{{i18n_links_end}}<br />
<br />
This information is basically mirrored from the gentoo wiki with some additional hints. Recently it was updated to reflect changes in udev >= 98 syntax.<br />
<br />
This process allows you to always map a specific device to the same <code>/dev</code> node. This can then be used in <code>fstab</code> to ensure you can always mount the device same device in exactly the same place - which is great for desktop shortcuts!<br />
<br />
<br />
==Get the udev info for your USB device==<br />
<br />
I've written a small script to do this for you. Simply plug in the device you want the entry for, then run the script. I call it "usb-show-serial", and I run it like so:<br />
<br />
root@hobo:/usr/local/sbin/ > ./usb-show-serial /dev/sdb foo<br />
add the following to /etc/udev/rules.d/90-automounter.rules<br />
BUS=="usb", ATTRS{serial}=="23560716050834460007" , KERNEL=="sd?1", NAME="%k", SYMLINK+="foo", GROUP="storage"<br />
<br />
The script is available from here: http://kaizo.org/misc/slackware/current/misc/usb-show-serial<br />
<br />
<br />
<br />
<br />
==Manual Method==<br />
<br />
Make sure one of your target devices is plugged in and then run the following as root:<br />
udevadm info -a -p `udevadm info -q path -n /dev/sda`<br />
<br />
This gets the udev device info for the device on <code>/dev/sda</code> - if your device is not mapped to <code>/dev/sda</code> then obviously use the correct mapping. :)<br />
<br />
You should get some output like this:<br />
<pre><br />
<br />
Udevadm starts with the device specified by the devpath and then<br />
walks up the chain of parent devices. It prints for every device<br />
found, all possible attributes in the udev rules key format.<br />
A rule to match, can be composed by the attributes of the device<br />
and the attributes from one single parent device.<br />
<br />
looking at device '/block/sda':<br />
KERNEL=="sda"<br />
SUBSYSTEM=="block"<br />
DRIVER==""<br />
ATTR{stat}==" 19 111 137 160 0 0 0 0 0 152 160"<br />
ATTR{size}=="2007040"<br />
ATTR{removable}=="1"<br />
ATTR{range}=="16"<br />
ATTR{dev}=="8:0"<br />
<br />
looking at parent device '/devices/pci0000:00/0000:00:02.2/usb1/1-5/1-5:1.0/host5/target5:0:0/5:0:0:0':<br />
KERNELS=="5:0:0:0"<br />
SUBSYSTEMS=="scsi"<br />
DRIVERS=="sd"<br />
ATTRS{ioerr_cnt}=="0x0"<br />
ATTRS{iodone_cnt}=="0x1c"<br />
ATTRS{iorequest_cnt}=="0x1c"<br />
ATTRS{iocounterbits}=="32"<br />
ATTRS{timeout}=="30"<br />
ATTRS{state}=="running"<br />
ATTRS{rev}=="1.20"<br />
ATTRS{model}=="01GB Tiny "<br />
ATTRS{vendor}=="Pretec "<br />
ATTRS{scsi_level}=="3"<br />
ATTRS{type}=="0"<br />
ATTRS{queue_type}=="none"<br />
ATTRS{queue_depth}=="1"<br />
ATTRS{device_blocked}=="0"<br />
ATTRS{max_sectors}=="240"<br />
<br />
looking at parent device '/devices/pci0000:00/0000:00:02.2/usb1/1-5/1-5:1.0/host5/target5:0:0':<br />
KERNELS=="target5:0:0"<br />
SUBSYSTEMS==""<br />
DRIVERS==""<br />
<br />
looking at parent device '/devices/pci0000:00/0000:00:02.2/usb1/1-5/1-5:1.0/host5':<br />
KERNELS=="host5"<br />
SUBSYSTEMS==""<br />
DRIVERS==""<br />
<br />
looking at parent device '/devices/pci0000:00/0000:00:02.2/usb1/1-5/1-5:1.0':<br />
KERNELS=="1-5:1.0"<br />
SUBSYSTEMS=="usb"<br />
DRIVERS=="usb-storage"<br />
ATTRS{modalias}=="usb:v4146pBA01d0100dc00dsc00dp00ic08isc06ip50"<br />
ATTRS{bInterfaceProtocol}=="50"<br />
ATTRS{bInterfaceSubClass}=="06"<br />
ATTRS{bInterfaceClass}=="08"<br />
ATTRS{bNumEndpoints}=="03"<br />
ATTRS{bAlternateSetting}==" 0"<br />
ATTRS{bInterfaceNumber}=="00"<br />
<br />
looking at parent device '/devices/pci0000:00/0000:00:02.2/usb1/1-5':<br />
KERNELS=="1-5"<br />
SUBSYSTEMS=="usb"<br />
DRIVERS=="usb"<br />
ATTRS{configuration}==""<br />
ATTRS{serial}=="14AB0000000096"<br />
ATTRS{product}=="USB Mass Storage Device"<br />
ATTRS{maxchild}=="0"<br />
ATTRS{version}==" 2.00"<br />
ATTRS{devnum}=="7"<br />
ATTRS{speed}=="480"<br />
ATTRS{bMaxPacketSize0}=="64"<br />
ATTRS{bNumConfigurations}=="1"<br />
ATTRS{bDeviceProtocol}=="00"<br />
ATTRS{bDeviceSubClass}=="00"<br />
ATTRS{bDeviceClass}=="00"<br />
ATTRS{bcdDevice}=="0100"<br />
ATTRS{idProduct}=="ba01"<br />
ATTRS{idVendor}=="4146"<br />
ATTRS{bMaxPower}==" 98mA"<br />
ATTRS{bmAttributes}=="80"<br />
ATTRS{bConfigurationValue}=="1"<br />
ATTRS{bNumInterfaces}==" 1"<br />
<br />
looking at parent device '/devices/pci0000:00/0000:00:02.2/usb1':<br />
KERNELS=="usb1"<br />
SUBSYSTEMS=="usb"<br />
DRIVERS=="usb"<br />
ATTRS{configuration}==""<br />
ATTRS{serial}=="0000:00:02.2"<br />
ATTRS{product}=="EHCI Host Controller"<br />
ATTRS{manufacturer}=="Linux 2.6.18-ARCH ehci_hcd"<br />
ATTRS{maxchild}=="6"<br />
ATTRS{version}==" 2.00"<br />
ATTRS{devnum}=="1"<br />
ATTRS{speed}=="480"<br />
ATTRS{bMaxPacketSize0}=="64"<br />
ATTRS{bNumConfigurations}=="1"<br />
ATTRS{bDeviceProtocol}=="01"<br />
ATTRS{bDeviceSubClass}=="00"<br />
ATTRS{bDeviceClass}=="09"<br />
ATTRS{bcdDevice}=="0206"<br />
ATTRS{idProduct}=="0000"<br />
ATTRS{idVendor}=="0000"<br />
ATTRS{bMaxPower}==" 0mA"<br />
ATTRS{bmAttributes}=="e0"<br />
ATTRS{bConfigurationValue}=="1"<br />
ATTRS{bNumInterfaces}==" 1"<br />
<br />
looking at parent device '/devices/pci0000:00/0000:00:02.2':<br />
KERNELS=="0000:00:02.2"<br />
SUBSYSTEMS=="pci"<br />
DRIVERS=="ehci_hcd"<br />
ATTRS{broken_parity_status}=="0"<br />
ATTRS{enable}=="1"<br />
ATTRS{modalias}=="pci:v000010DEd00000068sv00001043sd00000C11bc0Csc03i20"<br />
ATTRS{local_cpus}=="f"<br />
ATTRS{irq}=="17"<br />
ATTRS{class}=="0x0c0320"<br />
ATTRS{subsystem_device}=="0x0c11"<br />
ATTRS{subsystem_vendor}=="0x1043"<br />
ATTRS{device}=="0x0068"<br />
ATTRS{vendor}=="0x10de"<br />
<br />
looking at parent device '/devices/pci0000:00':<br />
KERNELS=="pci0000:00"<br />
SUBSYSTEMS==""<br />
DRIVERS==""<br />
<br />
</pre><br />
<br />
Bit too much information! The only bit of this you actually need is the <code>ATTRS{serial}</code> part - so now you know what the above command does just grep out the bit you want in future cases:<br />
<br />
udevadm info -a -p `udevadm info -q path -n /dev/sda` | grep ATTRS{serial}<br />
<br />
output:<br />
<br />
ATTRS{serial}=="14AB0000000096"<br />
ATTRS{serial}=="0000:00:02.2"<br />
<br />
Hmm, two serials. Which one to use?<br />
<br />
udevadm info -a -p `udevadm info -q path -n /dev/sda` | grep ATTRS{product}<br />
<br />
and we get<br />
<br />
ATTRS{product}=="USB Mass Storage Device"<br />
ATTRS{product}=="EHCI Host Controller"<br />
<br />
So, we need to use first serial.<br />
<br />
==Create a udev rule==<br />
<br />
You then use the <code>ATTRS{serial}</code> in a udev rule as follows:<br />
<br />
Note: The convention for Arch Linux is to place custom rules into <code>/etc/udev/rules.d/00.rules</code><br />
You may, however create a file with a different name. Just remember that udev processes these files in alphabetical order.<br />
<br />
BUS=="usb", ATTRS{serial}=="14AB0000000096", KERNEL=="sd?1", NAME="%k", SYMLINK+="usbdrive", GROUP="storage"<br />
<br />
<br />
==Create an fstab entry and mount point==<br />
<br />
Create a directory:<br />
<br />
mkdir /mnt/usbdrive<br />
<br />
In your <code>/etc/fstab</code>, create an entry like this:<br />
<br />
/dev/usbdrive /mnt/usbdrive vfat rw,noauto,group,flush,quiet,nodev,nosuid,noexec,noatime,dmask=000,fmask=111 0 0<br />
<br />
Additionally, depending on your locale preferences, add something like <code>codepage=866,iocharset=utf-8</code> to be able to see non-Latin filenames correctly.<br />
<br />
Now root or any user who belongs to the <code>storage</code> group can mount the USB stick by simply doing<br />
<br />
mount /mnt/usbdrive<br />
<br />
BTW, all the last 3 additional mount options are meant to increase your system's security, e.g. they will prevent you running an executable file directly from the USB drive.<br />
<br />
To allow non-root users to access to USB stick do<br />
gpasswd -a user1 storage<br />
gpasswd -a user2 storage<br />
<br />
==Restart udev==<br />
<br />
To load your updated rules you can run:<br />
udevadm control --reload-rules<br />
<br />
''Note: As of udev-1.30, the following is deprecated and needs to be updated. It probably won't work anymore.''<br />
<br />
Only if really needed, you may restart udev like this. As root, run those 3 commands:<br />
/etc/./start_udev<br />
mount /dev/pts<br />
mount /dev/shm<br />
<br />
==Examples==<br />
<br />
Here are some examples from my system. My devices sometimes mount on <code>sda</code> or <code>sda1</code> so I have two rules for each - this is a work around for device not found problems. The sda node is also needed for disk-level activities e.g. <code>fdisk /dev/sda</code>.<br />
<br />
This always maps my disgo USB pen to <code>/dev/usbpen</code> which I then map in fstab to mount on <code>/mnt/usbpen</code><br />
<br />
# Symlink USB pen<br />
SUBSYSTEMS=="usb", ATTRS{serial}=="1730C13B18000B84", KERNEL=="sd?", NAME="%k", SYMLINK+="usbpen", GROUP="storage"<br />
SUBSYSTEMS=="usb", ATTRS{serial}=="1730C13B18000B84", KERNEL=="sd?1", NAME="%k", SYMLINK+="usbpen", GROUP="storage"<br />
<br />
If you have a device with with multiple partitions, the following example maps the device to <code>/dev/usbdisk</code>, and partitions 1, 2, 3 etc. to <code>/dev/usbdisk1</code>, <code>/dev/usbdisk2</code>, <code>/dev/usbdisk3</code> etc.<br />
<br />
# Symlink multi-part device<br />
SUSSYSTEMS=="usb", ATTRS{serial}=="1730C13B18000B84", KERNEL=="sd?", NAME="%k", SYMLINK+="usbdisk", GROUP="storage"<br />
SUBSYSTEMS=="usb", ATTRS{serial}=="1730C13B18000B84", KERNEL=="sd?[1-9]", NAME="%k", SYMLINK+="usbdisk%n", GROUP="storage"<br />
<br />
These rules are equivalent to the following one:<br />
<br />
# Symlink multi-part device<br />
SUBSYSTEMS=="usb", ATTRS{serial}=="1730C13B18000B84", KERNEL=="sd*", NAME="%k", SYMLINK+="usbdisk%n", GROUP="storage"<br />
<br />
You can also omit the NAME and GROUP statements, so that the defaults from <code>udev.rules</code> are used. So the shortest and simplest solution would be adding this rule:<br />
<br />
# Symlink multi-part device<br />
SUBSYSTEMS=="usb", ATTRS{serial}=="1730C13B18000B84", KERNEL=="sd*", SYMLINK+="usbdisk%n"<br />
<br />
This always maps our Olympus digicam to <code>/dev/usbcam</code> which I then map in fstab to mount on <code>/mnt/usbcam</code><br />
<br />
# Symlink USB camera<br />
SUBSYSTEMS=="usb", ATTRS{serial}=="000207532049", KERNEL=="sd?", NAME="%k", SYMLINK+="usbcam", GROUP="storage"<br />
SUBSYSTEMS=="usb", ATTRS{serial}=="000207532049", KERNEL=="sd?1", NAME="%k", SYMLINK+="usbcam", GROUP="storage"<br />
<br />
And this maps my Packard Bell MP3 player to <code>/dev/mp3player</code><br />
<br />
# Symlink MP3 player<br />
SUBSYSTEMS=="usb", ATTRS{serial}=="0002F5CF72C9C691", KERNEL=="sd?", NAME="%k", SYMLINK+="mp3player", GROUP="storage"<br />
SUBSYSTEMS=="usb", ATTRS{serial}=="0002F5CF72C9C691", KERNEL=="sd?1", NAME="%k", SYMLINK+="mp3player", GROUP="storage"<br />
<br />
To map your own usb key to <code>/dev/mykey</code> and all of other keys to <code>/dev/otherkey</code><br />
<br />
# Symlink USB keys<br />
SUBSYSTEMS=="usb", ATTRS{serial}=="insert serial key", KERNEL=="sd?1", NAME="%k", SYMLINK+="mykey"<br />
SUBSYSTEMS=="usb", KERNEL=="sd?1", NAME="%k", SYMLINK+="otherkey"<br />
<br />
Note the order of the lines. Since all the usb keys should create the /dev/sd<a||b> node, udev will first check if it is your own usb key, defined with the serial number. But if you plug another key witch you don't know the serial number, it will create a node too, with a generic name "otherkey". That rule should be the last one your rules file.<br />
<br />
<br />
This is an example how to distinguish USB HDD drive and USB sticks:<br />
<br />
BUS=="usb", ATTRS{product}=="USB2.0 Storage Device", KERNEL=="sd?", NAME="%k", SYMLINK+="usbdisk", GROUP="storage"<br />
BUS=="usb", ATTRS{product}=="USB2.0 Storage Device", KERNEL=="sd?[1-9]", NAME="%k", SYMLINK+="usbdisk%n", GROUP="storage"<br />
BUS=="usb", ATTRS{product}=="USB Mass Storage Device", KERNEL=="sd?1", NAME="%k", SYMLINK+="usbflash", GROUP="storage"<br />
<br />
Note that this udev rule doesn't use serials at all.</div>Spbkaizo