Udev is the device manager for the Linux kernel. Udev dynamically creates or removes device node files at boot time in the /dev directory for all types of devices. Udev is now part of systemd as you can see by viewing the “udev” file names included with the systemd RPM package.
# rpm -ql systemd | grep udev /etc/udev /etc/udev/hwdb.bin /etc/udev/rules.d /etc/udev/udev.conf /usr/bin/udevadm ...
The Udev daemon, systemd-udevd, receives device uevents directly from the kernel whenever a device is added or removed from the system. For every event, systemd-udevd executes matching instructions specified in Udev rules.
Device file names can change when disks are removed from the system due to failure. For example, devices are named /dev/sda, /dev/sdb, and /dev/sdc at boot time. But on the next reboot, /dev/sdb fails and what was previously /dev/sdc is named /dev/sdb. Any configuration references to /dev/sdb now contain content originally referenced by /dev/sdc.
The solution to avoid this type of situation is to guarantee consistent names for devices through reboots. You can configure Udev to create persistent names and use these names in the file system mount table, /etc/fstab, or as an argument to the mount command.
Udev Rule Files and Directories
Udev rules determine how to identify devices and how to assign a name that is persistent through reboots or disk changes. When Udev receives a device event, it matches the configured rules against the device attributes in sysfs to identify the device. Rules can also specify additional programs to run as part of device event handling.
Udev rules files are located in the following directories:
/lib/udev/rules.d/
– The default rules directory/etc/udev/rules.d/
– The custom rules directory. These rules take precedence.
Rules files need to have unique names. Files in the custom rules directory override files of the same name in the default rules directory. Rules files are sorted and processed in lexical order. The following is a partial listing of rules files from the default and custom rules directories:
# ls -l /lib/udev/rules.d/ total 348 -r--r--r--. 1 root root 7266 Aug 5 2017 10-dm.rules -r--r--r--. 1 root root 2454 Aug 5 2017 11-dm-lvm.rules -rw-r--r--. 1 root root 2865 Jan 25 16:05 11-dm-mpath.rules -r--r--r--. 1 root root 1499 Aug 5 2017 13-dm-disk.rules -rw-r--r--. 1 root root 553 Aug 6 2017 39-usbmuxd.rules -rw-r--r--. 1 root root 1622 Mar 7 13:27 40-redhat.rules ...
# ls -l /etc/udev/rules.d/ total 8 -rw-r--r--. 1 root root 709 Aug 4 2017 70-persistent-ipoib.rules -rw-r--r--. 1 root root 96 Apr 21 05:09 70-persistent-net.rules lrwxrwxrwx. 1 root root 9 Sep 29 2014 80-net-name-slot.rules -> /dev/null
Sample Udev Rules
Below example contains selected entries from the /lib/udev/rules.d/50-udev-default.rules file. This rules file contains over 60 entries.
# cat /lib/udev/rules.d/50-udev-default.rules # do not edit this file, it will be overwritten on update SUBSYSTEM=="virtio-ports", KERNEL=="vport*", ATTR{name}=="?*", SYMLINK+="virtio-ports/$attr{name}" # select "system RTC" or just use the first one SUBSYSTEM=="rtc", ATTR{hctosys}=="1", SYMLINK+="rtc" SUBSYSTEM=="rtc", KERNEL=="rtc0", SYMLINK+="rtc", OPTIONS+="link_priority=-100" SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", IMPORT{builtin}="usb_id", IMPORT{builtin}="hwdb --subsystem=usb" SUBSYSTEM=="input", ENV{ID_INPUT}=="", IMPORT{builtin}="input_id" ENV{MODALIAS}!="", IMPORT{builtin}="hwdb --subsystem=$env{SUBSYSTEM}" ACTION!="add", GOTO="default_permissions_end" SUBSYSTEM=="tty", KERNEL=="ptmx", GROUP="tty", MODE="0666" SUBSYSTEM=="tty", KERNEL=="tty", GROUP="tty", MODE="0666" SUBSYSTEM=="tty", KERNEL=="tty[0-9]*", GROUP="tty", MODE="0620" SUBSYSTEM=="tty", KERNEL=="sclp_line[0-9]*", GROUP="tty", MODE="0620" SUBSYSTEM=="tty", KERNEL=="ttysclp[0-9]*", GROUP="tty", MODE="0620" ....
The selected entries assist in describing the syntax of the rules files.
1. Comments begin with a # sign.
2. Each non-commented line in a rules file consists of a list of one or more key-value pairs separated by a comma. There are two types of keys:
Match keys
Assignment keys
3. If all match keys match their respective value, the rule gets applied and the assignment keys are assigned the specified value. Each key has a distinct operation, depending on the operator. Valid operators are:
- == : Compare for equality
- != : Compare for inequality
- = : Assign a value to a key
- += : Add the value to the current values for the key
- := : Assign the final value to the key. Disallow any later changes by any later rules.
4. Shell-style pattern matching (*, ?, []) is also supported in Udev rules.
Match Keys
The following key names are used to match against device properties. Some of the keys also match against properties of the parent devices in sysfs, and not just the device that has generated the event. If multiple keys are specified in a single rule, all these keys must match.
- ACTION: Match the name of the event action.
- DEVPATH: Match the devpath of the event device.
- KERNEL: Match the name of the event device.
- NAME: Match the name of a network interface. It can be used if the NAME key was set in one of the preceding rules.
- SYMLINK: Match the name of the symlink targeting the node. It can be used if a SYMLINK key was set in one of the preceding rules. There can be multiple symlinks but only one needs to match.
- SUBSYSTEM: Match the subsystem of the event device.
- TEST{octal mode mask}: Test the existence of a file. You can specify the octal mode mask.
Other match keys include DRIVER, ATTR{filename}, KERNELS, SUBSYSTEMS, DRIVERS, ATTRS{filename}, TAGS, ENV{key}, TAG, PROGRAM, and RESULT.
Assignment Keys
The following keys can have values assigned to them:
- NAME – The name to use for a network interface. The name of a device node cannot be changed by Udev, only additional symlinks can be created.
- SYMLINK – The name of the symlink targeting the node
- OWNER, GROUP, MODE – The permissions for the device node
- OPTIONS – Rule and device options. The ignore_remove option used in the example means “Do not remove the device node when the device goes away.”
Other assignment keys include ATTR{key}, ENV{key}, TAG, RUN{type}, LABEL, GOTO, IMPORT{type}, WAIT_FOR, and OPTIONS.
String Substitutions
The NAME, SYMLINK, PROGRAM, OWNER, GROUP, MODE, and RUN keys support many printf- like string substitutions. The substitutions used in the example are:
- %M – The kernel major number for the device
- %m – The kernel minor number for the device
Additional string substitutions are supported. Refer to the udev man page for all supported substitutions and details on additional match keys, additional assignment keys, and additional rule and device options.
udevadm Utility
The udevadm utility is a userspace management tool for Udev. Among other functions, you can use udevadm to query sysfs and obtain device attributes to help in creating Udev rules that match a device. To display udevadm usage:
# udevadm --help udevadm [--help] [--version] [--debug] COMMAND [COMMAND OPTIONS] Send control commands or test the device manager. Commands: info Query sysfs or the udev database trigger Request events from the kernel settle Wait for pending udev events control Control the udev daemon monitor Listen to kernel and udev events test Test an event run test-builtin Test a built-in command
You can also obtain usage for each of the udevadm commands. For example, to get help on using the info command:
# udevadm info --help udevadm info [OPTIONS] [DEVPATH|FILE] Query sysfs or the udev database. -h --help Print this message --version Print version of the program -q --query=TYPE Query device information: name Name of device node symlink Pointing to node path sysfs device path property The device properties all All values -p --path=SYSPATH sysfs device path used for query or attribute walk -n --name=NAME Node or symlink name used for query or attribute walk -r --root Prepend dev directory to path names -a --attribute-walk Print all key matches walking along the chain of parent devices -d --device-id-of-file=FILE Print major:minor of device containing this file -x --export Export key/value pairs -P --export-prefix Export the key name with a prefix -e --export-db Export the content of the udev database -c --cleanup-db Clean up the udev database
Example of udevadm utility
Some examples follow. To query the Udev database for the device path of /dev/xvdd:
# udevadm info --query=path --name=/dev/xvdd /devices/vbd-5696/block/xvdd
To query the Udev database for all device information for /dev/xvda:
# udevadm info --query=all --name=/dev/xvda P: /devices/vbd-768/block/xvda N: xvda E: DEVNAME=/dev/xvda E: DEVPATH=/devices/vbd-768/block/xvda E: DEVTYPE=disk E: DM_MULTIPATH_TIMESTAMP=1524287355 E: ID_PART_TABLE_TYPE=dos E: MAJOR=202 E: MINOR=0 E: MPATH_SBIN_PATH=/sbin E: SUBSYSTEM=block E: TAGS=:systemd: E: USEC_INITIALIZED=476119
Enter the following to print all sysfs properties of /dev/xvda. These properties can be used in Udev rules to match the device. It prints all devices along the chain, up to the root of sysfs.
# udevadm info --attribute-walk --name=/dev/xvda Udevadm info 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 '/devices/vbd-768/block/xvda': KERNEL=="xvda" SUBSYSTEM=="block" DRIVER=="" ATTR{ro}=="0" ATTR{size}=="41943040" ATTR{stat}==" 16775 4 686095 36372 2953 313 203104 42044 0 19603 78392" ATTR{range}=="16" ATTR{discard_alignment}=="0" ATTR{ext_range}=="16" ATTR{alignment_offset}=="0" ATTR{badblocks}=="" ATTR{inflight}==" 0 0" ATTR{removable}=="0" ATTR{capability}=="10" looking at parent device '/devices/vbd-768': KERNELS=="vbd-768" SUBSYSTEMS=="xen" DRIVERS=="vbd" ATTRS{devtype}=="vbd" ATTRS{nodename}=="device/vbd/768"
Creating a Symbolic Link to a Device Node
The order in which rules are evaluated is important. When creating your own rules, you want these evaluated before the defaults. Because rules are processed in lexical order, create a rules file with a file name such as /etc/udev/rules.d/10-local.rules for it to be processed first.
The following rule creates the /dev/my_disk symbolic link to the /dev/xvdd device node. You can create a Udev rule to change the name of a network interface but the name of a device node cannot be changed by Udev. Only additional symlinks can be created for device nodes.
KERNEL=="xvdd", SUBSYSTEM=="block", SYMLINK="my_disk"
Run udevadm trigger to process the rules files:
# udevadm trigger
The symlink now exists.
# ls –l /dev/my* lrwxrwxrwx. ... /dev/my_disk -> xvdd
Remove the 10-local.rules file and run udevadm trigger to remove the symlink.