Map Custom Device Entries with udev (Español)

From ArchWiki
Revision as of 17:29, 20 October 2012 by Pedro (Talk | contribs)

Jump to: navigation, search

Esta información es básicamente una réplica de la que aparece en la wiki de Gentoo con el añadido de algunas pistas. Recientemente fue actualizada para reflejar los cambios acaecidos en la sintaxis de las versiones de udev a partir de la 98.

Este proceso le permite asignar siempre un dispositivo específico al mismo nodo /dev. Se puede utilizar esto en fstab para asegurarse de que el dispositivo se monta siempre con exactitud en el mismo punto, lo que es genial para tener atajos de teclado.

Obtener la información que conoce udev acerca de su dispositivo USB

Asegúrese de tener conectado uno de sus dispositivos y ejecute lo siguiente como root:

udevinfo -a -p `udevinfo -q path -n /dev/sda`

Así se obtiene la información de udev del dispositivo conectado en /dev/sda - si su dispositivo no está en /dev/sda tendrá obviamente que poner el dispositivo que sea correcto. :)

Debería obtener una salida como ésta:


Udevinfo 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.

  looking at device '/block/sda':
    KERNEL=="sda"
    SUBSYSTEM=="block"
    DRIVER==""
    ATTR{stat}=="      19      111      137      160        0        0        0        0        0      152      160"
    ATTR{size}=="2007040"
    ATTR{removable}=="1"
    ATTR{range}=="16"
    ATTR{dev}=="8:0"

  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':
    KERNELS=="5:0:0:0"
    SUBSYSTEMS=="scsi"
    DRIVERS=="sd"
    ATTRS{ioerr_cnt}=="0x0"
    ATTRS{iodone_cnt}=="0x1c"
    ATTRS{iorequest_cnt}=="0x1c"
    ATTRS{iocounterbits}=="32"
    ATTRS{timeout}=="30"
    ATTRS{state}=="running"
    ATTRS{rev}=="1.20"
    ATTRS{model}=="01GB Tiny       "
    ATTRS{vendor}=="Pretec  "
    ATTRS{scsi_level}=="3"
    ATTRS{type}=="0"
    ATTRS{queue_type}=="none"
    ATTRS{queue_depth}=="1"
    ATTRS{device_blocked}=="0"
    ATTRS{max_sectors}=="240"

  looking at parent device '/devices/pci0000:00/0000:00:02.2/usb1/1-5/1-5:1.0/host5/target5:0:0':
    KERNELS=="target5:0:0"
    SUBSYSTEMS==""
    DRIVERS==""

  looking at parent device '/devices/pci0000:00/0000:00:02.2/usb1/1-5/1-5:1.0/host5':
    KERNELS=="host5"
    SUBSYSTEMS==""
    DRIVERS==""

  looking at parent device '/devices/pci0000:00/0000:00:02.2/usb1/1-5/1-5:1.0':
    KERNELS=="1-5:1.0"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb-storage"
    ATTRS{modalias}=="usb:v4146pBA01d0100dc00dsc00dp00ic08isc06ip50"
    ATTRS{bInterfaceProtocol}=="50"
    ATTRS{bInterfaceSubClass}=="06"
    ATTRS{bInterfaceClass}=="08"
    ATTRS{bNumEndpoints}=="03"
    ATTRS{bAlternateSetting}==" 0"
    ATTRS{bInterfaceNumber}=="00"

  looking at parent device '/devices/pci0000:00/0000:00:02.2/usb1/1-5':
    KERNELS=="1-5"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{configuration}==""
    ATTRS{serial}=="14AB0000000096"
    ATTRS{product}=="USB Mass Storage Device"
    ATTRS{maxchild}=="0"
    ATTRS{version}==" 2.00"
    ATTRS{devnum}=="7"
    ATTRS{speed}=="480"
    ATTRS{bMaxPacketSize0}=="64"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{bDeviceProtocol}=="00"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bDeviceClass}=="00"
    ATTRS{bcdDevice}=="0100"
    ATTRS{idProduct}=="ba01"
    ATTRS{idVendor}=="4146"
    ATTRS{bMaxPower}==" 98mA"
    ATTRS{bmAttributes}=="80"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bNumInterfaces}==" 1"

  looking at parent device '/devices/pci0000:00/0000:00:02.2/usb1':
    KERNELS=="usb1"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{configuration}==""
    ATTRS{serial}=="0000:00:02.2"
    ATTRS{product}=="EHCI Host Controller"
    ATTRS{manufacturer}=="Linux 2.6.18-ARCH ehci_hcd"
    ATTRS{maxchild}=="6"
    ATTRS{version}==" 2.00"
    ATTRS{devnum}=="1"
    ATTRS{speed}=="480"
    ATTRS{bMaxPacketSize0}=="64"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{bDeviceProtocol}=="01"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bDeviceClass}=="09"
    ATTRS{bcdDevice}=="0206"
    ATTRS{idProduct}=="0000"
    ATTRS{idVendor}=="0000"
    ATTRS{bMaxPower}=="  0mA"
    ATTRS{bmAttributes}=="e0"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bNumInterfaces}==" 1"

  looking at parent device '/devices/pci0000:00/0000:00:02.2':
    KERNELS=="0000:00:02.2"
    SUBSYSTEMS=="pci"
    DRIVERS=="ehci_hcd"
    ATTRS{broken_parity_status}=="0"
    ATTRS{enable}=="1"
    ATTRS{modalias}=="pci:v000010DEd00000068sv00001043sd00000C11bc0Csc03i20"
    ATTRS{local_cpus}=="f"
    ATTRS{irq}=="17"
    ATTRS{class}=="0x0c0320"
    ATTRS{subsystem_device}=="0x0c11"
    ATTRS{subsystem_vendor}=="0x1043"
    ATTRS{device}=="0x0068"
    ATTRS{vendor}=="0x10de"

  looking at parent device '/devices/pci0000:00':
    KERNELS=="pci0000:00"
    SUBSYSTEMS==""
    DRIVERS==""

