udev — Linux dynamic device management
udev is a replacement for the Device File System (DevFS) starting with the Linux 2.6 kernel series. It allows you to identify devices based on their properties, like vendor ID and device ID, dynamically. udev runs in userspace (as opposed to devfs which was executed in kernel space).
udev allows for rules that specify what name is given to a device, regardless of which port it is plugged into. For example, a rule to always mount a hard drive with manufacturer «iRiver» and device code «ABC» as /dev/iriver is possible. This consistent naming of devices guarantees that scripts dependent on a specific device’s existence will not be broken.
Overview
The udev system is composed of some kernel services and the udevd daemon. The kernel informs the udevd daemon when certain events happen. The udevd daemon is configured to respond to events with corresponding actions. The event information comes from the kernel — the actions happen in userspace. The responses to the events are configurable in «rules».
The userspace udev functionality is implemented by the systemd-udevd.service Its config file is in /etc/udev/udev.conf. The rules files (which amount to more configuration for udevd) are taken from /run/udev/rules.d, /etc/udev/rules.d or /lib/udev/rules.d. Packages install rules in /lib/udev/rules.d), while the /etc and /run locations provide a facility for the administrator to override the behavior of a package-provided rule. If a file with the same name is present in more than one of these directories then the latter(s) file will be ignored. Files in there are parsed in alpha order, as long as the name ends 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).
udev was created to respond to hotplug type of events. Much documentation refers to creating devices in response to new devices that have appeared. But, udev is more general; it can run arbitrary userspace commands in response to a new device appearing — or to whatever events it receives from the kernel.
- at startup, it parses all the config files and rule files and builds a rules database in memory.
- When an event happens, it checks its rule database and performs the appropriate actions.
Rules
- rules are all on one line (lines can be broken with \ just before 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*2|dasd*8", ENV=="?*", \ SYMLINK+="disk/by-id/$env-$env-part%n"
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"
Blacklisting
Persistent Device name
In this example, we want to make sure your 3G card get a persistent name.
1. Plug the «card» (or device)
2. run the following command, on the proper device;
$ udevadm info --name=/dev/ttyS1 --attribute-walk
udevadm starts with the device specified by the devpath and then walks up the chain of parent devices. It prints for every device found, all possible attributes in the udev rules key format. A rule to match, can be composed by the attributes of the device and the attributes from one single parent device.
looking at device '/class/tty/ttyS1': KERNEL=="ttyS1" SUBSYSTEM=="tty" DRIVER=="" ATTR=="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=="pcmcia:m00A4c1AAFf02fn00pfn00pa32607776pbD9E73B13pcAF9C4D7Fpd00000000" ATTRS=="NRM6831" ATTRS=="Merlin UMTS Modem" ATTRS=="Novatel Wireless" ATTRS=="0x1aaf" ATTRS=="0x00a4" ATTRS=="0x02" ATTRS=="on" ATTRS=="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=="1" ATTRS=="0" ATTRS=="2" ATTRS=="0" ATTRS=="pci:v00001180d00000476sv000017AAsd000020C6bc06sc07i00" ATTRS=="00000003" ATTRS=="16" ATTRS=="0x060700" ATTRS=="0x20c6" ATTRS=="0x17aa" ATTRS=="0x0476" ATTRS=="0x1180" looking at parent device '/devices/pci0000:00/0000:00:1e.0': KERNELS=="0000:00:1e.0" SUBSYSTEMS=="pci" DRIVERS=="" ATTRS=="1" ATTRS=="0" ATTRS=="1" ATTRS=="0" ATTRS=="pci:v00008086d00002448sv00000000sd00000000bc06sc04i01" ATTRS=="00000003" ATTRS=="0" ATTRS=="0x060401" ATTRS=="0x0000" ATTRS=="0x0000" ATTRS=="0x2448" ATTRS=="0x8086" looking at parent device '/devices/pci0000:00': KERNELS=="pci0000:00" SUBSYSTEMS=="" DRIVERS=="" ATTRS==""
3. Create a file in /etc/udev/rules.d, typically named z21_persistent-local.rules.
ATTRS=="Merlin UMTS Modem", ATTRS=="Novatel Wireless", SYMLINK+="MerlinUMTS" ## Alternatively we could use : # ATTRS=="0x1aaf", ATTRS=="0x00a4", SYMLINK+="MerlinUMTS"
4. Force re-running the scripts (or reboot ; )
udevadm control --reload-rules udevadm test -a -p $(udevadm info -q path -n /dev/ttyS1)
References
DESCRIPTION
udev supplies the system software with device events, manages permissions of device nodes and may create additional symlinks in the /dev/ directory, or renames network interfaces. The kernel usually just assigns unpredictable device names based on the order of discovery. Meaningful symlinks or network device names provide a way to reliably identify devices based on their properties or current configuration.
The udev daemon, systemd-udevd.service(8), receives device uevents directly from the kernel whenever a device is added or removed from the system, or it changes its state. When udev receives a device event, it matches its configured set of rules against various device attributes to identify the device. Rules that match may provide additional device information to be stored in the udev database or to be used to create meaningful symlink names.
All device information udev processes is stored in the udev database and sent out to possible event subscribers. Access to all stored data and the event sources is provided by the library libudev.
RULES FILES
The udev rules are read from the files located in the system rules directories /usr/lib/udev/rules.d and /usr/local/lib/udev/rules.d, the volatile runtime directory /run/udev/rules.d and the local administration directory /etc/udev/rules.d. All rules files are collectively sorted and processed in lexical order, regardless of the directories in which they live. However, files with identical filenames replace each other. Files in /etc/ have the highest priority, files in /run/ take precedence over files with the same name under /usr/. This can be used to override a system-supplied rules file with a local file if needed; a symlink in /etc/ with the same name as a rules file in /usr/lib/, pointing to /dev/null, disables the rules file entirely. Rule files must have the extension .rules; other extensions are ignored.
Every line in the rules file contains at least one key-value pair. Except for empty lines or lines beginning with «#», which are ignored. There are two kinds of keys: match and assignment. If all match keys match against their values, the rule gets applied and the assignment keys get the specified values assigned.
A matching rule may rename a network interface, add symlinks pointing to the device node, or run a specified program as part of the event handling.
A rule consists of a comma-separated list of one or more key-operator-value expressions. Each expression has a distinct effect, depending on the key and operator used.
Operators
Compare for inequality. (The specified key doesn’t have the specified value, or the specified key is not present at all.)
Assign a value to a key. Keys that represent a list are reset and only this single value is assigned.
Values
Values are written as double quoted strings, such as («string»). To include a quotation mark («) in the value, precede it by a backslash (\»). Any other occurrences of a backslash followed by a character are not unescaped. That is, «\t\n» is treated as four characters: backslash, lowercase t, backslash, lowercase n.
The string can be prefixed with a lowercase e (e»string\n») to mark the string as C-style escaped[1]. For example, e»string\n» is parsed as 7 characters: 6 lowercase letters and a newline. This can be useful for writing special characters when a kernel driver requires them.
Please note that NUL is not allowed in either string variant.
Keys
The following key names can be used to match against device properties. Some of the keys also match against properties of the parent devices in sysfs, not only the device that has generated the event. If multiple keys that match a parent device are specified in a single rule, all these keys must match at one and the same parent device.