常规umount失败后有3种处理方法:fuser,lsof,和umount -l
fuser:
fuser(find user process)可以帮助识别阻碍卸载文件系统进程,fuser需要系统支持/proc文件系统
直接fuser /mnt/yellowmachine 输出:/mnt/yellowmachine: 23334c 23697c
输出结果中可以很明显看到有哪个进程PID使用指定挂载点了。
从输出中可以看到PID后面跟了个字符c,含义是指明PID相关的与指定挂载点的工作方式,c是最常用的,表明进程使用文件系统中的目录作为它当前的工作目录
不过上面的输出看上去并不友好,甚至都没指明进程的名称,这样可以通过-v的选项让它输出与ps外观类似的信息格式
$ fuser -v /mnt/yellowmachine USER PID ACCESS COMMAND /mnt/yellowmachine: wvh 23334 ..c.. bash wvh 23697 ..c.. emacs
这样就好懂多了,至少知道进程是什么了。在通过fuser获得PID信息后,可以结合ps和egrep可以在结束这个进程前获得更信息的信息
# ps alxww |egrep '23334|23697' 4 1000 23334 23332 20 0 18148 2076 wait Ss pts/13 0:00 -bash 0 1000 23697 23334 20 0 75964 12352 poll_s S+ pts/13 0:00 emacs -nw file2.txt 0 0 23703 23665 20 0 6060 632 - R+ pts/16 0:00 egrep 23334|23697
然后就可以用kill命令手动结束指定进程。
用fuse终结进程:
可以直接使用fuse的 -k选项,加挂载目录名作为参数 直接关掉占用挂载目录的进程
# fuser -k /mnt/yellowmachine /mnt/yellowmachine: 23334c 23697c Could not kill process 23697: No such process
报错是因为23697的emacs是由bash产生的进程(子进程),bash被终止了,这个进程也就直接跟着终止了,所以没办法再被终止了,就报了这么个错
如果要查看的是物理设备,而不是简单的文件系统挂载点的话,必须使用-m 选项,看下面的例子
# fuser -v /opt2 USER PID ACCESS COMMAND /opt2: wvh 23712 ..c.. bash wvh 23753 ..c.. emacs # fuser -v /dev/sdb1 # fuser -vm /dev/sdb1 USER PID ACCESS COMMAND /dev/sdb1: wvh 23712 ..c.. bash wvh 23753 ..c.. emacs
第一条指令显示对文件系统挂载点使用可以得到期望的输出,第二条说明不能直接对设备使用标准的fuser选项,第三条指令演示了-m选项后,你可以获得想要的输出。你可以对第一条或者第三条指令增加-k选项,来终结存在于/dev/sdb1设备上的进程
lsof:
lsof(list open files)显示对一个指定文件系统,目录或者设备所有打开的文件和进程
默认情况下,lsof会列出当前打开的所有文件,共享库,目录,并且提供尽可能多的关于他们的信息。这样输出量是非常大的,所以应该直接指定目录,或者用管道过滤输出。看下面例子:
$ lsof /opt2 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME bash 23334 wvh cwd DIR 8,17 4096 2 /opt2 more 23402 wvh cwd DIR 8,17 4096 2 /opt2 more 23402 wvh 3r REG 8,17 10095 264 /opt2/resume.txt
如果不能卸载/opt2的话,需要将上面这些进程全部终结。
终结前请注意,如果这些进程都没有写文件的话,可以直接终结,如果在写文件,直接终结会导致数据丢失
lsof也能处理NFS及远程文件系统(samba)
umount -l
这个很简单,在在内核2.4.11后mount增加了Lazy选项,该项会自动处理挂载文件系统上未关闭的文件和进程,从而完成卸载
直接umount -l /mount_dir
这个很方便,但马上完成卸载文件系统有点不现实