用 UDEV 固定 iSCSI 设备名称

本文介绍如何使用UDEV机制固定iSCSI设备名称,包括配置规则文件和编写iscsidev.sh脚本的方法。
[size=small] 用 open-iscsi 连上 Target 之后,iSCSI 设备的名称在系统里总是变来变去,无法固定,这给应用带来了诸多不便。为了固定系统中 iSCSI 设备的名称,可以考虑使用Linux 2.6 内核引入的 UDEV 机制。
关于 UDEV 的介绍,网上的资料很多,这里就不啰嗦了。英文好的同学也可以用 [color=red]man udev[/color] 来查看系统自带的帮助文档。

[list]
[*][b]UDEV 规则文件[/b]
[/list] UDEV 相关的配置文件、规则文件和脚本等的位置在不同系统上不尽相同,可以通过 [color=red]man udev[/color] 查到。在 CentOS 上,这些文件均位于 [color=red]/etc/udev[/color] 目录下。
UDEV 规则文件必须以 [color=red].rules[/color] 结尾,开始的数字代表规则执行的优先级,数字越小,优先级越高。当然,也可以不指定数字。
好了,废话不多说,直接上规则:

[b][color=violet]KERNEL=="sd*", BUS=="scsi", ENV{ID_PATH}=="ip-*", PROGRAM="/etc/udev/scripts/iscsidev.sh %E{ID_PATH}", SYMLINK+="iscsi/%c/part%n"[/color][/b]

