Translation(s): English - Français - Italiano - Português (Brasil) - Русский
The udev daemon manages the /dev filesystem. It allows you to identify devices based on their properties, such as vendor ID or device ID, dynamically. It runs in userspace and was introduced in Linux 2.6.
Contents
Overview
The udev system is composed of some kernel services and the udevd daemon. The kernel informs the daemon when hardware-related events happen. The daemon responds to events with appropriate actions, which happen in userspace, based on configurable udev "rules". The userspace udev functionality is implemented by the systemd-udevd.service
udev uses rules to determine what device name is given to each piece of hardware. This means device get the same name, regardless of which port they are plugged into. For example, a rule may say that a hard drive with manufacturer "iRiver" and device code "ABC" is always mounted as /dev/iriver. Consistent naming of devices guarantees that scripts dependent on a specific device's existence will not be broken.
At startup, udev reads its configuration and rule files into memory. When an event happens, it checks its rule database and performs the appropriate actions: although some documents focus on creating devices in response to new devices that have appeared ("hotplugging"), udev rules can be more general: udev can run arbitrary userspace commands in response to various events it receives from the kernel. (give an example of this?)
Configuration
Where rules are read from
The main configuration file is in /etc/udev/udev.conf, and rules are read from /run/udev/rules.d, /etc/udev/rules.d and /lib/udev/rules.d: If a file with the same basename is present in more than one of these directories the later versions are be ignored. The idea is that packages should install rules in /lib/udev/rules.d), and the administrator can overrides these by putting files in /etc (or /run for temporary experiments).
Rules are read in alphabetical order, and must end with ".rules".
When the config file or rules files are changed, the udevadm program should be used to instruct systemd-udevd to reload the rules (see below).
Rules syntax
Rules for rules:
rules contain one line (lines can be broken with a \ before a newline)
- rules consist of "matches" and "actions"
- matches and actions are "key" "operator" "value" triplets
- matches have == or != for operator
- actions have = (assignment) for operator
- matches check one or more attributes of the event to see if the action will be applied
- actions specify what will happen
example match: BUS=="usb"
example action: NAME="mydev"
example rule:
KERNEL=="sd*[0-9]|dasd*[0-9]", ENV{ID_SERIAL}=="?*", \ SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}-part%n"- all matching rules will fire
- earlier rules have precedence over later rules - so put your customizations early in the rules.d file list
- actions like key="value" override
actions like key+="value" add to the actions that are executed, eg SYMLINK+="foo" means "in addition to any other symlinks you were going to make for this event, also make one called foo"
Rule sets
Rules for rule sets:
- All the rules are in one big rule space, although they are divided into several files.
The only organization in the rule space is the ability to set labels, and then to skip a bunch of rules during "match this event to rules" time by jumping forward with a GOTO action.
there is one other rule type called a label: eg LABEL="persistent_storage_end" These are used by regular rules that have "GOTO" actions, eg:
ACTION!="add", GOTO="persistent_storage_end"
Note that in this rule, the term ACTION is an attribute of an event and is being used as a condition for deciding if the GOTO action will be triggered.- It is polite to keep GOTOs to jump within a file (or you will have to worry about reordering the files)
- Don't jump backwards to a label (didn't try it, but imagine it might end in an infinite loop? Maybe the udev code checks for that - but if it's going to be ignored (at best) why bother?)
- You can set variables in ENV space in earlier rules and refer to them with later rules
The facility for dynamic rule creation exists (example: see z45_persistent-net-generator.rules)
Blacklisting
Example: persistent device naming
In this example, we make sure a 3G card gets a persistent name.
1. Plug in the "card" (or device).
We assume this is recognised as /dev/ttyS1.
2. Find udev attributes using udevadm
udevadm starts with the device specified (here /dev/ttyS1) and walks up the chain of parent devices. It prints, for every device found, all possible attributes in the udev rules format.
A rule to match the device can then be created using the attributes of the device and one of its parents.
$ udevadm info --name=/dev/ttyS1 --attribute-walk looking at device '/class/tty/ttyS1': KERNEL=="ttyS1" SUBSYSTEM=="tty" DRIVER=="" ATTR{dev}=="4:65" looking at parent device '/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/0.0': KERNELS=="0.0" SUBSYSTEMS=="pcmcia" DRIVERS=="serial_cs" ATTRS{modalias}=="pcmcia:m00A4c1AAFf02fn00pfn00pa32607776pbD9E73B13pcAF9C4D7Fpd00000000" ATTRS{prod_id3}=="NRM6831" ATTRS{prod_id2}=="Merlin UMTS Modem" ATTRS{prod_id1}=="Novatel Wireless" ATTRS{card_id}=="0x1aaf" ATTRS{manf_id}=="0x00a4" ATTRS{func_id}=="0x02" ATTRS{pm_state}=="on" ATTRS{function}=="0x00" looking at parent device '/devices/pci0000:00/0000:00:1e.0/0000:15:00.0': KERNELS=="0000:15:00.0" SUBSYSTEMS=="pci" DRIVERS=="yenta_cardbus" ATTRS{msi_bus}=="1" ATTRS{broken_parity_status}=="0" ATTRS{enable}=="2" ATTRS{numa_node}=="0" ATTRS{modalias}=="pci:v00001180d00000476sv000017AAsd000020C6bc06sc07i00" ATTRS{local_cpus}=="00000003" ATTRS{irq}=="16" ATTRS{class}=="0x060700" ATTRS{subsystem_device}=="0x20c6" ATTRS{subsystem_vendor}=="0x17aa" ATTRS{device}=="0x0476" ATTRS{vendor}=="0x1180" looking at parent device '/devices/pci0000:00/0000:00:1e.0': KERNELS=="0000:00:1e.0" SUBSYSTEMS=="pci" DRIVERS=="" ATTRS{msi_bus}=="1" ATTRS{broken_parity_status}=="0" ATTRS{enable}=="1" ATTRS{numa_node}=="0" ATTRS{modalias}=="pci:v00008086d00002448sv00000000sd00000000bc06sc04i01" ATTRS{local_cpus}=="00000003" ATTRS{irq}=="0" ATTRS{class}=="0x060401" ATTRS{subsystem_device}=="0x0000" ATTRS{subsystem_vendor}=="0x0000" ATTRS{device}=="0x2448" ATTRS{vendor}=="0x8086" looking at parent device '/devices/pci0000:00': KERNELS=="pci0000:00" SUBSYSTEMS=="" DRIVERS=="" ATTRS{uevent}==""
3. Create a rules file in /etc/udev/rules.d
Typically you would name this file z21_persistent-local.rules:
ATTRS{prod_id2}=="Merlin UMTS Modem", ATTRS{prod_id1}=="Novatel Wireless", SYMLINK+="MerlinUMTS" ## Alternatively we could use : # ATTRS{card_id}=="0x1aaf", ATTRS{manf_id}=="0x00a4", SYMLINK+="MerlinUMTS"
4. Tell udev to reload its rules (or you can reboot):
udevadm control --reload-rules udevadm test -a -p $(udevadm info -q path -n /dev/ttyS1)
See also
semu5 on comp.os.linux.questions for a more detailed example
http://reactivated.net/writing_udev_rules.html - Writing udev rules
CategorySystemAdministration | CategoryBootProcess | CategoryHardware