¡Tal vez demasiada información! Lo único que necesita de todo esto es la parte ATTRS{serial} - así que ahora que sabe lo que hace la orden anterior, en el futuro sólo tendrá usar grep para filtrar lo que busque:

udevinfo -a -p `udevinfo -q path -n /dev/sda` | grep ATTRS{serial}

salida:

   ATTRS{serial}=="14AB0000000096"
   ATTRS{serial}=="0000:00:02.2"

Hmm, dos serials. ¿Cuál utilizar?

udevinfo -a -p `udevinfo -q path -n /dev/sda` | grep ATTRS{product}

y obtenemos

   ATTRS{product}=="USB Mass Storage Device"
   ATTRS{product}=="EHCI Host Controller"

Por tanto, necesitamos utilizar el primer serial.


Crear una regla udev

Ahora utilizará el ATTRS{serial} en una regla udev de esta manera:

Nota: la convención en Arch Linux es situar las reglas personalizadas en /etc/udev/rules.d/00.rules Usted puede, sin embargo, crear un fichero con un nombre diferente. Recuerde tan sólo que udev procesa estos ficheros en orden alfabético.

BUS=="usb", ATTRS{serial}=="14AB0000000096", KERNEL=="sd?1", NAME="%k", SYMLINK+="usbdrive", GROUP="storage"


Crear en entrada en fstab con el punto de montaje

Cree un directorio:

 mkdir /mnt/usbdrive

En su archivo /etc/fstab, cree una entrada como ésta:

/dev/usbdrive    /mnt/usbdrive    vfat rw,noauto,group,flush,quiet,nodev,nosuid,noexec,noatime,dmask=000,fmask=111    0 0

Adicionalmente, dependiendo de sus propias preferencias, añada algo parecido a codepage=866,iocharset=utf-8 para ser capaz de ver correctamente los nombres de fichero con caracteres no latinos.

Ahora el usuario root o cualquier otro usuario que pertenezca al grupo storage podrá montar el dispositivo USB con un simple

mount /mnt/usbdrive

A propósito, cada una de las 3 opciones de montaje adicionales buscan incrementar la seguridad de su sistema, p.ej. le impedirán ejecutar un ejecutable directamente desde el dispositivo USB.

Para permitir a los usuarios normales acceder al dispositivo USB haga

gpasswd -a user1 storage
gpasswd -a user2 storage

Rearrancar udev

para probar sus reglas actualizadas ejecute:

udevcontrol reload_rules

Solamente si es absolutamente necesario, puede rearrancar udev de esta manera. Como roo, ejecute estas 3 órdenes:

/etc/./start_udev
mount /dev/pts
mount /dev/shm

Ejemplos

Estos son algunos ejemplos procedentes de mi sistema. Mis dispositivos a veces se montan en sda y a veces en sda1 así que tengo dos reglas para cada uno de ellos - esta es una solución para dispositivos que no presentan problemas. El nodo sda es también necesario para actividades a nivel de disco p.ej. fdisk /dev/sda.