[b][color=red]注意[/color][/b]:规则文件中的一条规则必须在同一行内,不允许跨行。
上述规则中,"==" 为条件判断,"KERNEL"、"BUS"、"ENV{ID_PATH}"为规则必须满足的条件。这3个条件可以确认一个 iSCSI 设备或分区。其中,"ENV{ID_PATH}"表示设备的 ID_PATH 属性,该属性在 CentOS 中为 "[color=red]ip-[/color]" 开头的字符串。
PROGRAM 指定满足规则后执行的脚本程序,SYMLINK 表示满足规则后创建指定该设备的符号链接。SYMLINK 默认创建在 [color=red]/dev[/color] 目录下,所以这里只给出了相对路径。
规则中以"%"开始的是 UDEV 中的参数,如下:
[table]
|%E{key}|一个环境变量的值,即通过 [color=red]udevadm[/color] 命令查询出的设备属性
|%c|PROGRAM 返回的结果
|%n|设备的内核号码,例如:sda3 的内核号码是 3
[/table] 详细的参数说明,可以查看 UDEV 的系统帮助([color=red]man udev[/color]),也可以参考[url=http://zhumeng8337797.blog.163.com/blog/static/1007689142010836613486/]简述udev的自定义规则[/url]。

上述规则中,iSCSI 设备的 SYMLINK 为 [color=red]/dev/iscsi/<target name>/part<n>[/color]。其中,<n> 为设备的内核号码;<target name> 通过 PROGRAM 指定的脚本获得。

[list]
[*][b]UDEV 脚本[/b]
[/list] iscsidev.sh 脚本的内容如下:
[b][color=violet]#!/bin/sh
# File: /etc/udev/scripts/iscsidev.sh

TARGET_NAME=`/bin/echo $1 | /bin/awk -F"-iscsi-" '{print $2}' | /bin/awk -F"-lun-" '{print $1"/lun"$2}'`
/bin/echo ${TARGET_NAME}[/color][/b]

脚本的传入参数为设备的 ID_PATH 属性,其格式为 [color=red]ip-<server ip>:<port>-iscsi-<target name>-lun-<lun id>[/color],可以通过 [color=red]udevadm[/color] 查询到:
[b][color=green]# udevadm info --query=property --name=/dev/sdb[/color][/b]
[img]http://dl.iteye.com/upload/attachment/0077/3312/eae770df-3aa5-3755-b33f-044897a74b30.png[/img]

脚本解析传入的参数,解析出 Target 的名字,然后组成 LUN 对应设备的符号链接,并返回。
现在,可以登入 iSCSI Target,然后再 [color=red]/dev/iscsi/[/color] 下查看对应的符号链接了。
[/size]
root@test-10-1-18-12:/home/test/gpu-burn# udevadm test /sys/class/infiniband/mlx5_7 This program is for debugging only, it does not run any program specified by a RUN key. It may show incorrect results, because some values may be different, or not available at a simulation run. Trying to open "/etc/systemd/hwdb/hwdb.bin"... Trying to open "/etc/udev/hwdb.bin"... Trying to open "/usr/lib/systemd/hwdb/hwdb.bin"... Trying to open "/lib/systemd/hwdb/hwdb.bin"... Trying to open "/lib/udev/hwdb.bin"... === trie on-disk === tool version: 249 file size: 11124932 bytes header size 80 bytes strings 2374708 bytes nodes 8750144 bytes Load module index Found cgroup2 on /sys/fs/cgroup/, full unified hierarchy Found container virtualization none. Network interface NamePolicy= disabled on kernel command line, ignoring. Loaded timestamp for '/etc/systemd/network'. Loaded timestamp for '/run/systemd/network'. Parsed configuration file /usr/lib/systemd/network/99-default.link Parsed configuration file /usr/lib/systemd/network/73-usb-net-by-mac.link Created link configuration context. Loaded timestamp for '/etc/udev/rules.d'. Loaded timestamp for '/run/udev/rules.d'. Reading rules file: /usr/lib/udev/rules.d/01-md-raid-creating.rules Reading rules file: /etc/udev/rules.d/30-persistent-rdma.rules Reading rules file: /usr/lib/udev/rules.d/39-usbmuxd.rules Reading rules file: /usr/lib/udev/rules.d/40-usb_modeswitch.rules Reading rules file: /usr/lib/udev/rules.d/40-vm-hotadd.rules Reading rules file: /usr/lib/udev/rules.d/50-apport.rules Reading rules file: /usr/lib/udev/rules.d/50-firmware.rules Reading rules file: /usr/lib/udev/rules.d/50-udev-default.rules Reading rules file: /usr/lib/udev/rules.d/55-dm.rules Reading rules file: /usr/lib/udev/rules.d/55-scsi-sg3_id.rules Reading rules file: /usr/lib/udev/rules.d/56-dm-mpath.rules Reading rules file: /usr/lib/udev/rules.d/56-dm-parts.rules Reading rules file: /usr/lib/udev/rules.d/56-lvm.rules Reading rules file: /usr/lib/udev/rules.d/58-scsi-sg3_symlink.rules Reading rules file: /usr/lib/udev/rules.d/60-autosuspend.rules Reading rules file: /usr/lib/udev/rules.d/60-block.rules Reading rules file: /usr/lib/udev/rules.d/60-bridge-network-interface.rules Reading rules file: /usr/lib/udev/rules.d/60-cdrom_id.rules Reading rules file: /usr/lib/udev/rules.d/60-drm.rules Reading rules file: /usr/lib/udev/rules.d/60-evdev.rules Reading rules file: /usr/lib/udev/rules.d/60-fido-id.rules Reading rules file: /usr/lib/udev/rules.d/60-input-id.rules Reading rules file: /usr/lib/udev/rules.d/60-multipath.rules Reading rules file: /usr/lib/udev/rules.d/60-open-vm-tools.rules Reading rules file: /usr/lib/udev/rules.d/60-persistent-alsa.rules Reading rules file: /usr/lib/udev/rules.d/60-persistent-input.rules Reading rules file: /usr/lib/udev/rules.d/60-persistent-storage-dm.rules Reading rules file: /usr/lib/udev/rules.d/60-persistent-storage-tape.rules Reading rules file: /usr/lib/udev/rules.d/60-persistent-storage.rules Reading rules file: /usr/lib/udev/rules.d/60-persistent-v4l.rules Reading rules file: /usr/lib/udev/rules.d/60-rdma-ndd.rules Reading rules file: /usr/lib/udev/rules.d/60-rdma-persistent-naming.rules Reading rules file: /usr/lib/udev/rules.d/60-sensor.rules Reading rules file: /usr/lib/udev/rules.d/60-serial.rules Reading rules file: /usr/lib/udev/rules.d/60-srp_daemon.rules Reading rules file: /usr/lib/udev/rules.d/60-tpm-udev.rules Reading rules file: /usr/lib/udev/rules.d/60-xpmem.rules Reading rules file: /usr/lib/udev/rules.d/61-persistent-storage-android.rules Reading rules file: /usr/lib/udev/rules.d/63-md-raid-arrays.rules Reading rules file: /usr/lib/udev/rules.d/64-btrfs-dm.rules Reading rules file: /usr/lib/udev/rules.d/64-btrfs-zoned.rules Reading rules file: /usr/lib/udev/rules.d/64-btrfs.rules Reading rules file: /usr/lib/udev/rules.d/64-md-raid-assembly.rules Reading rules file: /usr/lib/udev/rules.d/64-xorg-xkb.rules Reading rules file: /usr/lib/udev/rules.d/66-azure-ephemeral.rules Reading rules file: /usr/lib/udev/rules.d/66-snapd-autoimport.rules Reading rules file: /usr/lib/udev/rules.d/68-del-part-nodes.rules Reading rules file: /usr/lib/udev/rules.d/69-bcache.rules Reading rules file: /usr/lib/udev/rules.d/69-lvm-metad.rules Reading rules file: /usr/lib/udev/rules.d/69-md-clustered-confirm-device.rules Reading rules file: /usr/lib/udev/rules.d/70-iscsi-network-interface.rules Reading rules file: /usr/lib/udev/rules.d/70-joystick.rules Reading rules file: /usr/lib/udev/rules.d/70-memory.rules Reading rules file: /usr/lib/udev/rules.d/70-mouse.rules Reading rules file: /usr/lib/udev/rules.d/70-open-iscsi.rules Reading rules file: /usr/lib/udev/rules.d/70-power-switch.rules Reading rules file: /etc/udev/rules.d/70-snap.snapd.rules Reading rules file: /usr/lib/udev/rules.d/70-touchpad.rules Reading rules file: /usr/lib/udev/rules.d/70-uaccess.rules Reading rules file: /usr/lib/udev/rules.d/71-nvidia.rules Reading rules file: /usr/lib/udev/rules.d/71-power-switch-proliant.rules Reading rules file: /usr/lib/udev/rules.d/71-seat.rules Reading rules file: /usr/lib/udev/rules.d/71-u-d-c-gpu-detection.rules Reading rules file: /usr/lib/udev/rules.d/73-seat-late.rules Reading rules file: /usr/lib/udev/rules.d/73-special-net-names.rules Reading rules file: /usr/lib/udev/rules.d/75-net-description.rules Reading rules file: /usr/lib/udev/rules.d/75-probe_mtd.rules Reading rules file: /usr/lib/udev/rules.d/75-rdma-description.rules Reading rules file: /usr/lib/udev/rules.d/77-mm-broadmobi-port-types.rules Reading rules file: /usr/lib/udev/rules.d/77-mm-cinterion-port-types.rules Reading rules file: /usr/lib/udev/rules.d/77-mm-dell-port-types.rules Reading rules file: /usr/lib/udev/rules.d/77-mm-dlink-port-types.rules Reading rules file: /usr/lib/udev/rules.d/77-mm-ericsson-mbm.rules Reading rules file: /usr/lib/udev/rules.d/77-mm-fibocom-port-types.rules Reading rules file: /usr/lib/udev/rules.d/77-mm-foxconn-port-types.rules Reading rules file: /usr/lib/udev/rules.d/77-mm-gosuncn-port-types.rules Reading rules file: /usr/lib/udev/rules.d/77-mm-haier-port-types.rules Reading rules file: /usr/lib/udev/rules.d/77-mm-huawei-net-port-types.rules Reading rules file: /usr/lib/udev/rules.d/77-mm-longcheer-port-types.rules Reading rules file: /usr/lib/udev/rules.d/77-mm-mtk-port-types.rules Reading rules file: /usr/lib/udev/rules.d/77-mm-nokia-port-types.rules Reading rules file: /usr/lib/udev/rules.d/77-mm-qcom-soc.rules Reading rules file: /usr/lib/udev/rules.d/77-mm-qdl-device-blacklist.rules Reading rules file: /usr/lib/udev/rules.d/77-mm-quectel-port-types.rules Reading rules file: /usr/lib/udev/rules.d/77-mm-sierra.rules Reading rules file: /usr/lib/udev/rules.d/77-mm-simtech-port-types.rules Reading rules file: /usr/lib/udev/rules.d/77-mm-telit-port-types.rules Reading rules file: /usr/lib/udev/rules.d/77-mm-tplink-port-types.rules Reading rules file: /usr/lib/udev/rules.d/77-mm-ublox-port-types.rules Reading rules file: /usr/lib/udev/rules.d/77-mm-x22x-port-types.rules Reading rules file: /usr/lib/udev/rules.d/77-mm-zte-port-types.rules Reading rules file: /usr/lib/udev/rules.d/78-graphics-card.rules Reading rules file: /usr/lib/udev/rules.d/78-sound-card.rules Reading rules file: /usr/lib/udev/rules.d/80-debian-compat.rules Reading rules file: /usr/lib/udev/rules.d/80-drivers.rules Reading rules file: /usr/lib/udev/rules.d/80-mm-candidate.rules Reading rules file: /usr/lib/udev/rules.d/80-net-setup-link.rules Reading rules file: /usr/lib/udev/rules.d/80-udisks2.rules Reading rules file: /usr/lib/udev/rules.d/81-net-dhcp.rules Reading rules file: /usr/lib/udev/rules.d/83-mlnx-sf-name.rules Reading rules file: /usr/lib/udev/rules.d/85-hdparm.rules Reading rules file: /usr/lib/udev/rules.d/90-bolt.rules Reading rules file: /usr/lib/udev/rules.d/90-console-setup.rules Reading rules file: /usr/lib/udev/rules.d/90-fwupd-devices.rules Reading rules file: /usr/lib/udev/rules.d/90-ib.rules Reading rules file: /run/udev/rules.d/90-netplan.rules Reading rules file: /usr/lib/udev/rules.d/90-rdma-umad.rules Reading rules file: /usr/lib/udev/rules.d/95-dm-notify.rules Reading rules file: /usr/lib/udev/rules.d/95-kpartx.rules Reading rules file: /usr/lib/udev/rules.d/95-upower-hid.rules Reading rules file: /usr/lib/udev/rules.d/95-upower-wup.rules Reading rules file: /usr/lib/udev/rules.d/96-e2scrub.rules Reading rules file: /usr/lib/udev/rules.d/99-lxd-agent.rules Reading rules file: /etc/udev/rules.d/99-persistent-rdma.rules Reading rules file: /usr/lib/udev/rules.d/99-systemd.rules Reading rules file: /usr/lib/udev/rules.d/99-vmware-scsi-udev.rules value '[dmi/id]sys_vendor' is 'Giga Computing' value '[dmi/id]sys_vendor' is 'Giga Computing' mlx5_7: /usr/lib/udev/rules.d/75-rdma-description.rules:41 Importing properties from results of builtin command 'hwdb --subsystem=pci' mlx5_7: hwdb modalias key: "pci:v000015B3d00001021sv000015B3sd00000022bc02sc07i00" mlx5_7: sd-device: Created db file '/run/udev/data/+infiniband:mlx5_7' for '/devices/pci0000:c7/0000:c7:01.0/0000:c8:00.0/0000:c9:00.0/0000:ca:00.0/0000:cb:00.0/0000:cc:00.0/infiniband/mlx5_7' DEVPATH=/devices/pci0000:c7/0000:c7:01.0/0000:c8:00.0/0000:c9:00.0/0000:ca:00.0/0000:cb:00.0/0000:cc:00.0/infiniband/mlx5_7 NAME=mlx5_7 ACTION=add SUBSYSTEM=infiniband TAGS=:systemd: CURRENT_TAGS=:systemd: SYSTEMD_WANTS=rdma-ndd.service ID_RDMA_INFINIBAND=1 ID_RDMA_ROCE=1 ID_BUS=pci ID_VENDOR_ID=0x15b3 ID_MODEL_ID=0x1021 ID_PCI_CLASS_FROM_DATABASE=Network controller ID_PCI_SUBCLASS_FROM_DATABASE=Infiniband controller ID_VENDOR_FROM_DATABASE=Mellanox Technologies ID_MODEL_FROM_DATABASE=MT2910 Family [ConnectX-7] USEC_INITIALIZED=162756069 Unload module index Unloaded link configuration context. root@test-10-1-18-12:/home/test/gpu-burn#
06-07
<think>好的,用户的问题是关于如何通过udev规则固定USB串口设备名称,防止设备名称从ACM0变为ACM1。用户之前已经询问过串口设备名称变化的原因,现在需要具体的配置方法。我需要参考之前的回答和提供的引用内容来给出详细的步骤。 首先,用户提到的引用[1]和[2]都涉及到了通过udev规则来绑定设备名称。引用[1]中提到了如何查找设备的路径和属性,而引用[2]则具体说明了如何在ROS中配置udev规则,特别是SYMLINK的使用。引用[3]是关于CDC_ACM设备的代码,可能与驱动有关,但暂时不需要深入。 用户的需求是固定设备名称,防止变化。根据之前的回答,核心是通过udev规则根据设备的唯一属性(如序列号、VID/PID)来创建符号链接或者固定名称。需要确保规则中使用了足够唯一的属性,避免多个设备冲突。 接下来,我需要分步骤解释如何操作。首先获取设备的唯一属性,比如使用udevadm命令或者lsusb。然后创建udev规则文件,通常放在/etc/udev/rules.d/目录下,文件名以数字开头,如99-usb-serial.rules。规则内容需要匹配设备的属性,比如SUBSYSTEM、ATTRS{idVendor}、ATTRS{idProduct},以及可能的序列号。然后通过SYMLINK或直接指定KERNEL来固定名称。 需要注意的是,用户可能对udev规则语法不熟悉,所以需要给出具体的示例,并解释每个参数的作用。比如,使用SYMLINK创建符号链接,或者直接分配固定设备节点名称。同时,提醒用户重启服务或重新加载规则,以及测试的方法,如重新插拔设备后检查/dev下的名称。 另外,用户可能遇到的问题包括权限问题,比如串口设备默认属于dialout组,可能需要添加用户到该组。或者规则未生效,需要检查语法错误,使用udevadm test命令调试。 最后,确保回答结构清晰,步骤明确,并包含验证方法和常见问题处理,这样用户能够一步步操作,避免困惑。</think>### 通过 udev 规则固定 USB 串口设备名称的详细步骤 #### 一、核心原理 通过 **设备唯一标识**(如 `VID/PID`、`序列号`)绑定固定设备节点名称,避免依赖系统动态分配的 `ttyACM0/1` 编号。具体通过以下步骤实现: 1. **获取设备唯一属性** 2. **编写 udev 规则** 3. **重新加载规则** --- #### 二、操作流程 ##### 1. **查询设备唯一属性** 使用 `udevadm info` 或 `lsusb` 获取设备标识: ```bash # 插入设备后执行(假设当前设备名为 ttyACM0) udevadm info -a -n /dev/ttyACM0 | grep -E 'idVendor|idProduct|serial' ``` 输出示例: ```bash ATTRS{idVendor}=="0483" # VID(十六进制) ATTRS{idProduct}=="5740" # PID(十六进制) ATTRS{serial}=="0001A0000000" # 设备序列号(唯一标识) ``` ##### 2. **创建 udev 规则文件** 新建规则文件 `/etc/udev/rules.d/99-usb-serial.rules`,内容如下: ```bash # 固定名称规则(根据实际属性修改) SUBSYSTEM=="tty", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="5740", ATTRS{serial}=="0001A0000000", SYMLINK+="my_uart", MODE="0666" ``` - **关键参数说明**: - `SUBSYSTEM=="tty"`:匹配串口设备 - `ATTRS{idVendor}/ATTRS{idProduct}`:设备的 VID/PID(必须与查询结果一致) - `ATTRS{serial}`:**序列号**(确保唯一性,避免多设备冲突) - `SYMLINK+="my_uart"`:创建符号链接 `/dev/my_uart` - `MODE="0666"`:设置设备权限(允许所有用户读写) ##### 3. **生效规则** ```bash # 重新加载规则 sudo udevadm control --reload-rules sudo udevadm trigger # 重新插拔设备后验证 ls -l /dev/my_uart # 应显示指向 ttyACM* 的符号链接 ``` --- #### 三、高级配置(可选) 1. **直接分配固定设备名**(非符号链接): ```bash SUBSYSTEM=="tty", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="5740", NAME="my_uart" ``` *需注意:`NAME` 参数可能受系统限制,建议优先使用 `SYMLINK`[^2]*。 2. **多设备共存时**:为每个设备单独指定序列号: ```bash # 设备1 SUBSYSTEM=="tty", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="5740", ATTRS{serial}=="0001A0000000", SYMLINK+="device1" # 设备2 SUBSYSTEM=="tty", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="5740", ATTRS{serial}=="0001A0000001", SYMLINK+="device2" ``` --- #### 四、验证与调试 1. **查看设备节点**: ```bash ls /dev | grep -E 'ttyACM|my_uart' ``` 2. **检查规则匹配**: ```bash udevadm test $(udevadm info -q path -n /dev/ttyACM0) 2>&1 | grep my_uart ``` 3. **内核日志排查**: ```bash dmesg | grep ttyACM ``` --- #### 五、常见问题 - **规则未生效**:检查规则语法(逗号、引号)、文件命名(`.rules` 后缀)、属性值是否与设备匹配。 - **权限问题**:确保 `MODE="0666"` 或用户加入 `dialout` 组。 - **多设备混淆**:必须使用 `ATTRS{serial}` 区分相同 VID/PID 的设备[^1]。 --- ### 相关问题 1. 如何为无序列号的 USB 设备固定名称? 2. udev 规则中 `SYMLINK` 和 `NAME` 的区别是什么? 3. 为什么修改 udev 规则后需要重新加载服务?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值