Development/Docs/Udev
From Mandriva Community Wiki
udev is a userspace implementation of devfs and replacement for hotplug
Contents |
[edit] Summary
udev is an implementation of devfs/devfsd in userspace using sysfs. Like devfs, udev dynamically creates and removes device nodes from /dev/. It requires a 2.6 kernel to run properly.
It also replaces the hotplug package, which contains scripts run on kernel events. Needed scripts to migrate from hotplug to udev have been developed : hotplug agents are replaced by udev rules, usermaps have been implemented when needed and coldplug support has been added into udev to avoid duplication of functionalities in initscripts.
[edit] Why switch to udev?
devfs was unmaintained.
hotplug used to run slow shell scripts on each event, even if the event didn't need to be caught.
The fact that udev now uses target rules (and being a C program rather than shell scripts) makes it faster than previously with hotplug, BTW it greatly reduces the boot time as well.
[edit] A replacement for hotplug
[edit] Cold plug
udev can now manage hotplug and coldplug for many buses (pci/usb/). Previously, we loaded the usb controllers using the usb service, and we didn't use the hotplug service. So, cold plug is enabled for USB controllers and devices only in udev, and the "usb" service is run by rc.sysinit only for 2.4 kernels.
This feature is implemented in udevstart, in which we added cold plug for PCI and USB buses. PCI coldplug is needed for USB controllers. USB coldplug is needed when the USB controllers have already been loaded from the initrd.
This feature is probably better done in udevsynthetize, but it was quite late to include a new program at this stage of 2006 development, while our small udevstart patch could be easily tested.
udevstart is started by the udev service really early in the boot, before any other service is run actually.
[edit] Hot plug: modules loading
USB and PCI hotplug are also managed by udev, which can load the modules and run scripts on the fly. It loads the modules by using the modalias parameter and their matching kernel module from /lib/modules/`uname -r`/modules.alias
The modalias value can be found in sysfs, it looks like this:
pci:v00008086d000024D1sv00001043sd000080A6bc01sc01i8f
[edit] Hot plug: driver specific agents
A helper has been added to run old hotplug agents named this way: /etc/hotplug/<subsystem>/<driver> It is run automatically for USB modules having a modalias.
The /etc/hotplug directory will be removed, so if an agent has to be run after a device is detected, it should now be moved to /etc/udev/agents.d/<subsystem>/<driver> The helper will now use this path.
[edit] Hot plug: usermaps
A useful feature in hotplug was the usermap support, it allowed to load modules or run scripts using USB characteristics, even if they weren't referenced by a kernel module. They were loaded by the usb agent of hotplug, which is disabled now because we manage hotplugging in udev. Though, this feature is missing in udev.
To solve this issue, we wrote the "udev_import_usermap" script to migrate hotplug usermaps (it's in the udev-tools package).
It parses usermaps to write udev rules, which will modprobe the matching module and run the matching driver agent. The driver agent is run automatically only when a modalias is provided by the kernel, that's why the agent needs to be run here.
Please note that if the driver agent only runs one command, it's better to inline it in the udev rule. It will avoid to run the (presumably shell) script /etc/udev/agents.d/<subsystem>/<driver>
This script can be run with options to avoid modprobing or agent running when we know it's unnecessary for the parsed usermap. It would be nice to be able to specify a command line to replace the agent helper path.
Some packages in the main/contrib repositories have to be modified to use udev rules. Only a few of them are still using usermaps.
[edit] Blacklisting automatic modules loading
You are allowed to blacklist automatic module loading by using the following syntax in /etc/modprobe.conf, thanks to the latest module-init-tools package :
blacklist <module name>
It forbids modprobe to load modules when "modprobe <matching modalias>" is used, but still allows "modprobe <module name>".
[edit] Firmware loading
I'll keep /lib/hotplug/firmware for compatibility, so firmwares still have to be present in this directory (/usr/lib/hotplug is a symlink to /lib/hotplug).
[edit] Hotplug package (almost) removed:
This package isn't really useful now. The agent and rc scripts are not used anymore. /etc/hotplug will disappear, it can only entail confusion now.
The only useful remaining data were the prebuilt usermaps, which have been converted to udev rules: /etc/udev/rules.d/70-distmap.rules They've been moved to the udev package, so that we can avoid installing hotplug on a new system. However, some entries of these usermaps may not be useful anymore, they're probably duplicates of the kernel modules.alias file, though they're kept for safety's sake.
[edit] Network devices hot plug
The old net.agent from agent has been moved as /sbin/udev_net_helper. It's still run where network devices are added or removed. It allows to run ifup/ifdown, and create default configuration files if they don't exist yet.
ifup/ifdown are run with the "boot" parameter, so that ifplugd and wpa_supplicant are run if configured.
ACTION=="add", SUBSYSTEM=="net", ENV{INTERFACE}=="*", \ RUN+="/sbin/udev_net_helper" ACTION=="remove", SUBSYSTEM=="net", ENV{INTERFACE}=="*", \ RUN+="/sbin/udev_net_helper"
[edit] Coldplug/hotplug rules
Here are the udev rules to do PCI/USB cold/hot plug, but avoiding to load any PCI drivers (except USB controllers) during cold plug.
# libusb device access (mount usbfs or usbdev nodes) DEVPATH=="/module/usbcore", ACTION=="add", \ RUN+="/bin/sh -c 'sleep 1; /bin/mount -t usbfs -o \ devmode=0664,devgid=43 none /proc/bus/usb'" # allow pci cold plug for usb controllers \ only # alias pci:v*d*sv*sd*bc0Csc03i10* ohci-hcd # alias pci:v*d*sv*sd*bc0Csc03i20* ehci-hcd # alias pci:v*d*sv*sd*bc0Csc03i00* uhci-hcd ACTION=="add", SUBSYSTEM=="pci", ENV{UDEV_START}=="1", \ SYSFS{class}!="0x0c0300", \ SYSFS{class}!="0x0c0310", \ SYSFS{class}!="0x0c0320", \ OPTIONS="ignore_device" # modprobe on hot plug (and cold plug, which is processed by udevstart) ACTION=="add", SUBSYSTEM=="pci", MODALIAS=="*", \ RUN+="/sbin/modprobe $modalias" ACTION=="add", SUBSYSTEM=="usb", MODALIAS=="*", \ RUN+="/sbin/modprobe $modalias" ACTION=="add", SUBSYSTEM=="usb", MODALIAS=="*", \ RUN+="/sbin/udev_agent_helper"