基于systemd/udev的Linux系统下,如何按多盘位存储柜物理位置命名磁盘
基于systemd/udev的Linux系统下,如何按多盘位存储柜物理位置命名磁盘
太懂这种麻烦了!多盘位JBOD里/dev/sda、/dev/sdb这种默认命名完全对应不上物理盘位,查故障、换硬盘要对着表格翻半天,简直折腾人。我来给你一步步解决这个问题:
为什么你之前的软链接没生效?
你之前创建的/dev/encl1这类symlink只是指向原设备的软链接,不是真正的设备名替代。系统和ZFS默认还是会优先识别内核生成的/dev/sd*节点,所以lsblk和zpool status里自然不会显示这些别名。我们需要做的是让udev生成持久化的别名,同时让ZFS主动使用这些别名。
步骤1:收集磁盘的唯一标识与对应槽位
首先得把每个物理槽位的磁盘和它的唯一标识绑定起来,有两种方式:
- 用磁盘序列号:你已经有这个对应表了,直接用就行。可以用
lsblk -o NAME,SERIAL快速查看所有磁盘的序列号。 - 用物理路径ID:如果你的JBOD支持,udev会给磁盘分配包含物理槽位的
ID_PATH属性。执行udevadm info --query=all --name=/dev/sda,找类似ENV{ID_PATH}="pci-0000:02:00.0-scsi-0:0:1:0"的行,里面的数字通常对应槽位编号。
步骤2:编写udev规则创建物理槽位别名
在/etc/udev/rules.d/下新建一个高优先级的规则文件,比如90-enclosure-drives.rules(数字越大,规则优先级越高),内容如下:
方式一:基于序列号映射(适合你已经有对应表的情况)
# 绑定序列号到物理槽位别名 SUBSYSTEM=="block", KERNEL=="sd*[!0-9]", ENV{ID_SERIAL_SHORT}=="ZR5CTR4V", SYMLINK+="encl1", ENV{UDISKS_PRESENTATION_NAME}="encl1 (Slot 1)" SUBSYSTEM=="block", KERNEL=="sd*[!0-9]", ENV{ID_SERIAL_SHORT}=="XXXXXXX", SYMLINK+="encl2", ENV{UDISKS_PRESENTATION_NAME}="encl2 (Slot 2)" # 以此类推,写完8个槽位的映射
KERNEL=="sd*[!0-9]":确保只匹配磁盘本身(比如sda、sdb),不匹配分区(sda1、sdb2)SYMLINK+="encl1":创建/dev/encl1软链接UDISKS_PRESENTATION_NAME:让lsblk等工具显示友好的槽位名称
方式二:基于物理路径自动映射(更自动化)
如果你的JBOD的ID_PATH包含槽位信息,可以写更通用的规则:
# 从ID_PATH提取槽位编号,生成别名 SUBSYSTEM=="block", KERNEL=="sd*[!0-9]", ENV{ID_PATH}=="*scsi-0:0:[1-8]:0", SYMLINK+="encl%E{ID_PATH_CLEAN}"
这里需要根据你的实际ID_PATH格式调整匹配规则,比如把[1-8]替换成你的槽位范围,ID_PATH_CLEAN会提取路径里的槽位数字。
步骤3:让udev规则生效
写完规则后,执行以下命令重新加载规则并触发设备事件:
udevadm control --reload-rules && udevadm trigger
然后检查/dev/目录下是否生成了encl1到encl8的软链接:
ls -l /dev/encl*
步骤4:让ZFS使用新的槽位别名
现在需要让ZFS池切换到使用这些别名,步骤如下:
- 先导出当前ZFS池(确保没有进程在使用池里的文件):
zpool export backup_pool
- 重新导入池,指定扫描
/dev目录让ZFS识别新的别名:
zpool import -d /dev backup_pool
- 验证效果:执行
zpool status backup_pool,现在应该能看到encl1这类槽位别名,而不是/dev/sd*了。
步骤5:让lsblk显示槽位别名
执行lsblk -l -o NAME,SIZE,SYMLINKS,MOUNTPOINT,就能看到每个磁盘对应的encl*别名。如果想让lsblk默认显示这个信息,可以修改/etc/lsblk.conf,添加:
OPTIONS="-o NAME,SIZE,SYMLINKS,MOUNTPOINT"
注意事项
- 不要删除
/dev/sd*节点:系统内核仍需要它们,我们的别名只是软链接,不影响原设备的正常工作。 - 更换磁盘后要更新规则:如果某槽位换了新硬盘,记得把对应的序列号更新到udev规则里。
- 规则优先级:确保你的规则文件名以90+开头,避免被默认udev规则覆盖。
备注:内容来源于stack exchange,提问作者dimus




