一台 CentOS 7 上挂了四块云盘,用 udev 规则按序列号把盘绑成 /dev/data1 到 /dev/data4,某次重挂之后 data2 上出现了别的业务数据,脚本照样写进去了。

真正麻烦的地方在于,几个原因的现象几乎一样。云盘卸载再挂载后序列号变了,旧规则匹配不到设备,新盘被 udev 按默认顺序命名;规则写的是 KERNEL 而不是 SUBSYSTEM,匹配范围过宽;规则文件命名顺序靠后,被更早加载的默认规则覆盖;没有重新触发 udev,新设备只用旧缓存生成节点。

先看设备序列号与当前软链

lsblk -o NAME,SERIAL,SIZE,MOUNTPOINT && ls -l /dev/disk/by-id/ | grep -i virtio

接着用 by-id 路径确认绑定的稳定性

udevadm info --query=all --name=/dev/vdb | grep -i serial

然后按序列号重写规则并限定子系统

printf 'SUBSYSTEM=="block", KERNEL=="vd*", ATTRS{serial}=="abc123", SYMLINK+="data2", OWNER="mysql"\n' > /etc/udev/rules.d/70-data2.rules

剩下的就是重新触发规则并核对软链

udevadm control --reload && udevadm trigger --subsystem-match=block && ls -l /dev/data2

改完先别撤,确认这几项。/dev/data2 指向的块设备序列号与规则一致,挂载后 df 显示的容量与预期相符,业务校验脚本读到的确实是本业务的数据。

补一句。云盘的序列号在卸载重挂后可能变化,更稳妥的做法是用文件系统 UUID 或标签挂载;绑定规则改完必须重新触发并重启验证。报错文案容易误导,真正的原因往往在相邻那一层的日志里。

作者 9823189