@tony-yin
2017-09-06T14:29:14.000000Z
字数 1871
阅读 1816
Magicloud
| env | udev monitor | UI data | disk alias | device | lsblk | mount info | mount point |
|---|---|---|---|---|---|---|---|
| normal | - | /dev/sdg1 | osd4-data | /dev/sdg | exist | exist | /data/osd.1 |
| first pull | remove sdg | empty | remove | remove | remove | exist | exist, readerror |
| first plug | add sdd | /dev/sdd1 | osd4-data | /dev/sdd | exist | exist | exist, readerror |
| second pull | no remove | empty | osd4-data | /dev/sdd | not change | exist | exist, readerror |
| second plug | All Not Change | - | - | - | - | - | - |
| clear mount | - | - | exist | - | exist | remove | change style |
| third pull | remove sdd | empty | remove | remove | remove | remove | change style |
| third plug | add sdd | /dev/sdd1 | osd4-data | /dev/sdd | exist | exist | exist, readerror |









通过上面的表格和图片,如果拔盘前没有卸载mount链接,那么可以发现:
sdf,那么就改名为sdglsblk显示device列表不会变化,alias name也是不会变化device列表不会变化,udev monitor不会接收到任何设备的删除的事件信息device列表不会变化,udev monitor不会接收到任何设备的添加的事件信息如果清除了mount信息,插拔变得正常起来
udev可以正常接收设备添加和删除的信息lsblk可以正常显示设备列表,会随着磁盘的拔盘而更新显示,alias name也是如此sdd所以针对一块硬盘的拔插只要做好即时清除mount就够了,那么这个时候拔另外插槽的一块盘呢?
结果是:
udev感知到(remove 当前磁盘名),device列表和alias name消失 udev感知到(add sdg),device增加了sdg,alias name增加,没有变化mount信息后,插盘:无反应alias name: 无反应目前来看,只要拔盘超过两块,一旦第二块盘的磁盘名称变了跟之前名称不一样,那么之后再怎么清理mount信息或者反复拔插都不会被udev感知到
理论上来说,要实现硬盘热替换,那就得保证udev每次都能检测到硬盘的插入,拔盘检测倒不是那么重要,
针对这种情况,目前没发现什么比较好的解决方案,唯一一种也是我当前采用的方案,在检测拔盘事件时会触发一个脚本,做拔的盘的mount信息的检查,如果存在mount信息,那么就umount掉,这是一种比较完美的场景,也就是说要保证每次插盘前,当前盘在系统中都不存在任何mount信息
这种方案还是太完美化了,还需要大量的测试,期望能找出更能经得起推敲的方案
测试过程中偶然发现每次硬盘插入如果被udev感知到,也会执行大量的udev rules,其中包括创建设备,建立连接,建立连接这个事情就包括硬盘分区的alias,而我们感知到磁盘设备插入执行脚本在这之前,找了一系列的方案,都没能够使得让脚本在它alias之后再执行
这里有一份官方的解释:http://www.reactivated.net/writing_udev_rules.html#external-run
至于为什么脚本依赖这个别名,那是因为系统存的data path还是journal path都是以别名的形式,如果我们能够在别名之后执行脚本,那么理想情况下系统db之前存的别名会自动和插入的盘匹配建立连接,不需要我们再做过多的事情,否则我们得在每次创建osd的时候再存原始路径,记录分区信息等等,还有/etc/fstab存的都是别名,这样就导致有些操作无法进行,还有一些其他的矛盾暂时还没想到
