如何卸载繁忙的设备

时间:2011-10-24 16:22:30

标签: linux umount

我有一些samba驱动器,每天都有多个用户访问。我已经有代码来识别共享驱动器(来自SQL表)并将它们安装在一个特殊目录中,所有用户都可以访问它们。

我想知道,如果我从我的SQL表中删除一个驱动器(有效地使其脱机)如何,甚至是,有办法卸载繁忙的设备?到目前为止,我发现任何形式的umount都不起作用。

忽略破坏数据的可能性 - 是否可以卸载当前正在读取的设备?

13 个答案:

答案 0 :(得分:342)

YES!有一种方法可以立即分离繁忙的设备(即使它很忙,也无法强行卸下)。您可以稍后清理所有内容:

umount -l /PATH/OF/BUSY-DEVICE
umount -f /PATH/OF/BUSY-NFS(NETWORK-FILE-SYSTEM)

注意:

  1. 这些命令可能会中断正在运行的进程,导致数据丢失或损坏打开的文件。访问目标DEVICE / NFS文件的程序可能会抛出错误,或在强制卸载后无法正常工作。
  2. 尝试在未安装的文件夹/驱动器/设备中执行这些命令。

答案 1 :(得分:77)

如果可能,让我们找到/识别繁忙的进程,终止进程,然后卸载samba共享以最大限度地减少损坏。

  • lsof | grep '<mountpoint of /dev/sda1>'(或无论安装的设备是什么)

  • pkill target_process(按名称杀死忙碌程序| kill PID | killall target_process

  • umount /dev/sda1(或无论安装的设备是什么)

答案 2 :(得分:46)

当您尝试卸载时,请确保您不在安装的设备中。

答案 3 :(得分:39)

尝试以下操作,但在运行之前请注意,-k标志将终止正在运行的进程,导致设备忙碌。

-i标记会在杀死之前询问fuser

fuser -kim /address  # kill any processes accessing file
unmount /address

答案 4 :(得分:7)

避免使用umount -l

在撰写本文时,最受好评的答案建议使用umount -l

umount -l is dangerous or at best unsafe。总结:

  • 它实际上并没有卸载设备,只是从名称空间中删除了文件系统。打开文件的写入可以继续。
  • 它可能导致btrfs文件系统损坏

变通/替代

umount -l的有用行为是通过绝对路径名隐藏文件系统,以防止对其进行进一步的访问。

可以通过在要卸载的目录上安装具有权限000的空目录来实现相同的行为。

然后,对安装点下面的文件名的任何新访问都将以零权限进入新覆盖的目录-从而防止了新的卸载阻止程序。

请先尝试remount,ro

要解锁的主要卸载成就是只读的重新装载。当您获得remount,ro徽章时,就会知道:

  1. 所有未决数据已写入磁盘
  2. 将来所有的写尝试都将失败
  3. 如果您需要物理断开设备连接,则数据处于一致状态。

mount -o remount,ro /dev/device is guaranteed to fail if there are files open for writing,所以请尝试尝试。朋克,您可能会感到幸运!

如果您不走运,请仅关注processes with files open for writing

lsof +f -- /dev/<devicename> | awk 'NR==1 || $4~/[0-9]+[uw -]/'

然后,您应该能够以只读方式重新安装设备并确保状态一致。

如果此时您无法重新安装只读,请调查列出的here的其他可能原因。

解锁的只读重装成就?☑

恭喜,您在挂载点上的数据现在是一致的,并且可以防止将来写入。

为什么fuser不如lsof

为什么不更早使用fuser?可以,但是fuser是在目录而不是 device 上运行的,因此,如果要从文件名空间中删除挂载点,并且仍然使用fuser,您需要:

  1. 暂时将带有mount -o bind /media/hdd /mnt的安装点复制到另一个位置
  2. 隐藏原始安装点并阻止名称空间:

方法如下:

null_dir=$(sudo mktemp --directory --tmpdir empty.XXXXX")
sudo chmod 000 "$null_dir"

# A request to remount,ro will fail on a `-o bind,ro` duplicate if there are
# still files open for writing on the original as each mounted instance is
# checked.  https://unix.stackexchange.com/a/386570/143394
# So, avoid remount, and bind mount instead:
sudo mount -o bind,ro "$original" "$original_duplicate"

# Don't propagate/mirror the empty directory just about hide the original
sudo mount --make-private "$original_duplicate"

# Hide the original mountpoint
sudo mount -o bind,ro "$null_dir" "$original"

您将拥有:

  1. 原始名称空间被隐藏(无法打开更多文件,问题不会变得更糟)
  2. 重复的绑定安装目录(与设备相对) 运行fuser

这更令人困惑 [1] ,但允许您使用:

fuser -vmMkiw <mountpoint>

会交互式地要求杀死打开待写入文件的进程。当然,您可以完全不隐藏安装点来执行此操作,但是上面的umount -l模仿点没有任何危险。

-w开关仅限于写入过程,而-i是交互式的,因此在只读重新挂载后,如果您很着急,可以使用:

fuser -vmMk <mountpoint>

在挂载点下打开文件的情况下杀死所有剩余进程。

希望此时您可以卸载设备。 (如果您已在顶部绑定模式umount的目录,则需要在安装点上运行000两次。)

或使用:

fuser -vmMki <mountpoint>

以交互方式杀死其余阻止卸载的只读进程。

该死,我仍然得到target is busy

打开的文件不是唯一的卸载阻止程序。有关其他原因及其补救措施,请参见herehere

即使您有一些潜伏的gremlin阻止了您完全卸载设备,也至少使您的文件系统处于一致状态。

然后,您有两种选择来卸载设备:lsof路由或XXX:

  1. lsof +f -- /dev/device将列出包含文件系统的设备上所有带有打开文件的进程,并将其杀死。

[1]使用mount --move的过程比较麻烦,但这需要mount --make-private /parent-mount-point which has implications。基本上,如果将挂载点挂载在/文件系统下,则要避免这种情况。

答案 5 :(得分:6)

结帐umount2

  

Linux 2.1.116添加了umount2()系统调用,与umount()一样,   卸载目标,但允许其他标志控制   操作行为:

     

MNT_FORCE(自Linux 2.1.116起)即使忙碌也强制卸载。 (仅适用于   NFS安装。)MNT_DETACH(自Linux 2.4.11起)执行延迟卸载:   使挂载点不可用于新访问,实际上   当挂载点不再忙时执行卸载。 MNT_EXPIRE   (自Linux 2.6.8起)将挂载点标记为已过期。如果是挂载点   当前没有使用,然后用这个初始调用umount2()   标志因EAGAIN错误而失败,但将挂载点标记为   过期。只要不访问挂载点,挂载点就会保持过期   任何过程。指定MNT_EXPIRE的第二个umount2()调用将卸载   过期的挂载点。这两个标志都不能指定   MNT_FORCE或MNT_DETACH。返回值

     

成功时,返回零。出错时,返回-1,错误是   适当地设定。

答案 6 :(得分:6)

使用exportfs -v检查导出的NFS文件系统。如果找到,请使用exportfs -d share:/ directory删除。这些不会出现在fuser / lsof列表中,可以防止umount成功。

答案 7 :(得分:4)

我最近也有类似的需要卸载,以便使用 gparted 更改它的标签。

/dev/sda1 正在通过 /etc/fstab 挂载为 /media/myusername。当尝试卸载失败时,我研究了错误。 我忘记先卸载带有 /dev/hda1 挂载点的双分区 U 盘。

我按照建议尝试了 'lsof'。

$ sudo lsof | grep /dev/sda1

其输出为:

lsof:警告:不能 stat() fuse.gvfsd-fuse 文件系统 /run/user/1000/gvfs
输出信息可能不完整。
lsof:警告:无法 stat() 融合文件系统 /run/user/1000/doc
输出信息可能不完整。

由于 lsof 发出了两个保险丝警告,我在 /run/user/1000/* 中摸索了一下,并猜测它可能是打开的文件或挂载点(或两者)干扰了事情。

由于挂载点位于 /media/,我再次尝试:

$ sudo lsof | grep /media

同样的两个警告,但这次它返回了额外的信息:

bash 4350 myusername cwd DIR 8,21 4096 1048577 /media
sudo 36302 root cwd DIR 8,21 4096 1048577 /media
grep 36303 myusername cwd DIR 8,21 4096 1048577 /media
lsof 36304 root cwd DIR 8,21 4096 1048577 /media
lsof 36305 root cwd DIR 8,21 4096 1048577 /media

我仍然在挠头,就在此时我想起了从 USB 端口伸出的拇指驱动器。也许抓挠有帮助。

所以我卸载了拇指驱动器分区(卸载一个会自动卸载另一个)并安全地拔下拇指驱动器。这样做之后,我能够卸载 /dev/sda1(不再挂载任何东西),用 gparted 重新标记它,重新挂载驱动器和拇指驱动器,没有任何问题。
培根得救了。

答案 8 :(得分:3)

有人提到如果您使用终端,并且当前目录位于要卸载的路径内,则会出现错误。
作为补充,在这种情况下,您的lsof | grep path-to-be-unmounted必须具有以下输出:

bash ... path-to-be-unmounted

答案 9 :(得分:1)

以防万一某人具有相同的铅。 :

我无法卸载chroot监狱的挂载点(此处为/mnt)。

这是我键入要调查的命令:

$ umount /mnt
umount: /mnt: target is busy.
$ df -h | grep /mnt
/dev/mapper/VGTout-rootFS  4.8G  976M  3.6G  22% /mnt
$ fuser -vm /mnt/
                     USER        PID ACCESS COMMAND
/mnt:                root     kernel mount /mnt
$ lsof +f -- /dev/mapper/VGTout-rootFS
$

您会注意到,即使lsof也不返回任何内容。

然后我想到了输入:

$ df -ah | grep /mnt
/dev/mapper/VGTout-rootFS  4.8G  976M  3.6G  22% /mnt
dev                        2.9G     0  2.9G   0% /mnt/dev
$ umount /mnt/dev
$ umount /mnt
$ df -ah | grep /mnt
$

这里是我创建的/mnt/dev/dev的绑定,能够从chroot监狱修复我的系统。

卸载后,我的铅。现在已解决。

答案 10 :(得分:0)

任何有效的方法是编辑/etc/fstab,添加noauto标志并重新启动计算机。设备无法安装,当您完成任何操作后,请删除标记并重新启动。

答案 11 :(得分:0)

利基答案:

如果该设备上有一个zfs池,至少当它是基于文件的池时,lsof将不会显示使用情况。但是您只需运行

sudo zpool export mypoo

然后卸载。

答案 12 :(得分:0)

在文件夹中多个安装

另一个原因可能是主安装文件夹中的辅助安装,例如在为嵌入式设备使用SD卡之后:

# mount /dev/sdb2 /mnt       # root partition which contains /boot
# mount /dev/sdb1 /mnt/boot  # boot partition

卸载/ mnt将会失败:

# umount /mnt
umount: /mnt: target is busy.

首先,我们必须卸载引导文件夹,然后卸载根目录:

# umount /mnt/boot
# umount /mnt