Esto relaciona siempre mi lápiz USB Disgo con /dev/usbpen al cual le asigno como punto de montaje /mnt/usbpen en fstab.

# Symlink USB pen
SUBSYSTEMS=="usb", ATTRS{serial}=="1730C13B18000B84", KERNEL=="sd?", NAME="%k", SYMLINK+="usbpen", GROUP="storage"
SUBSYSTEMS=="usb", ATTRS{serial}=="1730C13B18000B84", KERNEL=="sd?1", NAME="%k", SYMLINK+="usbpen", GROUP="storage"

Si tiene un dispositivo con múltiples particiones, el siguiente ejemplo relacona el dispositivo con /dev/usbdisk, y las particiones 1, 2, 3 etc. con /dev/usbdisk1, /dev/usbdisk2, /dev/usbdisk3 etc.

# Symlink multi-part device
SUSSYSTEMS=="usb", ATTRS{serial}=="1730C13B18000B84", KERNEL=="sd?", NAME="%k", SYMLINK+="usbdisk", GROUP="storage"
SUBSYSTEMS=="usb", ATTRS{serial}=="1730C13B18000B84", KERNEL=="sd?[1-9]", NAME="%k", SYMLINK+="usbdisk%n", GROUP="storage"

Estas reglas son equivalentes a esta otra:

# Symlink multi-part device
SUBSYSTEMS=="usb", ATTRS{serial}=="1730C13B18000B84", KERNEL=="sd*", NAME="%k", SYMLINK+="usbdisk%n", GROUP="storage"

También puede omitir las asignaciones NAME y GROUP, de manera que se usen los valores por defecto de udev.rules. La solución más corta y sencilla sería pues añadiendo esta regla:

# Symlink multi-part device
SUBSYSTEMS=="usb", ATTRS{serial}=="1730C13B18000B84", KERNEL=="sd*", SYMLINK+="usbdisk%n"

Esto siempre relaciona nuestra cámara digital Olympus con /dev/usbcam a la que asigno en fstab el punto de montaje /mnt/usbcam

# Symlink USB camera
SUBSYSTEMS=="usb", ATTRS{serial}=="000207532049", KERNEL=="sd?", NAME="%k", SYMLINK+="usbcam", GROUP="storage"
SUBSYSTEMS=="usb", ATTRS{serial}=="000207532049", KERNEL=="sd?1", NAME="%k", SYMLINK+="usbcam", GROUP="storage"

Y esto relaciona mi reproductor MP3 Packard Bell MP3 con /dev/mp3player

# Symlink MP3 player
SUBSYSTEMS=="usb", ATTRS{serial}=="0002F5CF72C9C691", KERNEL=="sd?", NAME="%k", SYMLINK+="mp3player", GROUP="storage"
SUBSYSTEMS=="usb", ATTRS{serial}=="0002F5CF72C9C691", KERNEL=="sd?1", NAME="%k", SYMLINK+="mp3player", GROUP="storage"

Para relacionar su propio llavero USB con /dev/mykey y todos los demás llaveros con /dev/otherkey

# Symlink USB keys
SUBSYSTEMS=="usb", ATTRS{serial}=="insert serial key", KERNEL=="sd?1", NAME="%k", SYMLINK+="mykey"
SUBSYSTEMS=="usb", KERNEL=="sd?1", NAME="%k", SYMLINK+="otherkey"

Tenga en cuenta el orden de las líneas. Dado que todos los llaveros USB deberían crear el nodo /dev/sd<a||b>, udev comprobará primero si es su propio llavero USB, definido por el número de serie. Pero si inserta otro llavero del que no conoce el número de serie, creará un nodo también, con el nombre genérico "otherkey". Esta regla debería ser la última en su archivo de reglas.


Este es un ejemplo de cómo distinguir una unidad de dsco duro USB y un dispositivo de memoria USB:

BUS=="usb", ATTRS{product}=="USB2.0 Storage Device", KERNEL=="sd?", NAME="%k", SYMLINK+="usbdisk", GROUP="storage"
BUS=="usb", ATTRS{product}=="USB2.0 Storage Device", KERNEL=="sd?[1-9]", NAME="%k", SYMLINK+="usbdisk%n", GROUP="storage"
BUS=="usb", ATTRS{product}=="USB Mass Storage Device", KERNEL=="sd?1", NAME="%k", SYMLINK+="usbflash", GROUP="storage"

Fíjese en que esta regla de udev bo utiliza serials en absoluto.