401

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

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

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

4

16 回答 16

674

的!有一种方法可以立即分离繁忙的设备 - 即使它很忙并且无法强制卸载。您可以稍后清理所有内容:

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

注意/注意

  1. 这些命令可能会中断正在运行的进程,导致数据丢失或损坏打开的文件。访问目标 DEVICE/NFS 文件的程序可能会抛出错误或在强制卸载后无法正常工作。
  2. 不要在安装路径(文件夹/驱动器/设备)本身内执行上述命令。umount首先,您可以使用pwdcommand 来验证您当前的目录路径(不应该是挂载路径),然后使用cdcommand 退出挂载路径 - 稍后使用上述命令卸载它。
于 2013-11-14T04:17:32.083 回答
188

如果可能,让我们定位/识别繁忙的进程,杀死该进程,然后杀死unmountsamba 共享/驱动器以最大程度地减少损坏:

  • lsof | grep '<mountpoint of /dev/sda1>'(或任何安装的设备)

  • pkill target_process(按名称杀死繁忙的进程 | kill PID| killall target_process

  • umount /dev/sda1(或任何安装的设备)

于 2011-10-24T16:27:00.913 回答
127

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

于 2017-04-28T19:05:42.500 回答
69

避免umount -l

在撰写本文时,投票最多的答案建议使用umount -l.

umount -l是危险的或充其量是不安全的。总之:

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

变通/替代

的有用行为umount -l是隐藏文件系统以防止被绝对路径名访问,从而最大限度地减少进一步的 moutpoint 使用。

可以通过挂载一个空目录来实现相同的行为000,该目录对要卸载的目录具有权限。

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

首先尝试remount,ro

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

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

mount -o remount,ro /dev/device 如果有文件打开以进行写入,则保证会失败,因此请直接尝试。你可能感觉很幸运,朋克!

如果您不走运,请仅关注打开文件以进行写入的进程

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

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

如果此时您无法以只读方式重新挂载,请调查此处列出的其他一些可能原因。

只读重装成就解锁☑</p>

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

为什么fuser不如lsof

fuser为什么不早点使用 use呢?好吧,你可以有,但 fuser操作的是directory,而不是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

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

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

然后,您可以使用lsof +f -- /dev/device列出包含文件系统的设备上打开文件的所有进程,然后终止它们。


[1] 使用起来不那么复杂mount --move,但这需要mount --make-private /parent-mount-point具有含义。基本上,如果挂载点挂载在/文件系统下,您会希望避免这种情况。

于 2019-09-26T16:41:39.350 回答
47

尝试以下操作,但在运行之前请注意,该-k标志将终止任何使设备处于忙碌状态的正在运行的进程。

旗帜-ifuser杀戮前先询问。

fuser -kim /address  # kill any processes accessing file
unmount /address
于 2014-06-30T07:44:52.703 回答
8

Check for exported NFS file systems with exportfs -v. If found, remove with exportfs -d share:/directory. These don't show up in the fuser/lsof listing, and can prevent umount from succeeding.

于 2014-04-20T15:02:16.973 回答
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,并适当设置 errno。

于 2011-10-24T16:26:42.203 回答
6

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

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

以下是我键入要调查的命令:

$ 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 监狱中修复我的系统。

卸载后,我的pb。现在解决了。

于 2020-10-01T22:19:56.060 回答
5

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

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

我按照建议尝试了“lsof”。

$ sudo lsof | grep /dev/sda1

其输出是:

lsof: WARNING: can't stat() fuse.gvfsd-fuse 文件系统 /run/user/1000/gvfs
输出信息可能不完整。
lsof: WARNING: can't stat() fuse file system /run/user/1000/doc
输出信息可能不完整。

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

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

$ sudo lsof | grep /media

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

Bash 4350 Myusername CWD DIR 8,21 4096 1048577 /媒体
Sudo 36302根CWD DIR 8,21 4096 1048577 /
MEDIA GREP 36303 MYUSERNAME CWD
DIR 8,21 4096
1048577根 cwd DIR 8,21 4096 1048577 /媒体

我还在摸不着头脑,这时我才想起拇指驱动器从 USB 端口伸出来。也许抓挠有帮助。

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

于 2021-03-16T08:11:48.787 回答
4

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

bash ... path-to-be-unmounted
于 2020-03-30T08:17:04.240 回答
3

在卸载文件系统之前。我们需要检查是否有任何进程持有或使用文件系统。这就是它显示设备繁忙或文件系统正在使用的原因。运行以下命令以找出文件系统使用的进程:

fuser -cu /local/mnt/

它将显示有多少进程持有/使用文件系统。

local/mnt: 1725e(root) 5645c(shasankarora)

ps -ef | grep 1725<-->ps -ef | grep <pid>

kill -9 pid

杀死所有进程,然后您将能够卸载分区/繁忙设备。

于 2021-12-08T17:52:38.643 回答
2

当一切正常时,另一种选择是编辑/etc/fstab、添加noauto标志和重新启动机器。该设备将不会被挂载,当你完成任何操作后,删除标志并再次重新启动。

于 2018-05-31T07:55:04.340 回答
2

利基答案:

如果您在该设备上有一个 zfs 池,至少当它是一个基于文件的池时,lsof不会显示使用情况。但是你可以简单地运行

sudo zpool export mypool

然后卸载。

于 2020-05-17T06:35:32.597 回答
1
sudo fusermount -u -z <mounted path>

注意:不要对路径使用完成,因为这也会冻结终端。

于 2021-09-20T13:34:28.703 回答
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
于 2020-08-30T15:13:02.597 回答
0

就我而言,我无法卸载挂载到 AFP 共享目录的分区。(共享到 Apple bonjour/avahi mdns 世界)我将服务器上的所有登录名移到了他们的主目录;我将所有远程连接的 Mac 移动到其他目录。即使使用 umount -f 我仍然无法卸载分区所以我重新启动了服务器上的 netatalk 守护程序。
(/etc/netatalk/afp.conf 中有共享分配) netatalk 重新启动后,没有 -f 的情况下 umount 成功。

于 2022-01-28T07:06:25.010 回答