udevd

最後更新: 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

 

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

 

Creative Commons license icon Creative Commons license icon