@tony-yin
2017-09-06T22:29:14.000000Z
字数 1871
阅读 1562
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
,那么就改名为sdg
lsblk
显示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
存的都是别名,这样就导致有些操作无法进行,还有一些其他的矛盾暂时还没想到