最後更新: 2020-02-04
介紹
udev replaces the functionality of hotplug
它負責 device renaming (under /dev 下), set permission, create linking (/dev/hdd_RED3T -> sdd1)
Deamon
ps aux | grep udevd
root 421 0.0 0.0 46068 4944 ? Ss 21:26 0:03 /lib/systemd/systemd-udevd
目錄
- udevadm
- 引發一次更新(rename)
- udev rule
- List attributes of a device
- 即時查看有新 hardware 加入時
- Testing rules before loading
- Rule Eample
- PROGRAM 與 RESULT
- Usage Example
udevadm
It controls the runtime behavior of udev, requests kernel events, manages the event queue,
and provides simple debugging mechanisms.
Sub command:
- trigger
- info
- monitor
- test
Version
udevadm --version
204
引發一次更新(rename) - trigger
trigger - replay events at system coldplug time
# Trigger All Device
udevadm trigger
udev: renamed network interface eth1 to eth0
# Trigger 個別 Device
udevadm trigger --attr-match=ATTR{address}=="52:54:00:f1:68:0b"
udev rule
* All the rules are in one big rule space, although they are divided into several files.
udevd processes the rules files in lexical order, regardless of which directory they are located.
- /etc/udev/rules.d
- /lib/udev/rules.d (Default Rule)
lexical order:
- xx-descriptive-name.rules
99 是最尾那個
if you want to prevent an assignment being overriden by default rules, use the := operator.
當修改了 Rule 後, 就要 reload 話比 udevd 知才生效
udevadm control --reload-rules
udev rules multiple lines
ACTION=="add", SUBSYSTEMS=="block" \ , ENV{ID_MODEL}=="ST500DM002-1BD142" \ , ENV{PARTN}=="1" \ , ENV{ID_FS_TYPE}=="ext4" \ , SYMLINK+="disk/bakdisk-500g"
List attributes of a device - info
info - Queries the udev database (query the properties of a device)
usage
udevadm info [-q type] [-a] -n [device name]
opts
-q => --query [ name / symlink / path / property / all ]
-p, --path=DEVPATH # The /sys path of the device to query (i.e. [/sys]/class/block/sda)
-a => --attribute-walk # Print all sysfs properties of the specified device
# print all key matches while walking along the chain of parent devices
-n => --name=<name> # identify the specified device (name / symlink used for query or attribute walk)
i.e.
udevadm info /dev/sde # 相當於 "-q all"
P: /devices/pci0000:00/0000:00:11.0/ata5/host4/target4:0:0/4:0:0:0/block/sde N: sde S: disk/by-id/ata-ST500DM002-1BD142_W3T6QNF5 ...
remark
output (--query=type)
N: is for device name in /dev S: is for symlinks to that device name in /dev P: is for device path in /sys E: is for device properties in udev
udevadm info -q property /dev/sde
DEVLINKS=/dev/disk/by-path/pci-0000:00:11.0-ata-5 /dev/disk/by-id/ata-ST500DM002-1BD142_W3T6QNF5 /dev/disk/by-id/wwn-0x5000c50073bab306 DEVNAME=/dev/sde ...
udevadm info -p /sys/class/net/eth0
udevadm info -a /dev/sda
looking at device '/devices/pci0000:00/0000:00:11.0/ata1/host0/target0:0:0/0:0:0:0/block/sda': ... ATTR{removable}=="0" ATTR{ro}=="0" ATTR{size}=="5860533168" ... looking at parent device '/devices/pci0000:00/0000:00:11.0/ata1/host0/target0:0:0/0:0:0:0': ... looking at parent device '/devices/pci0000:00/0000:00:11.0/ata1/host0/target0:0:0': ... looking at parent device '/devices/pci0000:00/0000:00:11.0/ata1/host0': ... looking at parent device '/devices/pci0000:00/0000:00:11.0/ata1': ... looking at parent device '/devices/pci0000:00/0000:00:11.0': ... looking at parent device '/devices/pci0000:00': KERNELS=="pci0000:00" SUBSYSTEMS=="" DRIVERS==""
即時查看有新 hardware 加入時
monitor will print the received events for:
* devpath of the event
- UDEV - the event which udev sends out after rule processing
- KERNEL - the kernel uevent
i.e.
udevadm monitor [--udev] # 加入 "--udev" 即是只看 "UDEV" 所做的事
UDEV [5189977.155707] remove /devices/pci0000:00/0000:00:1d.0/usb4/4-1/4-1.4 (usb)
KERNEL[5189982.563502] add /devices/pci0000:00/0000:00:1d.0/usb4/4-1/4-1.4 (usb)
Testing rules before loading
test: Simulate a udev event run for the given device, and print debug output.
udevadm test [options] devpath
usage
# 不能用 /dev/sdd 去做 devpath
udevadm test /sys/block/sdd
... Reading rules file: /etc/udev/rules.d/80-disk.rules invalid key/value pair in file /etc/udev/rules.d/80-disk.rules on line 5, starting at character 36 ('#') hint: comments can only start at beginning of line Reading rules file: /lib/udev/rules.d/80-drivers.rules ...
OR
/dev/sdd1 不是 devpath 來
udevadm info -q path /dev/sdd1
/devices/pci0000:00/0000:00:10.1/usb9/9-2/9-2:1.0/host11/target11:0:0/11:0:0:0/block/sdd/sdd1
# Debug with 2>&1
udevadm test '/devices/pci...' 2>&1 | less
Rule Eample
ACTION
單一個 Action: ACTION="add"
兩個 Action: ACTION=="add|change"
Action
- add
- remove
符號
- == #
- != #
- += # add to the actions that are executed
- := # Assign a value to a key finally;
設定名字
NAME
設定這 device 的名稱 (udev only creates one true device node for one device)
SYMLINK+="..."
當 Device 被 remove 時, 那 link 亦會被移除
%n
Will expand to the partition number.
For example, if the device has two partitions, two "DEV" will be created.
LABEL & GOTO
Label <- Rule type
e.g.
LABEL="persistent_storage_end" These are used by regular rules that have "GOTO" actions
用一個 rule file
ACTION!="add", .... , GOTO="persistent_storage_end" .... LABEL="persistent_storage_end"
Match 的條件設定
DRIVER="..."
DRIVERS=="sd"
KERNEL="..."
KERNEL=="sde"
SUBSYSTEM="..."
SUBSYSTEM=="block"
ATTR{filename}
Match sysfs attribute values of the event device.
ATTRS{filename}
Search the devpath upwards for a device with matching sysfs attribute values.
ENV{key}
Match against a device property value
RUN
行 program 或 script. 它們要用 full path (/usr/bin/touch)
* udev 執行程式時是沒有 tty 可用的
ACTION=="add", RUN+="/appmount/scripts/usb_mount.sh '%E{ID_FS_LABEL}' '%E{DEVNAME}'"
Varable
Environmental Variables
udev sets for you several environmental variables that you can use, among others ID_VENDOR.
Try that little script:
#!/bin/bash echo "Called by udev" >> /tmp/testenv env >> /tmp/testenv echo "Vendor id is $ID_VENDOR" >> /tmp/testenv
Put it in a rule, and you will see how much things are set up for you.
ENV{DEVTYPE}
ATTRS{idVendor}
$links
The current list of symlinks, separated by a space character.
The value is only set if an earlier rule assigned a value, or during a remove events.
$name
The current name of the device node. If not changed by a rule,
it is the name of the kernel device.
PROGRAM 與 RESULT
"RESULT" Match the returned string of the last "PROGRAM" call.
This key may be used in any following rule after a PROGRAM call.
i.e.
KERNEL=="sd*", SUBSYSTEM=="block" \ , PROGRAM=="/lib/udev/scsi_id --whitelisted --replace-whitespace /dev/$name" \ , RESULT=="1ATA_WDC_WD30EFRX-68AX9N0_WD-WMC1T0076306" \ , SYMLINK+="pci24scsi00"
Usage Example
hotplug disk
# shutdown disk
hdparm -Y /dev/sde
echo 1 > /sys/block/sde/device/delete
# config & apply
mv 99-disk.rules /etc/udev/rules.d
udevadm control --reload-rules
# reload the disk
echo "- - -" > /sys/class/scsi_host/host4/scan
ls -1 /dev/disk/
bakdisk-500g ...
USB disk SYMLINK
ls -l /dev/disk/by-id/ | grep WD2004FBYZ
lrwxrwxrwx 1 root root 9 May 13 11:07 ata-WDC_WD2004FBYZ-01YCBB1_WD-WMC6N0D6A1UV -> ../../sdd lrwxrwxrwx 1 root root 10 May 13 11:07 ata-WDC_WD2004FBYZ-01YCBB1_WD-WMC6N0D6A1UV-part1 -> ../../sdd1
udevadm info /dev/sdd1 | less
# alias name for sdX
ACTION=="add", KERNEL=="sd*" \ , ENV{ID_MODEL}=="WDC_WD2004FBYZ-01YCBB1" \ , ENV{DEVTYPE}=="partition" \ , SYMLINK+="usbdisk/WD2004FBYZ"
udevadm test /sys/block/sdd/sdd1 | grep DEVLINKS
* 當 USB un-plug 後, 那 Link 及 /dev 下的 Folder 會自動刪除
* touch 引發的 "change" 亦會引發刪除 link
如果不想 link 被刪除, 就要
ACTION=="add", KERNEL=="sd*" \
, ENV{ID_PART_ENTRY_NAME}=="WD4T-K3G5AD6B" \
, ENV{DEVTYPE}=="partition" \
, SYMLINK+="usbdisk/WD4T-K3G5AD6B"
ACTION=="change", KERNEL=="sd*" \
, ENV{ID_PART_ENTRY_NAME}=="WD4T-K3G5AD6B" \
, ENV{DEVTYPE}=="partition" \
, SYMLINK+="usbdisk/WD4T-K3G5AD6B"
# Link a USB Disk & mount it
/etc/udev/rules.d/99-usbdisk.rules
ACTION=="add",SUBSYSTEMS=="usb" \ , ATTRS{idVendor}=="174c",ATTRS{idProduct}=="5136" \ , SYMLINK+="hdd_RED3T" \ , RUN:="/root/scripts/usbdisk/mountdisk.sh" ACTION=="remove",SUBSYSTEMS=="usb" \ , ATTRS{idVendor}=="174c" \ , ATTRS{idProduct}=="5136" \ , RUN:="/root/scripts/usbdisk/umountdisk.sh"
script: mount-usbdisk.sh
#!/bin/bash mountusbdisk() { device="/dev/usbdisk/$1" point="/data/$1" if [ -L $device ]; then mountpoint $point > /dev/null if [[ $? == 1 ]]; then echo "mount $1" mount -o noatime $device $point else echo "$1 has mounted" fi else echo "no device $1" fi } mountusbdisk WD3003FZEX
DOC
http://www.reactivated.net/writing_udev_rules.html
https://wiki.archlinux.org/index.php/udev