En el Capítulo 6 se instaló el paquete Udev. Antes de entrar en detalles sobre cómo funciona, repasaremos los anteriores métodos de manejo de dispositivos.
Tradicionalmente, los sistemas Linux en general utilizan un método
estático de creación de dispositivos, implicando que un gran número
de nodos de dispositivo son creados en /dev
(literalmente, cientos de nodos) sin tener en
cuenta si el dispositivo hardware correspondiente existe en realidad.
Esto se hace típicamente mediante un guión MAKEDEV, que contiene una serie de
llamadas al programa mknod con los números mayor y menor
correspondientes a cada posible dispositivo que pudiera existir en el
mundo.
Con el uso del método Udev, sólo se crearán los nodos
correspondientes a aquellos dispositivos detectados por el núcleo.
Debido a que estos nodos de dispositivo se crearán cada vez que se
inicie el sistema, se almacenarán en un sistema de ficheros
tmpfs
(el cual existe por completo en
memoria). Los nodos de dispositivo no necesitan mucho espacio, por lo
que la memoria utilizada es muy poca.
En Febrero de 2000, un nuevo sistema de ficheros llamado
devfs
fue incluido en los núcleos
2.3.46 y estuvo disponible en la serie 2.4 de los núcleos estables.
Aunque estaba presente en las propias fuentes del núcleo, este
método de creación dinámica de dispositivos nunca recibió mucho
apoyo por parte del equipo de desarrolladores del núcleo.
El principal problema con el sistema adoptado por devfs
era el modo en el que manejaba la
detección, creación y denominación de dispositivos. El último
punto, la denominación de los nodos, fue quizás el más crítico.
Está generalmente aceptado que si los nombres de dispositivos son
configurables, entonces las políticas de denominación deberían ser
establecidas por un administrador del sistema y no impuestas por un
desarrollador en particular. El sistema de ficheros devfs
sufre también de extraños comportamientos
inherentes a su diseño y que no pueden corregirse sin una revisión
sustancial del núcleo. Durante un tiempo fué marcado como
descartado debido a la falta de mantenimiento, siendo removido
finalmente del núcleo en Junio de 2006.
Con el desarrollo del árbol inestable 2.5 del núcleo,
posteriormente liberado como núcleos estables de la serie 2.6,
aparece un nuevo sistema de ficheros virtual llamado sysfs
. El trabajo de sysfs
es exportar una visión de la
configuración hardware del sistema a los procesos de usuario. Con
esta representación visible a nivel de usuario, la posibilidad de
encontrar un sustituto para devfs
a
nivel de usuario se hace mucho más real.
Arriba se mencionó brevemente el sistema de ficheros sysfs
. Uno podría preguntarse cómo conoce
sysfs
los dispositivos presentes
en el sistema y qué números de dispositivo debe usar. Los
crontroladores que se han compilado directamente dentro del
núcleo registran sus objetos en sysfs
a medida que son detectados por el
núcleo. Para los controladores compilados como módulos, esto
sucederá cuando se cargue el módulo. Una vez montado el sistema
de ficheros sysfs
(en
/sys
), los datos registrados en
sysfs
por los controladores están
disponibles para los procesos de usuario y para que udevd cree los nodos de
dispositivo.
El guión de inicio S10udev se ocupa de la creación
de dichos nodos de dispositivo cuando se inicia Linux. Este guión
desactiva /sbin/hotplug como manejador
uevent. Esto se hace debido a que el núcleo ya no necesita llamar
a binarios externos. En su lugar, udevd escuchará en un conector
de red los uevent que el núcleo genere. A continuación, el guión
de arranque copia los nodos de dispositivo estáticos que
encuentre en /lib/udev/devices
a
/dev
. Esto es necesario ya que
algunos dispositivos, directorios y enlaces simbólicos son
requeridos antes de que el proceso de manejo dinámico de
dispositivos esté disponible durante las primeras fases del
arranque del sistema. La creación de nodos de dispositivo
estáticos en /lib/udev/devices
proporciona también una solución para aquellos dispositivos no
soportados por la infraestructura de manejo dinámico de
dispositivos. Entonces el guión de arranque iniciará el demonio
Udev, udevd, que
actuará sobre cualquier uevent recibido. Por último, el guión de
arranque fuerza al núcleo a repetir los uevents de los
dispositivos que ya hayan sido registrados y espera a que
udevd los maneje.
Para obtener los números mayor y menor correctos de un
dispositivo, Udev utiliza la información proporcionada por
sysfs
en /sys
. Por ejemplo, /sys/class/tty/vcs/dev
contiene la cadena
“7:0”. Esta cadena es
usada por udevd
para crear un nodo de dispositivo con número mayor 7 y menor 0. Los permisos y modos de los nodos
creados en el directorio /dev
son
determinados por las reglas especificadas en los ficheros que hay
en el directorio /etc/udev/rules.d/
. Estas se encuentran
numeradas en un formato similar al del paquete LFS-Bootscripts.
Si udevd no puede
encontrar una regla para el dispositivo que está creando,
utilizará los permisos 660
y como propietario root:root.La documentación sobre la
sintaxis de los ficheros de reglas de configuración de Udev se
encuentra en /usr/share/doc/udev-113/index.html
Los controladores de dispositivos compilados como módulos pueden
tener alias dentro de ellos. Los alias son visibles en la salida
del programa modinfo y normalmente están
relacionados con el identificados específico del bus de los
dispositivos soportados por el módulo. Por ejemplo, el
controlador snd-fm801
soporta dispositivos PCI con ID de vendedor 0x1319 e ID de
dispositivo 0x0801, y tiene el alias “pci:v00001319d00000801sv*sd*bc04sc01i*”.
Para muchos dispositivos, el controlador del bus exporta a través
de sysfs
el alias del controlador
que podría manejar el dispositivo. Por ejemplo, el fichero
/sys/bus/pci/devices/0000:00:0d.0/modalias
podría contener la cadena “pci:v00001319d00000801sv00001319sd00001319bc04sc01i00”.
Las reglas instaladas por LFS harán que udevd llame a /sbin/modprobe con el contenido
de la variable de entorno uevent MODALIAS
(que debería ser igual al contenido del
fichero modalias
del sysfs),
cargando todos los módulos cuyos alias concuerden con dicha
cadena tras la expansión de comodines.
En el ejemplo, esto significa que en adición a snd-fm801, el obsoleto (y no deseado) controlador forte será cargado si está disponible. Más abajo se muestran formas de evitar la carga de dispositivos no deseados.
El propio núcleo también es capaz de cargar módulos para protocolos de red, sistemas de ficheros y soporte NLS bajo demanda.
Cuando conectas un dispositivo, como un reproductor MP3 por USB, el núcleo reconoce que el dispositivo está conectado ahora y genera un uevent. Este uevent es manejado por udevd como se describe arriba.
Hay algunos problemas en relación con la creación automática de nodos de dispositivos.
Udev cargará un módulo sólo si este tiene un alias específico del
bus y el controlador del bus exporta correctamente los alias
necesarios a sysfs
. En caso
contrario, la carga del módulo deberá realizarse por otros
métodos. Con Linux-2.6.22.6, se sabe que Udev carga los
controladores correctamente escritos para dispositivos INPUT,
IDE, PCI, USB, SCSI, SERIO y FireWire.
Para determinar si el controlador de dispositivo que necesitas
tiene el soporte necesario para Udev, ejecuta modinfo con el nombre del
módulo como argumento. Ahora intenta localizar el directorio del
dispositivo bajo /sys/bus
y
comprueba si hay un fichero modalias
.
Si el fichero modalias
existe en
sysfs
, el controlador soporta el
dispositivo y puede hablar con él directamente, pero no contiene
el alias, esto es un fallo en el controlador. Carga el
controlador sin la ayuda de Udev y espera que el problema sea
solucionado más adelante.
Si no hay un fichero modalias
en el
directorio correspondiente bajo /sys/bus
, esto significa que los
desarrolladores del núcleo no han añadido todavía soporte de
alias a ese tipo de bus. Con Linux-2.6.22.6, este es el caso con
los bus ISA. Se espera que esto se resuelva e futuras versiones
del núcleo.
Udev no está pensado para cargar controladores “envoltorio”, como snd-pcm-oss o controladores que no pertenecen al hardware, como loop.
Si el módulo “envoltorio”
sólo amplía la funcionalidad proporcionada por otro módulo (del
modo que snd-pcm-oss
amplía la funcionalidad de snd-pcm haciendo que las tarjetas de
sonido están disponibles para aplicaciones OSS), configura
modprobe para
cargar el envoltorio despues de que Udev carge el módulo
envuelto. Para hacer esto, añade una línea “install” en /etc/modprobe.conf
. Por ejemplo:
install snd-pcm /sbin/modprobe -i snd-pcm ; \
/sbin/modprobe snd-pcm-oss ; true
Si el módulo en cuentión no es un envoltorio y es útil por si
mismo. configura el guión de arranque S05modules para cargar dicho
módulo en el arranque del sistema. Para hacer esto, añade una
nueva línea con el nombre del módulo al fichero /etc/sysconfig/modules
. Esto también funciona
para módulos envoltorio, pero no es óptimo en dicho caso.
Entonces no construyas el módulo, o ignoralo en el fichero
/etc/modprobe.conf
como se hace en
el siguiente ejemplo para el módulo forte:
blacklist forte
Los módulos ignorados aún pueden cargarse manualmente usando el comando modprobe.
Esto sucede normalmento cuando una regla concuerda inesperadamente con un dispositivo. Poe ejemplo, una regla pobremente escrita puede coincidir, en cuanto al vendedor, tanto con un disco SCSI (como se desea) como con el correspondiente dispositivo SCSI genérico (incorrecto). Encuentra la regla erronea y hazla más específica.
Se asume que el controlador ha sido compilado estáticamente dentro del núcleo o que ya ha sido cargado como módulo, y que ya has comprobado que Udev no crea un dispositivo equivocado.
Udev no tiene la información necesaria para crear un nodo de
dispositivo si un controlador del núcleo no exporata sus datos a
sysfs
. Este es el caso más común
con controladores externos al árbol del núcleo. Crea un nodo de
dispositivo estático en /lib/udev/devices
con los números mayor/menor
apropiados (mira el fichero devices.txt
en la documentación del núcleo o la
documentación proporcionada por el distribuidor del controlador
externo). El nodo de dispositivo estático será copiado a
/dev
por el guión de arranque
S10udev.
Esto se debe al hecho de que Udev, por diseño, maneja los uevent y la carga de módulos en paraleo, y por tanto en un orden impredecible. Esto nunca será “fijado”. No deberías confiar en que los nombres de dispositivos del núcleo sean estables. En su lugar, crea tus propias reglas para crear enlaces simbólicos con nombres estables basadas en algún atributo estable del dispositivo, como un número de serie o la salida de las diversas utilidades *_id instaladas por Udev. Mira los ejemplos en Sección 7.12, “Crear enlaces simbólicos persnalizados a los dispositivos” y Sección 7.13, “Configuración del guión network”.
En los siguientes sitios hay documentación de ayuda adicional:
Una implementación de devfs
en espacio de usuario
http://www.kroah.com/linux/talks/ols_2003_udev_paper/Reprint-Kroah-Hartman-OLS2003.pdf
FAQ de Udev http://www.kernel.org/pub/linux/utils/kernel/hotplug/udev-FAQ
El sistema de ficheros sysfs
http://www.kernel.org/pub/linux/kernel/people/mochel/doc/papers/ols-2005/mochel.pdf