本文主要实现网络设备的命名规则实现和tty串口设备的别名命名规则实现。
自Linux kernel2.6以来,便引入了sysfs,该文件系统的引入使得非常人性化,与人友好,与此协伴而生的还有udev,udev机制主要是解决热插拔设备的名字问题。如usb设备,当某usb当前接入时候名字生成是USB0,但当进行热插拔后有可能就不是USB0了,udev对此应运而生。详细可参考如下文章:
1.Linux udev规则编写
2.linux systemd_使用systemd-udevd在Linux上管理连接的硬件
3.systemd时代的服务管理
关于规则的关键字可参考下表:
键 | 含义 |
---|---|
ACTION | 一个时间活动的名字,比如add,当设备增加的时候 |
KERNEL | 在内核里看到的设备名字,比如sd*表示任意SCSI磁盘设备 |
DEVPATH | 内核设备录进,比如/devices/* |
SUBSYSTEM | 子系统名字,比如sound,net |
BUS | 总线的名字,比如IDE,USB |
DRIVER | 设备驱动的名字,比如ide-cdrom |
ID | 独立于内核名字的设备名字 |
SYSFS{ value} | sysfs属性值,他可以表示任意 |
ENV{ key} | 环境变量,可以表示任意 |
PROGRAM | 可执行的外部程序,如果程序返回0值,该键则认为为真(true) |
RESULT | 上一个PROGRAM调用返回的标准输出 |
NAME | 根据这个规则创建的设备文件的文件名。注意:仅仅第一行的NAME描述是有效的,后面的均忽略。 如果你想使用使用两个以上的名字来访问一个设备的话,可以考虑SYMLINK键。 |
SYMLINK | 根据规则创建的字符连接名 |
OWNER | 设备文件的属组 |
GROUP | 设备文件所在的组 |
MODE | 设备文件的权限,采用8进制 |
RUN | 为设备而执行的程序列表 |
LABEL | 在配置文件里为内部控制而采用的名字标签(下下面的GOTO服务) |
GOTO | 跳到匹配的规则(通过LABEL来标识),有点类似程序语言中的GOTO |
IMPORT{ type} | 导入一个文件或者一个程序执行后而生成的规则集到当前文件 |
WAIT_FOR_SYSFS | 等待一个特定的设备文件的创建。主要是用作时序和依赖问题 |
PTIONS | 特定的选项: last_rule 对这类设备终端规则执行; ignore_device 忽略当前规则; ignore_remove 忽略接下来的并移走请求。all_partitions 为所有的磁盘分区创建设备文件 |
下面依据实例来分析如何实现相应的udev规则:
1.网口设备命名。
SUBSYSTEM=="net",ACTION=="add",DRIVERS=="?*",ATTR{address}=="00:e0:4c:36:40:73",ATTR{type}=="1" ,KERNEL=="enx00e04c364073*",NAME="eth0"
SUBSYSTEM=="net",ACTION=="add",DRIVERS=="?*",ATTR{address}=="96:2f:65:df:b2:cc",ATTR{type}=="1" ,KERNEL=="eth0*",NAME="eth1"
SUBSYSTEM=="net",ACTION=="add",DRIVERS=="?*",ATTR{address}=="32:4a:26:2d:72:18",ATTR{type}=="1" ,KERNEL=="p2p0*",NAME="wlan1"
SUBSYSTEM=="net",ACTION=="add",DRIVERS=="?*",ATTR{address}=="30:4a:26:2d:72:18",ATTR{type}=="1" ,KERNEL=="wl*",NAME="wlan0"
上述规则是根据网络设备的mac地址命名成指定的设备名,据一条来分析下:
SUBSYSTEM=="net",ACTION=="add",DRIVERS=="?*",ATTR{address}=="96:2f:65:df:b2:cc",ATTR{type}=="1" ,KERNEL=="eth0*",NAME="eth1"
这句规则的意思是此句匹配的是子系统是net的设备,动作是设备add的时候,驱动是通配符,该设备的mac地址是96:2f:65:df:b2:cc,类型为1,内核设备名为eth0起始,末尾*通配,命名为指定eth1。
2.tty串口设备(此处是usb转串口设备)
KERNELS=="1-1.2:1.0", MODE:="0666", GROUP:="dialout", SYMLINK+="com1"
KERNELS=="1-1.2:1.2", MODE:="0666", GROUP:="dialout", SYMLINK+="com2"
KERNELS=="1-1.2:1.4", MODE:="0666", GROUP:="dialout", SYMLINK+="com3"
KERNELS=="1-1.2:1.6", MODE:="0666", GROUP:="dialout", SYMLINK+="com4"
KERNELS=="1-1.3:1.0", MODE:="0666", GROUP:="dialout", SYMLINK+="com5"
KERNELS=="1-1.3:1.2", MODE:="0666", GROUP:="dialout", SYMLINK+="com6"
KERNELS=="1-1.3:1.4", MODE:="0666", GROUP:="dialout", SYMLINK+="com7"
KERNELS=="1-1.3:1.6", MODE:="0666", GROUP:="dialout", SYMLINK+="com8"
KERNELS=="1-1.4:1.0", MODE:="0666", GROUP:="dialout", SYMLINK+="com9"
KERNELS=="1-1.4:1.2", MODE:="0666", GROUP:="dialout", SYMLINK+="com10"
KERNELS=="1-1.4:1.4", MODE:="0666", GROUP:="dialout", SYMLINK+="com11"
KERNELS=="1-1.4:1.6", MODE:="0666", GROUP:="dialout", SYMLINK+="com12"
KERNELS=="2-1.1:1.0", MODE:="0666", GROUP:="dialout", SYMLINK+="com13"
KERNELS=="2-1.1:1.2", MODE:="0666", GROUP:="dialout", SYMLINK+="com14"
KERNELS=="2-1.1:1.4", MODE:="0666", GROUP:="dialout", SYMLINK+="com15"
KERNELS=="2-1.1:1.6", MODE:="0666", GROUP:="dialout", SYMLINK+="com16"
KERNELS=="2-1.2:1.0", MODE:="0666", GROUP:="dialout", SYMLINK+="com17"
KERNELS=="2-1.2:1.2", MODE:="0666", GROUP:="dialout", SYMLINK+="com18"
KERNELS=="2-1.2:1.4", MODE:="0666", GROUP:="dialout", SYMLINK+="com19"
KERNELS=="2-1.2:1.6", MODE:="0666", GROUP:="dialout", SYMLINK+="com20"
KERNELS=="2-1.3:1.0", MODE:="0666", GROUP:="dialout", SYMLINK+="com21"
KERNELS=="2-1.3:1.2", MODE:="0666", GROUP:="dialout", SYMLINK+="com22"
KERNELS=="2-1.3:1.4", MODE:="0666", GROUP:="dialout", SYMLINK+="com23"
KERNELS=="2-1.3:1.6", MODE:="0666", GROUP:="dialout", SYMLINK+="com24"
上述规则是根据usb转串口设备在内核里的硬件链接端口节点来软链接命名(别名),据一条来分析下:
KERNELS=="1-1.2:1.0", MODE:="0666", GROUP:="dialout", SYMLINK+="com1"
这句规则意思为内核设备名为1-1.2:1.0,这实际代表的是某路usb上一个设备上的第0个端口,跟硬件是对起来的,对外权限是0666,以符号链接的形式在/dev/下创建com1设备。
Q:如何获取书写规则的相关参数?
A:
1:udevadm info --attribute-walk --name=/dev/ttyXRUSB0
2:udevadm info -e | grep ttyXR
root@root:~# udevadm info --attribute-walk --name=/dev/ttyXRUSB0
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/platform/fe3c0000.usb/usb2/2-1/2-1.1/2-1.1:1.0/tty/ttyXRUSB0':
KERNEL=="ttyXRUSB0"
SUBSYSTEM=="tty"
DRIVER==""
looking at parent device '/devices/platform/fe3c0000.usb/usb2/2-1/2-1.1/2-1.1:1.0':
KERNELS=="2-1.1:1.0"
SUBSYSTEMS=="usb"
DRIVERS=="cdc_xr_usb_serial"
ATTRS{authorized}=="1"
ATTRS{bAlternateSetting}==" 0"
ATTRS{bInterfaceClass}=="02"
ATTRS{bInterfaceNumber}=="00"
ATTRS{bInterfaceProtocol}=="01"
ATTRS{bInterfaceSubClass}=="02"
ATTRS{bNumEndpoints}=="01"
ATTRS{bmCapabilities}=="6"
ATTRS{iad_bFirstInterface}=="00"
ATTRS{iad_bFunctionClass}=="02"
ATTRS{iad_bFunctionProtocol}=="00"
ATTRS{iad_bFunctionSubClass}=="02"
ATTRS{iad_bInterfaceCount}=="02"
ATTRS{supports_autosuspend}=="1"
looking at parent device '/devices/platform/fe3c0000.usb/usb2/2-1/2-1.1':
KERNELS=="2-1.1"
SUBSYSTEMS=="usb"
DRIVERS=="usb"
ATTRS{authorized}=="1"
ATTRS{avoid_reset_quirk}=="0"
ATTRS{bConfigurationValue}=="1"
ATTRS{bDeviceClass}=="ef"
ATTRS{bDeviceProtocol}=="01"
ATTRS{bDeviceSubClass}=="02"
ATTRS{bMaxPacketSize0}=="64"
ATTRS{bMaxPower}=="94mA"
ATTRS{bNumConfigurations}=="1"
ATTRS{bNumInterfaces}==" 8"
ATTRS{bcdDevice}=="0003"
ATTRS{bmAttributes}=="c0"
ATTRS{busnum}=="2"
ATTRS{configuration}==""
ATTRS{devnum}=="3"
ATTRS{devpath}=="1.1"
ATTRS{idProduct}=="1414"
ATTRS{idVendor}=="04e2"
ATTRS{ltm_capable}=="no"
ATTRS{maxchild}=="0"
ATTRS{quirks}=="0x0"
ATTRS{removable}=="unknown"
ATTRS{speed}=="12"
ATTRS{urbnum}=="69"
ATTRS{version}==" 2.00"
looking at parent device '/devices/platform/fe3c0000.usb/usb2/2-1':
KERNELS=="2-1"
SUBSYSTEMS=="usb"
DRIVERS=="usb"
ATTRS{authorized}=="1"
ATTRS{avoid_reset_quirk}=="0"
ATTRS{bConfigurationValue}=="1"
ATTRS{bDeviceClass}=="09"
ATTRS{bDeviceProtocol}=="02"
ATTRS{bDeviceSubClass}=="00"
ATTRS{bMaxPacketSize0}=="64"
ATTRS{bMaxPower}=="100mA"
ATTRS{bNumConfigurations}=="1"
ATTRS{bNumInterfaces}==" 1"
ATTRS{bcdDevice}=="3298"
ATTRS{bmAttributes}=="e0"
ATTRS{busnum}=="2"
ATTRS{configuration}==""
ATTRS{devnum}=="2"
ATTRS{devpath}=="1"
ATTRS{idProduct}=="0610"
ATTRS{idVendor}=="05e3"
ATTRS{ltm_capable}=="no"
ATTRS{maxchild}=="4"
ATTRS{product}=="USB2.0 Hub"
ATTRS{quirks}=="0x0"
ATTRS{removable}=="unknown"
ATTRS{speed}=="480"
ATTRS{urbnum}=="40"
ATTRS{version}==" 2.00"
looking at parent device '/devices/platform/fe3c0000.usb/usb2':
KERNELS=="usb2"
SUBSYSTEMS=="usb"
DRIVERS=="usb"
ATTRS{authorized}=="1"
ATTRS{authorized_default}=="1"
ATTRS{avoid_reset_quirk}=="0"
ATTRS{bConfigurationValue}=="1"
ATTRS{bDeviceClass}=="09"
ATTRS{bDeviceProtocol}=="00"
ATTRS{bDeviceSubClass}=="00"
ATTRS{bMaxPacketSize0}=="64"
ATTRS{bMaxPower}=="0mA"
ATTRS{bNumConfigurations}=="1"
ATTRS{bNumInterfaces}==" 1"
ATTRS{bcdDevice}=="0404"
ATTRS{bmAttributes}=="e0"
ATTRS{busnum}=="2"
ATTRS{configuration}==""
ATTRS{devnum}=="1"
ATTRS{devpath}=="0"
ATTRS{idProduct}=="0002"
ATTRS{idVendor}=="1d6b"
ATTRS{interface_authorized_default}=="1"
ATTRS{ltm_capable}=="no"
ATTRS{manufacturer}=="Linux 4.4.179 ehci_hcd"
ATTRS{maxchild}=="1"
ATTRS{product}=="EHCI Host Controller"
ATTRS{quirks}=="0x0"
ATTRS{removable}=="unknown"
ATTRS{serial}=="fe3c0000.usb"
ATTRS{speed}=="480"
ATTRS{urbnum}=="22"
ATTRS{version}==" 2.00"
looking at parent device '/devices/platform/fe3c0000.usb':
KERNELS=="fe3c0000.usb"
SUBSYSTEMS=="platform"
DRIVERS=="ehci-platform"
ATTRS{companion}==""
ATTRS{driver_override}=="(null)"
ATTRS{uframe_periodic_max}=="100"
looking at parent device '/devices/platform':
KERNELS=="platform"
SUBSYSTEMS==""
DRIVERS==""
root@root:~# udevadm info -e | grep ttyXR
P: /devices/platform/fe380000.usb/usb1/1-1/1-1.2/1-1.2:1.0/tty/ttyXRUSB4
N: ttyXRUSB4
E: DEVNAME=/dev/ttyXRUSB4
E: DEVPATH=/devices/platform/fe380000.usb/usb1/1-1/1-1.2/1-1.2:1.0/tty/ttyXRUSB4
P: /devices/platform/fe380000.usb/usb1/1-1/1-1.2/1-1.2:1.2/tty/ttyXRUSB5
N: ttyXRUSB5
E: DEVNAME=/dev/ttyXRUSB5
E: DEVPATH=/devices/platform/fe380000.usb/usb1/1-1/1-1.2/1-1.2:1.2/tty/ttyXRUSB5
P: /devices/platform/fe380000.usb/usb1/1-1/1-1.2/1-1.2:1.4/tty/ttyXRUSB6
N: ttyXRUSB6
E: DEVNAME=/dev/ttyXRUSB6
E: DEVPATH=/devices/platform/fe380000.usb/usb1/1-1/1-1.2/1-1.2:1.4/tty/ttyXRUSB6
P: /devices/platform/fe380000.usb/usb1/1-1/1-1.2/1-1.2:1.6/tty/ttyXRUSB7
N: ttyXRUSB7
E: DEVNAME=/dev/ttyXRUSB7
E: DEVPATH=/devices/platform/fe380000.usb/usb1/1-1/1-1.2/1-1.2:1.6/tty/ttyXRUSB7
P: /devices/platform/fe380000.usb/usb1/1-1/1-1.3/1-1.3:1.0/tty/ttyXRUSB8
N: ttyXRUSB8
E: DEVNAME=/dev/ttyXRUSB8
E: DEVPATH=/devices/platform/fe380000.usb/usb1/1-1/1-1.3/1-1.3:1.0/tty/ttyXRUSB8
P: /devices/platform/fe380000.usb/usb1/1-1/1-1.3/1-1.3:1.2/tty/ttyXRUSB9
N: ttyXRUSB9
E: DEVNAME=/dev/ttyXRUSB9
E: DEVPATH=/devices/platform/fe380000.usb/usb1/1-1/1-1.3/1-1.3:1.2/tty/ttyXRUSB9
P: /devices/platform/fe380000.usb/usb1/1-1/1-1.3/1-1.3:1.4/tty/ttyXRUSB10
N: ttyXRUSB10
E: DEVNAME=/dev/ttyXRUSB10
E: DEVPATH=/devices/platform/fe380000.usb/usb1/1-1/1-1.3/1-1.3:1.4/tty/ttyXRUSB10
P: /devices/platform/fe380000.usb/usb1/1-1/1-1.3/1-1.3:1.6/tty/ttyXRUSB11
N: ttyXRUSB11
E: DEVNAME=/dev/ttyXRUSB11
E: DEVPATH=/devices/platform/fe380000.usb/usb1/1-1/1-1.3/1-1.3:1.6/tty/ttyXRUSB11
P: /devices/platform/fe380000.usb/usb1/1-1/1-1.4/1-1.4:1.0/tty/ttyXRUSB12
N: ttyXRUSB12
E: DEVNAME=/dev/ttyXRUSB12
E: DEVPATH=/devices/platform/fe380000.usb/usb1/1-1/1-1.4/1-1.4:1.0/tty/ttyXRUSB12
P: /devices/platform/fe380000.usb/usb1/1-1/1-1.4/1-1.4:1.2/tty/ttyXRUSB13
N: ttyXRUSB13
E: DEVNAME=/dev/ttyXRUSB13
E: DEVPATH=/devices/platform/fe380000.usb/usb1/1-1/1-1.4/1-1.4:1.2/tty/ttyXRUSB13
P: /devices/platform/fe380000.usb/usb1/1-1/1-1.4/1-1.4:1.4/tty/ttyXRUSB14
N: ttyXRUSB14
E: DEVNAME=/dev/ttyXRUSB14
E: DEVPATH=/devices/platform/fe380000.usb/usb1/1-1/1-1.4/1-1.4:1.4/tty/ttyXRUSB14
P: /devices/platform/fe380000.usb/usb1/1-1/1-1.4/1-1.4:1.6/tty/ttyXRUSB15
N: ttyXRUSB15
E: DEVNAME=/dev/ttyXRUSB15
E: DEVPATH=/devices/platform/fe380000.usb/usb1/1-1/1-1.4/1-1.4:1.6/tty/ttyXRUSB15
P: /devices/platform/fe3c0000.usb/usb2/2-1/2-1.1/2-1.1:1.0/tty/ttyXRUSB0
N: ttyXRUSB0
E: DEVNAME=/dev/ttyXRUSB0
E: DEVPATH=/devices/platform/fe3c0000.usb/usb2/2-1/2-1.1/2-1.1:1.0/tty/ttyXRUSB0
P: /devices/platform/fe3c0000.usb/usb2/2-1/2-1.1/2-1.1:1.2/tty/ttyXRUSB1
N: ttyXRUSB1
E: DEVNAME=/dev/ttyXRUSB1
E: DEVPATH=/devices/platform/fe3c0000.usb/usb2/2-1/2-1.1/2-1.1:1.2/tty/ttyXRUSB1
P: /devices/platform/fe3c0000.usb/usb2/2-1/2-1.1/2-1.1:1.4/tty/ttyXRUSB2
N: ttyXRUSB2
E: DEVNAME=/dev/ttyXRUSB2
E: DEVPATH=/devices/platform/fe3c0000.usb/usb2/2-1/2-1.1/2-1.1:1.4/tty/ttyXRUSB2
P: /devices/platform/fe3c0000.usb/usb2/2-1/2-1.1/2-1.1:1.6/tty/ttyXRUSB3
N: ttyXRUSB3
E: DEVNAME=/dev/ttyXRUSB3
E: DEVPATH=/devices/platform/fe3c0000.usb/usb2/2-1/2-1.1/2-1.1:1.6/tty/ttyXRUSB3