Udev

De Astillas.net

Enlaces y referencias

  • Ref: Writing udev rules by Daniel Drake que sólo está actualizado hasta el año 2008 por lo que algunos programas que emplea ya no existen. Es el caso de udevinfo que en la versión Squeeze de Debian es sustituído por udevadm info.

Recetario

Asignar propietario a un dispositivo

Lo primero es obtener atributos del dispositivo sobre el que vamos a escribir la regla. En nuestro caso es un SAI APC Smart UPS 1000 SC que incluye un conversor RS232 a USB y que el sistema crea como /dev/serial/by-id/usb-Prolific_Technology_Inc._USB-Serial_Controller-if00-port0 aunque luego es un enlace a /dev/ttyUSB0:

 # udevadm info --query=all --name=/dev/ttyUSB0 
 P: /devices/pci0000:00/0000:00:02.0/usb2/2-7/2-7:1.0/ttyUSB0/tty/ttyUSB0
 N: ttyUSB0
 S: char/188:0
 S: serial/by-path/pci-0000:00:02.0-usb-0:7:1.0-port0
 S: serial/by-id/usb-Prolific_Technology_Inc._USB-Serial_Controller-if00-port0
 E: UDEV_LOG=3
 E: DEVPATH=/devices/pci0000:00/0000:00:02.0/usb2/2-7/2-7:1.0/ttyUSB0/tty/ttyUSB0
 E: MAJOR=188
 E: MINOR=0
 E: DEVNAME=/dev/ttyUSB0
 E: SUBSYSTEM=tty
 E: ID_PORT=0
 E: ID_PATH=pci-0000:00:02.0-usb-0:7:1.0
 E: ID_VENDOR=Prolific_Technology_Inc.
 E: ID_VENDOR_ENC=Prolific\x20Technology\x20Inc.
 E: ID_VENDOR_ID=067b
 E: ID_MODEL=USB-Serial_Controller
 E: ID_MODEL_ENC=USB-Serial\x20Controller
 E: ID_MODEL_ID=2303
 E: ID_REVISION=0300
 E: ID_SERIAL=Prolific_Technology_Inc._USB-Serial_Controller
 E: ID_TYPE=generic
 E: ID_BUS=usb
 E: ID_USB_INTERFACES=:ff0000:
 E: ID_USB_INTERFACE_NUM=00
 E: ID_USB_DRIVER=pl2303
 E: ID_IFACE=00
 E: ID_VENDOR_FROM_DATABASE=Prolific Technology, Inc.
 E: ID_MODEL_FROM_DATABASE=PL2303 Serial Port
 E: DEVLINKS=/dev/char/188:0 /dev/serial/by-path/pci-0000:00:02.0-usb-0:7:1.0-port0 /dev/serial/by-id/usb-Prolific_Technology_Inc._USB-Serial_Controller-if00-port0

Después escribimos la regla seleccionando el subsistema y algún atributo que lo identifique lo más inequívocamente posible:

 SUBSYSTEM=="tty", ATTRS{ID_MODEL_FROM_DATABASE}=="PL2303 Serial Port",SYMLINK="APC_Smart_UPS_1000_SC",\
             ACTION=="add",GROUP:="nut",MODE="0660",SYMLINK+="APC_Smart_UPS_1000_SC"

En este caso lo que pretendemos es que cambie el grupo propietario para que el usuario nut tenga acceso al mismo según aparezca éste en el sistema, que cambie los permisos de acceso y que añada un enlace simbólico que nos facilite su localización. El archivo de reglas lo instalamos con el nombre de /etc/udev/rules.d/75-apc-smart-ups-1000.rules y pasamos a testearlo antes de instalarlo definitivamente.

Verificar reglas udev

Para determinar qué hará udev con un nuevo dispositivo podemos invocar la utilidad administrativa udevadm con los parámetros adecuados. En el caso de la ruta del dispositivo dentro del mapa del núcleo podemos consultar directamente al sistema con:

   # udevadm info --query=path --name=/dev/ttyUSB0 
   /devices/pci0000:00/0000:00:02.0/usb2/2-7/2-7:1.0/ttyUSB0/tty/ttyUSB0

