背景说明:
最近在使用mount远程目录的方式向远程机器写文件操作,当mount 成功后拔除网线或其它断网导致同远程环境之间实现网络断开,在此程序如果去操作被mount的目录程序卡滞,或者程序直接挂起,当恢复网络后程序继续运行。
问题分析:
在mount 需要去写远程文件时,程序会去被mount的目录下进行判断用以存储文件的子目录是否存在,或者直接去创建文件目录,或者创建文件,进而会调用到标准库中的access,mkdir 等标准函数, 而在访问被mount的目录时,实则是通过RPC方式来完成NFS系统的通信(TCP/CIP)。然而如果在设置mount 时没设置客户端侧超时时间或者设置当前服务器没有响应则直接返回等选项时,NFS 系统在使用RPC时可能就会一直尝试链接、接收数据返回被阻塞等情况,进而导致用户态使用到远程RPC 情况时而被阻塞。
验证测试:
首先,准备一个虚拟机环境,之后再虚拟机上分别启用一个Ubuntu 系统一个使用centos 系统,其中一个充当mount 客户端,一个充当mount服务端,之后在客户端侧编辑test code 对被mount 的目录进行验证测试,测试过程中可以使用虚拟机网络设置来模拟实现断网情况。
两个系统中一个ip 为192.168.174.130,一个为192.168.174.131,而且在两者都打开网络连接情况下,是可以ping 通进行通信的,如果将其中一个的网络断开则不能通信。如下图中所示:
两台机器间能正常通信
两台机器间不能正常通信,可以用开模拟拔出网线或者其的断网操作。
在客户端测编辑测试demo ,用以验证access,mkdir 等函数的的阻塞特性,其代码如下:
在网络正常的情况下直接使用 mount -t nfs 192.168.174.130:/home/code/temp /mnt进行mount操作,将服务器端/home/code/temp目录挂载到本地的 /mnt 目录,之后使用test demo 进行操作/mnt 目录,程序可以正常访问,且正常创建file 目录。
在使用mount -t nfs 192.168.174.130:/home/code/temp /mnt 做mount 操作后,将网络断开,再次使用 test demo 进行操作/mnt 目录,程序被卡滞,程序卡死不退出:
当再次把设备状态勾选,使之处于网络正常通讯状态,可继续执行程序。
在使用添加了一些条件限制方式进行mount 操作,mount -t nfs -o soft,intr,timeo=1 192.168.174.130:/home/code/temp /mnt 方式进行mount,则网络正常情况下access,mkdr等函数可以正常的访问被mount 的目录。
在断网的情况下,进行demo test 则程序不会被卡滞,但也无法对其进行正常操作,直接返回错误,任务不可访问。
总结说明:
综合如上述验证测试情况可以确定,序在断网情况下访问被mount 的目录被卡住原因为,主程序在调用access,mkdir 等函数时阻塞了进而导致整个程序卡死。其中其使用access 等函数进行操作卡住还和做mount时所使用的操作选项有关。
如果使用默认参数,不带选项参数则会时程序阻塞、测序卡滞,如果使用一些选项参数来控制nfs 系统的RPC操作,则可以直接以错误方式返回。
阻塞情况: mount -t nfs ip:/server_dir /local_dir
非阻塞情况: mount -t nfs -o soft,intr,timeo=1 ip:/server_dir /local_dir