Cuando los usuarios de Linux hablan acerca del hardware de sus sistemas a gente que puede llegar a pensar que Linux es algún tipo de virus o marca de café, el uso de términos como "barra dev barra algo" provocará, sin dudas, miradas raras. Pero para el usuario afortunado (incluyendo al lector) el usar /dev/hda1 es sólo una forma rápida de explicar que nos referimos a la primera partición del disco IDE maestro. ¿O no?
Todos sabemos lo que es un archivo de dispositivo. Algunos incluso saben por qué cuando miramos un poco más de cerca la salida de ls -l en /dev los archivos de dispositivo muestran unos números especiales. Pero lo que siempre damos por sentado es que el primer disco IDE se llama /dev/hda. Tal vez no lo vea así, pero ésta es un fallo de diseño.
Piense en los dispositivos que se enchufan en caliente como los USB, IEEE 1394, tarjetas PCI que se cambian en caliente ... ¿Cuál es el primer dispositivo? ¿Y por cuánto tiempo? ¿Cómo se llamarán los demás dispositivos cuando el primero desaparezca? ¿Cómo afectará ésto a las transacciones en curso? ¿No sería gracioso que un trabajo de impresión se cambiase de repente desde su flamante impresora láser nueva a la moribunda impresora de matriz solo porque alguien decidió desenchufar la impresora láser que era la primera impresora?
Entra en escena udev. Los objetivos del proyecto udev son a la vez interesantes y necesarios:
Para proporcionar estas características, udev se desarrolla en tres proyectos separados: namedev, libsysfs y por supuesto, udev.
Namedev permite definir nombres de dispositivos independientemente del programa udev. Esto permite políticas y esquemas flexibles de asignación de nombres desarrollados por entidades diferentes. Este subsistema de asignación de nombres proporciona un interfaz estándar que udev puede usar.
Actualmente se proporciona un solo esquema de asignación de nombres con udev; de LANANA, usado por la mayoría de sistemas Linux actuales y por tanto muy apropiado para la mayoría de usuarios de Linux.
Namedev usa un procedimiento de cinco pasos para averiguar el nombre de un determinado dispositivo. Si el nombre se encuentra en uno de los pasos dados, se usa ese nombre. Estos pasos son:
El paso de etiqueta o número de serie comprueba si el dispositivo tiene un identificador único. Por ejemplo, los dispositivos USB tienen un número de serie USB único; los dispositivos SCSI tienen un único UUID. Si namedev encuentra una correspondencia entre este número único y un archivo de configuración dado, se usa el nombre proporcionado por el archivo de configuración.
El paso del número del bus del dispositivo comprueba el número del bus del dispositivo. Para dispositivos no enchufables en caliente este procedimiento es suficiente para identificar un dispositivo de hardware. Por ejemplo, los números de bus PCI rara vez cambian durante la vida de un sistema. De nuevo, si namedev encuentra una correlación entre esta posición y un archivo de configuración dado, se usa el nombre proporcionado por el archivo de configuración.
Asimismo, la topología del bus es una forma algo estática de definir dispositivos mientras el usuario no los cambie. Cuando la posición de los dispositivos concuerda con la configuración proporcionada por el usuario, se usa el nombre acompañante.
El cuarto paso nombres dados estáticamente, es simplemente una sustitución de cadenas. Cuando un nombre del núcleo (el nombre por defecto) concuerda con una cadena dada, se usa el nombre sustituto.
El paso final (nombre proporcionado por el núcleo) es una solución para cuando no funcione ninguno de los anteriores: toma el nombre por defecto proporcionado por el núcleo. En la mayoría de los casos, esto es suficiente ya que concuerda con los nombres de dispositivo usados en los sistemas actuales de Linux.
Udev interacciona con el núcleo a través de el pseudo-sistema de archivos sysfs. El proyecto libsysfs proporciona una API común para acceder de forma genérica a la información dada por el sistema de archivos sysfs. Esto permite consultar todo tipo de hardware sin tener que hacer suposiciones acerca de su tipo.
Cada vez que el núcleo detecta un evento en la estructura de dispositivos, llama a udev para echarle un vistazo. udev sigue las reglas dispuestas en el directorio /etc/udev/rules.d/ y luego usa la información entregada por el núcleo para realizar las acciones necesarias sobre la estructura de /dev (creando o eliminando archivos de dispositivos).
Udev está pensado para ser utilizado en combinación con un núcleo 2.6 (como gentoo-sources) con el perfil por defecto 2007.0. Si está usando alguno de estos núcleos, asegúrese de tener instalado una versión reciente de sys-apps/baselayout. Es todo lo que hace falta.
Listado de Código 2.1: Instalar udev |
# emerge udev
|
Al construir un núcleo, asegúrese de activar las siguientes opciones:
Listado de Código 2.2: Opciones requeridas en el núcleo |
General setup --->
[*] Support for hot-pluggable devices
File systems --->
[*] Inotify file change notification support
[*] Inotify support for userspace
Pseudo filesystems --->
[*] /proc file system support
[*] Virtual memory file system support (former shm fs)
|
Si usa genkernel, no necesita hacer nada especial. Genkernel activa udev por defecto.
Si desea usar los ajustes que ofrece Gentoo para hacer su vida más fácil, entonces no siga leyendo. Gentoo usará udev, pero mantendrá un /dev estático, de forma que no le falten nodos de dispositivos. Los guiones de inicio de Gentoo no ejecutarán al demonio devfsd y desactivará devfs al arrancar.
Pero si es fanático y quiere tener un sistema sólo con udev, sin modificaciones, tal y como se pretende en el desarrollo de udev (incluyendo la dificultad generada por perder los nodos de los dispositivos que udev no soporta todavía), por supuesto, siga adelante :)
Desactivaremos las reglas que guarden los nodos de archivo: modifique la variable RC_DEVICE_TARBALL en /etc/conf.d/rc y cámbielo a no:
Listado de Código 2.3: /etc/conf.d/rc |
RC_DEVICE_TARBALL="no" |
Si ha incluido soporte para devfs en el núcleo, puede desactivarlo en el archivo de configuración del gestor de arranque, agregando el parámetro al núcleo: gentoo=nodevfs. Si desea usar devfs y desactivar udev, agregue el parámetro gentoo=noudev.
Nodos de dispositivos que faltan al arrancar
Si no logra arrancar por culpa de errores acerca de un /dev/null no encontrado, o porque falta la consola inicial, el problema es que faltan unos nodos de algunos dispositivos que deberían existir antes de montar /dev para luego sea manejado por udev. Esto es común en máquinas Gentoo que tienen instalaciones hechas con mucha antigüedad.
Si tiene instalado sys-apps/baselayout-1.8.12 o más reciente, este problema está paliado, ya que el proceso de arranque debe poder completarse. Sin embargo, para deshacerse de esas advertencias molestas, debe crear los nodos faltantes como describimos más adelante.
Para determinar cuáles nodos están presentes antes de montar el sistema de archivos /dev, ejecute los siguientes comandos:
Listado de Código 3.1: Listar los nodos de dispositivos disponibles al arrancar |
# mkdir test # mount --bind / test # cd test/dev # ls |
Los dispositivos necesarios para un arranque exitoso son /dev/null y /dev/console. Si no aparecen en el listado previo, debe crearlos manualmente. Escriba los siguientes comandos dentro del directorio test/dev/:
Listado de Código 3.2: Crear los archivos de nodos de dispositivos necesarios |
# mknod -m 660 console c 5 1 # mknod -m 660 null c 1 3 |
Al terminar, no se olvide de desmontar el directorio test/:
Listado de Código 3.3: Desmontar el directorio test/ |
# cd ../.. # umount test # rmdir test |
Si usa el driver propietario de nvidia y el servidor X falla al iniciar en un sistema puramente udev, asegúrese de tener:
Nombramiento inconsistente entre DevFS y udev
Aunque nuestra intención es tener un esquema de nombramiento consistente para ambas soluciones dinámicas de manejo de dispositivos, a veces ocurren diferencias en el nombramiento.
Un conflicto reportado ocurre con el controlador HP Smart Array 5i (para ser más preciso, con el módulo del núcleo cciss). Con udev los dispositivos son nombrados /dev/cciss/cXdYpZ con la X, Y y Z como números enteros. Con devfs, los dispositivos son nombrados /dev/hostX/targetY/partZ o enlazados simbólicamente a /dev/cciss/cXdY.
Si este es el caso, no se olvide actualizar su archivo /etc/fstab y su archivo de configuración del gestor de arranque como corresponde.
Lo mismo ocurre con los enlaces simbólicos que existían en el directorio /dev, como /dev/mouse, el cual udev ya no crea. Asegúrese de revisar su configuración X para ver si la regla del ratón apunta a un archivo de dispositivo existente.
Otro problema es la diferencia en el nombramiento de los terminales entre devfs y udev. Aunque devfs denomina tty a sus terminales, udev por su parte los llama vc y tty. Esto podría resultar en un problema en caso de que esté restringiendo los ingresos del superusuario desde las consolas usando /etc/securetty. Tendrá que asegurarse que tty1 y vc/1 aparezcan listados en /etc/securetty para que el superusuario pueda ingresar usando la consola.
Renombrar dispositivos de bloque
Versiones más recientes de udev (104 y subsiguientes) conjuntamente con núcleos más recientes (2.6.19 y subsiguientes) podrían cambiar los nombre de los dispositivos de disco, debido a un cambio en la implementación de libata del núcleo. Un dispositivo CD-RW en /dev/hdc podría cambiar a /dev/sr0. Mientras que normalmente esto no es problema, podría causar dificultades para algunas aplicaciones que busquen los dispositivos en ubicaciones fijas. Por ejemplo, media-sound/rip espera encontrar los discos en /dev/cdrom, lo cual es un problema porque los núcleos nuevos, en conjunción con udev renombrarán este dispositivo a /dev/cdrom1.
Para solucionar estos problemas, modifique el archivo /etc/udev/rules.d/70-persistent-cd.rules y asigne el nombre correcto al dispositivo.
Para más información acerca de escribir reglas para udev, por favor lea la guía de Daniel Drake.
A veces enchufar y enchufar de nuevo un dispositivo de red (cómo una tarjeta WiFi USB) puede renombrar su dispositivo de red cada vez, incrementando el número en uno.
Cuando esto ocurra, puede ver que se nombran wlan0, wlan1, wlan2, etc. Esto es porque udev esta añadiendo reglas adicionales a su fichero de reglas, en lugar de recargar las reglas existentes. Ya que udev ve su directorio de reglas a través de inotify, necesitará soporte para inotify en su fichero de configuración del núcleo:
Listado de Código 3.4: Habilitando soporte para inotify en el núcleo |
File systems --->
[*] Inotify file change notification support
[*] Inotify support for userspace
|
Ahora udev conservará los nombres apropiados para sus dispositivos de red.
udev carga los módulos en orden impredecible
A veces udev carga los módulos en un orden indeseado, impredecible o hasta aparentemente aleatorio. Esto es especialmente común en sistema con dispositivo múltiples del mismo tipo, al igual que dispositivos multimedia. Esto puede afectar los número de dispositivo asignados; por ejemplo, las tarjetas de sonido se cambian de número.
Existen unas pocas soluciones para resolver la asignación de números de dispositivo y/o orden de carga de los módulos. Idealmente, podría pasar parámetros al módulo para especificar el número de dispositivo deseado. Algunos módulos, como los de ALSA, incluyen un parámetro tipo "índice". Los módulos que usen este parámetro pueden ser ajustados de esta manera. Este ejemplo es para un sistema con dos tarjetas de sonido. La tarjeta con el índice 0 es designada como la primera tarjeta. Una vez que los parámetros sean cambiados, los archivos de configuración de los módulos deben ser actualizados.
Listado de Código 3.5: Especificar los parámetros por módulo |
# echo "option snd-ice1724 index=0" >> /etc/modprobe.d/alsa # echo "option snd-ymfpci index=1" >> /etc/modprobe.d/alsa # update-modules |
El ejemplo anterior es la solución preferida, pero no todos los módulos soportan este tipo de parámetro. Para estos módulos, habrá que forzar el orden correcto para su carga. Primero hay que pedirle a udev que no los cargue, colocándolos en una lista negra. Asegúrese de usar el nombre exacto del módulo a cargar. Para los dispositivos PCI, use los nombres obtenidos de la salida del comando pcimodules, disponible en el paquete pciutils. El siguiente ejemplo usa módulos DVB.
Listado de Código 3.6: Colocar los módulos en lista negra |
# echo "blacklist b2c2-flexcop-pci" >> /etc/modprobe.d/dvb # echo "blacklist budget" >> /etc/modprobe.d/dvb # update-modules |
Luego, cargue los módulos en el orden correcto. Agréguelos al /etc/modules.autoload.d/kernel-2.6 en el orden exacto que desee cargarlos.
Listado de Código 3.7: Cargar los módulos en el orden correcto |
# echo "budget" >> /etc/modules.autoload.d/kernel-2.6 # echo "b2c2-flexcop-pci" >> /etc/modules.autoload.d/kernel-2.6 |
Si los nodos de dispositivo no son creados al cargar un módulo en el archivo /etc/modules.autoload.d/kernel-2.6 pero si aparecen al cargarlo manualmente con modprobe, intente actualizar al sys-apps/baselayout-1.8.12 o más reciente.
El soporte para los dispositivos framebuffer (/dev/fb/*) viene con los núcleos a partir de la versión 2.6.6-rc2.
Para núcleos más antiguos que la versión 2.6.4, debe explícitamente incluir el soporte para el sistema de archivos /dev/pts.
Listado de Código 3.8: Activar el sistema de archivos /dev/pts |
File systems --->
Pseudo filesystems --->
[*] /dev/pts file system for Unix98 PTYs
|
La charla sobre udev en el Linux Symposium (Ottawa, Ontario Canada - 2003) dada por Greg Kroah-Hartman (IBM Corporation) proporcionó un sólido entendimiento acerca de la aplicación udev.
Decibel's UDEV Primer es un documento, en inglés, que trata en profundidad acerca de udev y Gentoo.
Writing udev rules por nuestro compañero desarrollador Gentoo Daniel Drake, es un excelente documento para aprender a personalizar su instalación udev.
El contenido de este documento está registrado bajo los términos de la licencia Creative Commons - Reconocimiento / Compartir Igual