y luego pasar los test con:

   # udevadm test /devices/pci0000:00/0000:00:02.0/usb2/2-7/2-7:1.0/ttyUSB0/tty/ttyUSB0
   run_command: calling: test
   udevadm_test: version 164
   parse_file: reading '/lib/udev/rules.d/19-ifrename.rules' as rules file
   ...
   parse_file: reading '/etc/udev/rules.d/z21_persistent-local.rules' as rules file
   ...
   util_run_program: '/lib/udev/usb-db' (stderr) 'device 0x7f53e61ccb70 has devpath '/devices/pci0000:00/0000:00:02.0/usb2/2-7
   util_run_program: '/lib/udev/usb-db' (stdout) 'ID_VENDOR_FROM_DATABASE=Prolific Technology, Inc.'
   util_run_program: '/lib/udev/usb-db' (stdout) 'ID_MODEL_FROM_DATABASE=PL2303 Serial Port'
   util_run_program: 'usb-db /devices/pci0000:00/0000:00:02.0/usb2/2-7/2-7:1.0/ttyUSB0/tty/ttyUSB0' returned with exitcode 0
   udev_rules_apply_to_event: GROUP 20 /lib/udev/rules.d/91-permissions.rules:39
   udev_rules_apply_to_event: GROUP 121 /etc/udev/rules.d/z21_persistent-local.rules:2
   udev_rules_apply_to_event: MODE 0660 /etc/udev/rules.d/z21_persistent-local.rules:2
   udev_rules_apply_to_event: LINK 'APC_Smart_UPS_1000_SC' /etc/udev/rules.d/z21_persistent-local.rules:2
   ...
   link_update: creating link '/dev/APC_Smart_UPS_1000_SC' to '/dev/ttyUSB0'
   node_symlink: creating symlink '/dev/APC_Smart_UPS_1000_SC' to 'ttyUSB0'
   ...
   udevadm_test: UDEV_LOG=6
   udevadm_test: DEVPATH=/devices/pci0000:00/0000:00:02.0/usb2/2-7/2-7:1.0/ttyUSB0/tty/ttyUSB0
   udevadm_test: MAJOR=188
   udevadm_test: MINOR=0
   udevadm_test: DEVNAME=/dev/ttyUSB0
   udevadm_test: ACTION=add
   udevadm_test: SUBSYSTEM=tty
   udevadm_test: DEVLINKS=/dev/char/188:0 /dev/serial/by-path/pci-0000:00:02.0-usb-0:7:1.0-port0 /dev/serial/by-id/usb-Prolific_Technology_Inc._USB-Serial_Controller-if00-port0 /dev/APC_Smart_UPS_1000_SC
   udevadm_test: ID_PORT=0
   udevadm_test: ID_PATH=pci-0000:00:02.0-usb-0:7:1.0
   udevadm_test: ID_VENDOR=Prolific_Technology_Inc.
   udevadm_test: ID_VENDOR_ENC=Prolific\x20Technology\x20Inc.
   udevadm_test: ID_VENDOR_ID=067b
   udevadm_test: ID_MODEL=USB-Serial_Controller
   udevadm_test: ID_MODEL_ENC=USB-Serial\x20Controller
   udevadm_test: ID_MODEL_ID=2303
   udevadm_test: ID_REVISION=0300
   udevadm_test: ID_SERIAL=Prolific_Technology_Inc._USB-Serial_Controller
   udevadm_test: ID_TYPE=generic
   udevadm_test: ID_BUS=usb
   udevadm_test: ID_USB_INTERFACES=:ff0000:
   udevadm_test: ID_USB_INTERFACE_NUM=00
   udevadm_test: ID_USB_DRIVER=pl2303
   udevadm_test: ID_IFACE=00
   udevadm_test: ID_VENDOR_FROM_DATABASE=Prolific Technology, Inc.
   udevadm_test: ID_MODEL_FROM_DATABASE=PL2303 Serial Port
   This program is for debugging only, it does not run any program,
   specified by a RUN key. It may show incorrect results, because
   some values may be different, or not available at a simulation run.

Relanzar eventos

Cuando necesitemos que udev vuelva a ejecutar sus juegos de reglas podemos pedirlo empleando la utilidad administrativa udevadm con la orden trigger y filtrando incluso por subsistema para no tocar el resto:

  # udevadm trigger --subsystem-match=tty
  # 

En este caso conviene recordar que algunos servicios como el de impresión (CUPS) pueden necesitar un reinicio si emplean impresoras conectadas directamente a la máquina que lo ejecuta.

Controlando el servidor

La utilidad administrativa udevadm permite realizar varios ajustes en el servidor:

udevadm control --log-priority={err|info|debug}
Cambia el nivel de depuración en el servidor.
udevadm control --reload-rules
Indica al servidor que cargue de nuevo los archivos de reglas pero sin afectar en absoluto a los dispositivos. udev ya carga automáticamente los archivos de reglas cuando detecta cambios por lo que esta opción no debería ser de uso frecuente.

Errores y problemas

udev: renamed network interface ...

Cuando uno encuentra este mensaje en los registros del sistema es casi seguro que la red acaba de dejar de funcionar. El culpable es el mecanismo udev, en concreto el programa /lib/udev/write_net_rules que es el encargado de crear el siguiente archivo:

/etc/udev/rules.d/70-persistent-net.rules 

cuyo contenido revela

SUBSYSTEM=="net", DRIVERS=="?*", ATTRS{address}=="00:05:1c:10:be:82", NAME="eth0"

# PCI device 0x10de:0x0057 (forcedeth)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:16:17:98:9b:8b", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth2"

El programa /lib/udev/write_net_rules es el que se encarga de crear el fichero de reglas.

udevd: SYSFS{} will be removed in a future version

Al parecer uno de los cambios en la síntaxis de las reglas de udev provoca que aparezcan multitud de avisos como éste en el arranque del sistema. Son avisos y no errores, y como tales pueden ignorarse hasta que en alguna versión futura todo deje de funcionar.

Al parecer una posible solución está en sustituir todas las apariciones de la expresión SYSFS por ATTR en todos los archivos de reglas:

# cd /etc/udev/rules.d
# egrep -l SYSFS *
025_logitechmouse.rules
10-blackberry.rules
99-pilot.rules
libnjb.rules
z60_iscan.rules
z60_xserver-xorg-input-wacom.rules
# perl -i -p -e "s{SYSFS}{ATTR}g" $(egrep -l SYSFS *)

Y como precaución reiniciar el paquete udev y el subsistema:

# dpkg-reconfigure udev 
update-initramfs: Generating /boot/initrd.img-2.6.32-5-amd64
...
# /etc/init.d/udev restart
Stopping the hotplug events dispatcher: udevd.
Starting the hotplug events dispatcher: udevd.