What is udev and how do you write custom udev rules in systemd environments (RHEL 7 and later) ?
Environment
- Red Hat Enterprise Linux 9
- Red Hat Enterprise Linux 8
- Red Hat Enterprise Linux 7
- udev
For systemv(RHEL 6 and earlier), see What is udev and how do you write custom udev rules is systemv environment (RHEL 6 and earlier)?
Issue
- What is udev and how do you write custom udev rules?
- How to add/create a customer device file through udev?
- Udev rules to create ASM devices in RHEL7 and later
- How to write an udev rule to change parameters like nr_request and/or to change the I/O scheduler of a device?
- Configuring persistent names for tape devices using udev
Resolution
- Udev is the mechanism used to create and name
/devdevice nodes corresponding to the devices that are present in the system. Udev uses matching information provided bysysfswith rules provided by the user to dynamically add the required device nodes.
Debugging udev Rules - How to turn on debugging in udev in Red Hat Enterprise Linux?
Writing udev Rules
Udev rule files are kept in the /etc/udev/rules.d/ directory.
Files in /etc/udev/rules.d/ are parsed in lexical order, and in some circumstances, the order in which rules are parsed is important.
The basic format of a rule is:
key1="value", key2="value", ... keyN="value", name="value", symlink="value"
At least one key and a name must be provided. Extra keys are optional, but all must match for the rule to be applied.
In order to find the "key" to use, we could use the udevadm command seen below. This is for an example dm-2 device
[root@host ~]# multipath -ll
mpathc (1234567890abcdefghijklmnopqrstuvwxyz) dm-2 IET,VIRTUAL-DISK
size=10G features='0' hwhandler='0' wp=rw
|-+- policy='round-robin 0' prio=1 status=active
| `- 3:0:0:1 sdb 8:16 active ready running
`-+- policy='round-robin 0' prio=1 status=enabled
`- 4:0:0:1 sdc 8:32 active ready running
[root@host ~]# udevadm info --query=all --path=/devices/virtual/block/dm-2/
P: /devices/virtual/block/dm-2
N: dm-2
L: 10
W: 71
S: mapper/mpathc
S: disk/by-id/dm-name-mpathc
S: disk/by-id/dm-uuid-mpath-1234567890abcdefghijklmnopqrstuvwxyz
S: block/253:2
E: UDEV_LOG=3
E: DEVPATH=/devices/virtual/block/dm-2
E: MAJOR=253
E: MINOR=2
E: DEVNAME=/dev/dm-2
E: DEVTYPE=disk
E: SUBSYSTEM=block
E: DM_SBIN_PATH=/sbin
E: DM_UDEV_PRIMARY_SOURCE_FLAG=1
E: DM_NAME=mpathc
E: DM_UUID=mpath-1234567890abcdefghijklmnopqrstuvwxyz
E: DM_SUSPENDED=0
E: DM_UDEV_RULES_VSN=1
E: ID_PART_TABLE_TYPE=dos
E: MPATH_SBIN_PATH=/sbin
E: UDISKS_PRESENTATION_NOPOLICY=1
E: UDISKS_DM_TARGETS_COUNT=1
E: UDISKS_DM_TARGETS_TYPE=multipath
E: UDISKS_DM_TARGETS_START=0
E: UDISKS_DM_TARGETS_LENGTH=20971520
E: UDISKS_PARTITION_TABLE=1
E: UDISKS_PARTITION_TABLE_SCHEME=mbr
E: UDISKS_PARTITION_TABLE_COUNT=0
E: DEVLINKS=/dev/mapper/mpathc /dev/disk/by-id/dm-name-mpathc /dev/disk/by-id/dm-uuid-mpath-1234567890abcdefghijklmnopqrstuvwxyz /dev/block/253:2
For tape devices, use
# udevadm info --query=all --path=/class/scsi_tape/st0
Any of the lines beginning with E: can be used as a qualifier in the udev rule, such as ENV{UDISKS_DM_TARGETS_TYPE}="multipath". With this new udev rule in place, the device permissions should be applied to the /dev/dm-X device as configured.
ACTION=="add|change", ENV{DM_UUID}=="mpath-1234567890abcdefghijklmnopqrstuvwxyz", GROUP="examplegroup", OWNER="exampleuser", MODE="0660"
If we could not check the multipath item from the output of udevadm info --query=all --path=, we should remove the ENV{DM_UUID}=="mpath-1234567890abcdefghijklmnopqrstuvwxyz" parameter from the above rule.
NOTE: The symlink in /dev/mapper/ will not have these permissions applied. However, the permissions on the symlink target controls which users can access the symlink.
For devices that do not use device mapper, we could use
# udevadm info --query=all --path=/block/sdb
In order to load the udev rule(s) without rebooting the system, execute
# /sbin/udevadm control --reload-rules
# /sbin/udevadm trigger --type=devices --action=change
Creating a device file through udev
# cd /etc/udev/rules.d/
# ls
98-kexec.rules 99-myrules.rules
# cat 99-myrules.rules
ACTION=="add", RUN+="/bin/sh -c 'mknod /dev/cs2 c 244 0 ; chmod 666 /dev/cs2'"
# udevadm trigger <<<< to execute the above rule. To make udev daemon aware of the above rule
Verify that the device has been created.
# ls -l /dev/cs2
crw-rw-rw-. 1 root root 244, 0 Mar 15 20:52 /dev/cs2
If this works for you, then rebooting the system should also create the /dev/cs2 device.
How to create ASM devices in RHEL7 using udev
Make sure you have created a desired user and group and also the directory location where you need the SYMLINK to reside.
create a file similar to cat /etc/udev/rules.d/99-oracle-asmdevices.rules
ACTION=="add|change", ENV{ID_SERIAL}=="QEMU_HARDDISK_QM00007", SYMLINK+="oracleasm/disk1", OWNER="oracle", GROUP="dba", MODE="0660"
OR
KERNEL=="sd*", SUBSYSTEM=="block", ENV{DEVTYPE}=="disk", ENV{ID_SERIAL}=="QEMU_HARDDISK_QM00007", SYMLINK+="oracleasm/disk1", \ OWNER="oracle", GROUP="dba", MODE="0660"
Any of the above rule should work.
Here ENV{ID_SERIAL} is taken from the output of the command
udevadm info --query=all --name=<full_path_of_device>
Any of the lines beginning with E: can be used as a qualifier in the udev rule, such as ENV{UDISKS_DM_TARGETS_TYPE}="multipath". With this new udev rule in place, the device permissions should be applied to the /dev/dm-X device as configured.
If we could not check the multipath item from the output of udevadm info --query=all --path=, we should remove the ENV{DM_UUID}=="mpath-1234567890abcdefghijklmnopqrstuvwxyz" parameter from the 96-multipath.rules file.
In order to reload the udev rules, please see How to reload "udev rules" without restarting udev service?
How to write an udev rule to change parameters like nr_request and/or to change the I/O scheduler of a device?
SUBSYSTEM!="block", GOTO="end_rule"
ENV{DEVTYPE}=="partition", GOTO="end_rule"
ACTION!="add|change", GOTO="end_rule"
KERNEL=="sd*", ATTR{queue/scheduler}="deadline", ATTR{queue/nr_requests}="1024"
LABEL="end_rule"
In this case, setting nr_requests for all sd devices to 1024 and setting I/O scheduler as deadline
How to write an udev rule to create persistent name for tape devices
Example :
preferred :
ACTION=="add|change", KERNEL=="nst[0-9]*", SUBSYSTEM=="scsi_tape", ENV{ID_SERIAL}=="351402ec011xxxxxx", SYMLINK+="tape_devices/mytape_LTO9_1.2.1"
OR
ACTION=="add|change",KERNEL=="nst*", PROGRAM=="/sbin/scsi_id --whitelisted --replace-whitespace --device=%N", RESULT=="350012340140c7f9a", SYMLINK="rmt-test0"
In this case mytape_LTO9_1.2.1 would be persistent name for the tape drive with IS_SERIAL as "351402ec011xxxxxx" and rmt-test0 would be the persistent name for tape device with WWID "350012340140c7f9a".
This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.