我经常在卸载目录时遇到问题:
卸载/ mnt / dir umount:/ mnt / dir:设备正忙
设备繁忙的原因有很多。有时正在运行的进程具有打开的锁,有时会在之上安装其他目录/mnt/dir
。
我的问题:
检查为什么无法卸载目录的步骤是什么。
我知道有很多原因,但是可以解释一个特定的解决方案。
[编辑]
[X]在已安装的卷上运行进程。
[X]另一个卷已安装在我们要卸载的卷的顶部
[_] NFS锁定了我们要卸载的卷
我经常在卸载目录时遇到问题:
卸载/ mnt / dir umount:/ mnt / dir:设备正忙
设备繁忙的原因有很多。有时正在运行的进程具有打开的锁,有时会在之上安装其他目录/mnt/dir
。
我的问题:
检查为什么无法卸载目录的步骤是什么。
我知道有很多原因,但是可以解释一个特定的解决方案。
[编辑]
[X]在已安装的卷上运行进程。
[X]另一个卷已安装在我们要卸载的卷的顶部
[_] NFS锁定了我们要卸载的卷
Answers:
检查的方法是fuser -vm /mnt/dir
,它必须以root用户身份运行。它会告诉您哪些进程正在访问挂载点。
一个替代方法是lsof /mnt/dir
,它将显示挂载上的每个打开的文件。再次最好以root身份运行。
您可以以非root用户身份运行其中任何一个,但是输出将仅限于您的进程-即使不会阻止卸载文件系统,也只会静默不显示来自其他用户的进程。
例:
Watt:~# fuser -vm /mnt/Zia/src
USER PID ACCESS COMMAND
/mnt/Zia/src: root kernel mount /mnt/Zia/src
anthony 24909 ..c.. bash
anthony 25041 F.c.. gvim
“访问”字段告诉您如何访问它。在这种情况下,内核会将其用作挂载(嗯,但是仅此一项就可以取消挂载)。bash
将其作为当前工作目录(cd
在卸载之前必须移至其他目录),并且gvim都具有当前目录并已打开文件(需要关闭该gvim)。
Watt:~# lsof /mnt/Zia/src
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
bash 24909 anthony cwd DIR 0,26 12288 3527682 /mnt/Zia/src/perl (zia.vpn.home:/home/anthony/src)
gvim 25041 anthony cwd DIR 0,26 12288 3527682 /mnt/Zia/src/perl (zia.vpn.home:/home/anthony/src)
gvim 25041 anthony 6u REG 0,26 16384 3526219 /mnt/Zia/src/perl/.utf8.c.swp (zia.vpn.home:/home/anthony/src)
在此输出中,您可以看到bash和gvim的当前目录(作为type DIR
)。您还可以查看gvim已打开哪个文件进行写入。
如何提出问题:
fuser
有一个-k
选项,该选项将SIGKILL
使用安装向每个进程发送信号(默认值:)。这是阻止挂载繁忙的一种相当有力的方法。(当然,要小心你SIGKILL
!)
umount
可以-l
选择执行懒惰卸载。该挂载将从文件系统名称空间中删除(因此/mnt/Zia/src
,在示例中,您将不再看到该挂载),但是该挂载保持挂载状态,因此访问该挂载的程序可以继续这样做。当最后一个访问它的程序退出时,卸载实际上会发生。
卸载失败有一个最终的可解决原因,那就是NFS服务器出现故障。您可以在此处使用umount -f
,但是如果这样做,则有丢失数据的风险。(客户端可能已缓存服务器尚未确认的写入,这些写入将被丢弃。但是,已经告知应用程序写入成功。)
fuser -k
是非常危险的,因为你会做它作为根,如果你不是很确定哪些进程会被杀死了,你可以做真正壮观的损害满不在乎命令
-k
选项的情况下运行了它,因此您将知道要杀死哪些进程。但我会加一个警告。
fuser -vm
显示“内核安装”。必须做systemctl stop opt.mount
而不是手工umount
。
umount -f
NFS 的说明。我的问题是与NFS有关,我的开发机器更改了IP,无法删除共享。
您应该使用:
sudo umount -l <path>
-l
是什么时候,甚至使用的选项-f
不起作用。
另一个卷已安装在我们要卸载的卷之上:
mount
如果调用时不带参数也没有选项(除外-v
),该命令可让您知道所有已装入的卷。您可以通过添加一些perl来获得活动安装点的列表:
mount | perl -pe 's/.*on (\S+) type.*/\1/'
然后,只需在要卸载的节点上执行grep,您就会知道在该节点上是否已挂载文件系统。
mount | perl -pe 's/.*on (\S+) type.*/\1/' | grep '/mnt/dir/'
然后,您有两个解决方案。卸载文件系统,或使用mount --move olddir newdir
(内核> 2.5.1)移动它们
带有打开文件的进程是常见的罪魁祸首。显示它们:
lsof +f -- <mountpoint or device>
使用/dev/<device>
而不是会有一个好处 /mountpoint
:挂载点将在后面消失umount -l
,或者可能被覆盖的挂载隐藏。
fuser
也可以使用,但是在我看来lsof
有更有用的输出。但是fuser
,在终止造成戏剧性事件的过程方面很有用,这样您就可以继续生活。
列出文件<mountpoint>
(请参见上面的注意事项):
fuser -vmM <mountpoint>
以交互方式仅杀死打开了可写入文件的进程:
fuser -vmMkiw <mountpoint>
重新安装只读(mount -o remount,ro <mountpoint>
)后,可以安全地杀死所有剩余进程:
fuser -vmMk <mountpoint>
罪魁祸首可能是内核本身。您尝试安装在文件系统上的另一个文件系统umount
将引起麻烦。检查:
mount | grep <mountpoint>/
对于环回安装,还请检查以下输出:
losetup -la
可以通过以下方式创建匿名索引节点:
open
带有O_TMPFILE
)这些是最难以捉摸的神奇宝贝类型,在lsof
的TYPE
列中显示为a_inode
(在lsof
手册页中未记录 )。
它们不会出现在中lsof +f -- /dev/<device>
,因此您需要:
lsof | grep a_inode
有关杀死持有匿名inode的进程,请参阅:列出当前inotify监视(路径名,PID)。
如何检查NFS是否访问要卸载的目录的问题仍未得到解答。
我只有的是:
检查nfsd是否正在运行:
pidof nfsd
显示客户端挂载的目录:
showmount -a
和showmount
W / O参数只显示了客户端主机,即使他们是脱机。我认为这是NFS的特殊行为。