背景
如果在 PC 上安装过 Linux,那么通常会遇到过硬件设备无法发现的问题,这类问题最终都可以通过 google 来解决掉。那么当我们在服务器场景下,如何做到设备自动发现且在设备发现后执行某些动作呢?
最近看了几个关于存储系统的 Operator 部分实现,记录一下。
命令行
最简单的肯定是我们写一个循环,永远检测我们要发现的设备,比如 lsblk 可以列举当前服务器所有 block 设备,那么我们就在循环内部执行 lsblk,diff 每次执行的结果,如果有新的设备,那么执行某些操作。
lsblk 是通过读取 /sys/block 下的具体目录判断的,那么我么也可以直接读取该路径下的目录来实现。
如果是网络设备也是一样,我们可以在循环内部执行 ip link list
来获取所有网络设备。
UDEV
照常先引用维基百科的解释:
udev 是Linux kernel 2.6系列的设备管理器。它主要的功能是管理/dev目錄底下的设备节点。它同时也是用来接替devfs及hotplug的功能,这意味着它要在添加/删除硬件时处理/dev目录以及所有用户空间的行为,包括加载firmware时。
如果你的 OS 是通过 systemd 来管理所有进程的话,那么可以发现一个服务叫做 systemd-udevd
,这个是 udev 的守护进程:
1 | [root@node90 19:58:10 ~]$systemctl status systemd-udevd |
udev 可以让我们对硬件的使用限制大大减少,除了常见的硬件发现,还有一个场景就是网卡改名,比如 82599 网卡,在 CentOS 上大概率识别为 enp4s0f1
之类的网卡名,如果我们想要统一服务器网卡名称,那么我们可以通过设置 udev 规则,匹配 mac 地址来做到,这里不细说。
我们来说说 udev 自动发现设备。udev 提供了完整的工具集,可以共我们使用,比如 udevadm:
1 | [root@node 20:02:41 ~]$udevadm --help |
我们可以通过 udevadm 来查看硬件设备的具体信息,也可以通过 udevadm 来进行显示的设备监控。
除了通过 udevadm 命令,我们还可以通过编写 udev 配置文件来实现设备发现后的具体动作,在 /etc/udev/rules.d/
路径下可以防止我们自己的配置文件。
比如我们想实现功能:节点上插入磁盘后,执行某条命令,那么我们可以这么定义:
1 | [root@node90 20:05:21 rules.d]$pwd |
这个规则具体含义为:
当检测到设备
sd[a-z]
, 类型为block
且动作为add
,那么执行echo add
操作。当检测到设备
sd[a-z]
,类型为block
且动作为remove
,那么执行echo add
操作。
我们来看一个具体的例子,执行 udevadm monito
来监控节点设备,然后插入一块 scsi 磁盘:
1 | [root@node 20:14:04 rules.d]$udevadm monitor |
可以看到 udev 监控到了设备名称,设备 pci id 以及设备触发的动作,这里与我们定义的规则相对应。
具体使用
命令行
在 OpenShift 的 local storage operator 中,是通过不断的执行 lsblk 比较结果来判断的,相关代码如下:
1 | // Run and create disk config |
UDEV
在 Rook 项目中,除了通过 lsblk 来获取设备,还监控了 udev 规则,具体代码如下:
1 |
|