it-swarm.cn

如何确定哪些进程阻止了设备的卸载?

有时,我想用umount /run/media/theDrive卸载SB设备,但出现drive is busy错误。

如何确定哪些进程或程序正在访问设备?

70
Stefan

采用 lsof | grep /media/whatever找出正在使用的挂载。

另外,请考虑umount -l(延迟卸载),以防止清理时新进程使用驱动器。

70
Peter Eisentraut

在大多数情况下,最好使用的命令是 lsof (“ l i s t o pen- f iles”)。

lsof +f -- /media/usb0

其中/media/usb0是要卸载的USB驱动器或其他文件系统的安装点。 +f --告诉lsof将后续参数视为安装点;它通常(但并非总是)自行管理,因此lsof /media/usb0也可以工作。这会找到打开的文件(甚至是未链接的文件),内存映射的文件,当前目录以及一些晦涩的用法。您需要以root用户身份运行命令以获取有关其他用户进程的信息(我认为在某些地方lsof必须以root用户身份运行)。

Lsof无法找到某些用途;这些在可移动媒体上并不常见。它们包括:

  • 挂载点:如果/foo是挂载点,则无法卸载/foo/bar
  • 挂载设备:如果/foo是已挂载的块设备或循环挂载的常规文件,或者它是Linux绑定挂载的源,则无法卸载/foo/bar
  • NFS导出:lsof不会检测到内核NFS服务器已导出树。

紧急情况下可以使用的另一个命令是fuser,它仅列出设备上带有打开文件的进程的PID:

fuser -m /media/usb0
37

打开文件

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

_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>/
_

对于环回安装( 感谢Stephen Kitt ),还请检查以下输出:

_losetup -la
_

匿名索引节点(Linux)

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

  • 临时文件(带有_O_TMPFILE_的open
  • inotify 手表
  • [eventfd]
  • [事件投票]
  • [timerfd]

这些是口袋妖怪中最难以捉摸的一种,在lsofTYPE列中以_a_inode_出现(在 lsof手册页中没有说明 ) 。

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

_lsof | grep a_inode
_

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

inotify手表(Linux)

此注释 解释了为什么inotify不应该防止卸下,但是 此注释 描述了其中的情况它

卸载可以挂在vx_softcnt_flush()调用中。之所以会发生挂起,是因为inotify监视程序会递增_i_count_变量,并使_v_os_hold value_保持升高,直到inotify监视程序释放保留为止。

9
Tom Hale

您可以像Peter所说的那样使用lsof,或者如果您确定只想杀死所有这些东西并将其卸载,则可以执行以下操作:

fuser -Mk /mnt/path
umount /mnt/path
8
pioto

如果使用GNOME,则通过Nautilus卸载将显示一条消息,指出哪个进程仍在使用驱动器,以及正在使用的文件。

alt text

5
tshepang

对于(至少)OpenBSD:

$ fstat /mnt/mountpoint

例如(使用doas作为根执行fstat,否则我们只会看到自己的进程):

$ doas fstat /usr/ports
USER     CMD          PID   FD MOUNT        INUM MODE         R/W    SZ|DV NAME
_pbuild  make       15172   wd /usr/ports  3923598  drwxrwxr-x     r     1536 /usr/ports/
_pbuild  make       40034   wd /usr/ports  3923598  drwxrwxr-x     r     1536 /usr/ports/

在这种情况下,我将无法卸载/usr/ports直到用户_pbuild已完成这两个make进程的运行。

1
Kusalananda