Umount上的繁忙设备


41

我经常在卸载目录时遇到问题:

卸载/ mnt / dir
umount:/ mnt / dir:设备正忙

设备繁忙的原因有很多。有时正在运行的进程具有打开的锁,有时会在之上安装其他目录/mnt/dir

我的问题:

检查为什么无法卸载目录的步骤是什么。

我知道有很多原因,但是可以解释一个特定的解决方案。

[编辑]

[X]在已安装的卷上运行进程。
[X]另一个卷已安装在我们要卸载的卷的顶部
[_] NFS锁定了我们要卸载的卷


Answers:


75

检查的方法是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,但是如果这样做,则有丢失数据的风险。(客户端可能已缓存服务器尚未确认的写入,这些写入将被丢弃。但是,已经告知应用程序写入成功。)


4
请注意,fuser -k非常危险的,因为你会做它作为根,如果你不是确定哪些进程会被杀死了,你可以做真正壮观的损害满不在乎命令
Shadur

1
@Shadur很好,希望您已经在没有-k选项的情况下运行了它,因此您将知道要杀死哪些进程。但我会加一个警告。
derobert 2014年

1
fuser -vm显示“内核安装”。必须做systemctl stop opt.mount而不是手工umount
lkraav

2
由于某种原因,umount -f对我不起作用,但是运行umount -l则可以正常工作。
Firze

感谢有关umount -fNFS 的说明。我的问题是与NFS有关,我的开发机器更改了IP,无法删除共享。
埃里克

19

您应该使用:

sudo umount -l <path>

7
⁺¹,我不知道有什么愚蠢的人会否决它。该-l是什么时候,甚至使用的选项-f不起作用。
Hi-Angel

@ Hi-Angel因为这不是OP的要求?
xhienne

@xheinne堆栈交换不只是要像一个笨拙的机器人那样回答问题,这个答案很有用。许多人也来自Google搜索。我个人认为这很有帮助。操作者应该接受他认为相关的答案,这就是为什么接受按钮存在的原因。
user1735921

6

另一个卷已安装在我们要卸载的卷之上:

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)移动它们


1
是啊谢谢。/ etc / mtab和/ proc / mounts也可以。

嗯,没错,我总是忘记了那些。假设输入“ mount”需要更少的字符(但是要执行更多的资源?)
mveroone 2014年

1
我在笔记本电脑上的某个目录中“永久”安装了一个外部USB存储设备,有时电缆会因错误连接而断开连接。在我阅读此答案之前,将设备重新安装到目录上是一个很大的痛苦(因为“设备繁忙”)。现在我知道使用mount --move olddir newdir。谢谢。
Silvio Levy 2014年

3

打开文件

带有打开文件的进程是常见的罪魁祸首。显示它们:

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

匿名索引节点(Linux)

可以通过以下方式创建匿名索引节点

  • 临时文件(open带有O_TMPFILE
  • 使手表变声
  • [eventfd]
  • [事件投票]
  • [timerfd]

这些是最难以捉摸的神奇宝贝类型,在lsofTYPE列中显示为a_inode(在lsof手册页中未记录 )。

它们不会出现在中lsof +f -- /dev/<device>,因此您需要:

lsof | grep a_inode

有关杀死持有匿名inode的进程,请参阅:列出当前inotify监视(路径名,PID)


1

如何检查NFS是否访问要卸载的目录的问题仍未得到解答。

我只有的是:

检查nfsd是否正在运行:

pidof nfsd

显示客户端挂载的目录:

showmount -a

showmountW / O参数只显示了客户端主机,即使他们是脱机。我认为这是NFS的特殊行为。


1

对我来说,问题是我多次登录(通过ssh),并且在其中一种登录名时,我处于命令提示符下,其中pwd位于从属于安装点的文件夹中。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.