网络文件系统的掉线监控(inotifywait)
问题背景:
在工作中遇到有批量的网络文件系统(100个左右)挂载在同一个机器上,结果一个频发的问题是:
时不时总有一些网络文件系统不明原因的掉线,时间也不确定,当然找到根本原因并解决才是王道,然而总是有些情况无法确定根本原因,而就算确定了也不一定就100%能解决, 比如网络问题,谁能保证100%的网络可靠性呢。 所以解决这个 掉线的问题就被提上了日程.
监控方式:
要解决问题,首先要发现问题,所以首先就是要有监控,第三方工具当然很多,这里介绍用系统自带的inotifywait来进行监控. 大致的思路如下:
inotifywait 可以从指定的配置文件中,读取文件/文件夹的路径,然后监控文件/文件夹 所属文件系统的unmount 事件,然后可以把 事件记录到指定文件中, 看起来应该不错。然而面临如下的问题:
A.
默认情况下inotifywait 监控到对应的umount事件之后会退出, 因为我们要批量的监控,所以当然不能因为一个挂载点的umount就退出 inotifywait, 所以需要在umount触发后继续监控. 这个通过inotify的参数 -m 就可以解决.
B.
被监控的”unmount“事件,只会被触发一次,就算持续监控,那么也只会触发一次,比如有一个cifs 共享挂载在 /mnt/win_logs , 那么当第一次发生了unmount的时候,会被inotifywait 监控到,后面自动恢复了 mount或者手动重新进行了mount, 在重新mount之后,如果又发生了unmount, 这时候就不会触发 inotifywait的 记录了。
这样的话,只监控第一次很明显不符合我们的要求啊.我们需要一个持续的监控啊.
鄙人的解决思路如下:
要想让 inotifywait 可以持续的监控unmount, 那么最好就是 发生了unmount之后,触发 对应的mount事件,这时候inotifywait将会自动退出,确保成功mount之后. 然后再次启动inotifywait 进行监控。这个思路看起来没有什么问题,但是在实际中一旦有多个挂载点同时出发了unmount事件,那么只有第一个unmount事件会触发相应挂载点的mount,而其他的挂载点则因为inotify已经退出,所以无法实现mount,因此再次启动的inotifywait事件就无法监控到正确状态挂载状态. 所以这个方法就被排除了.
既然在持续monitoring 的情况下, 可以正确监控到第一次发生unmount的情形,所以可以考虑在发生了unmount的情况后,把inotifywait强制停掉,然后把unmount的状况解决掉, 也就是重新mount好,最后再次启动inotiywait. 因为inotifywait是并发工作的,所以如果同时发生了unmount, 那么都会记录到 对应的结果文件中的,所以需要监控 结果文件的变化。
大致的流程如下:
- 获取inotifywait结果文件的修改日期, 记录为 m1
- 启动inotifywait进行监控,并获取其进程pid,记录为p1(如果以 -d 方式启动,那么路径都必须用绝对路径)
- sleep 一段时间(比如10s),获取 结果文件的修改时间, 记录为m2
- 比较m1,m2, 如果两者不等,那么表示等待时间内发生了 unmount. 同时用fuser来判断是否inotifywait依然占用着 结果文件,如果依然占用着结果文件,那么表示文件还没有写完,需要等待. 如果m1,m2两者相等,那么就回到步骤3继续进行等待,因为没有发生unmount,所以什么操作都不需要.
- 在inotifywait 已经释放了对结果文件的占用,并且结果文件有了更新(m1和m2不等),那么此时可以强制终止p1. 并且进行Mount操作。 mount 成功完成后,清空结果文件. 至此,一个循环完成.
- 重复步骤1到5.
BUG:
在终止当前的inotifywait,mount 丢失的挂载点,到再次成功启动inotifywait,这个时间段如果发生了unmount,那么是记录不到的