卸载繁忙的设备

Max*_*Max 195 linux umount

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

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

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

Ami*_*rma 393

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

umount -l /PATH/OF/BUSY-DEVICE
umount -f /PATH/OF/BUSY-NFS(NETWORK-FILE-SYSTEM)
Run Code Online (Sandbox Code Playgroud)

注意:

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

  • 注意:`-l`这里是一个小写的`L`(用于"懒惰卸载").(参见[此相关答案](http://stackoverflow.com/a/96288/558008).) (18认同)
  • 有点吓人。我延迟卸载然后重新安装,而其他一些进程仍在访问它。所以我想我最终将它安装到同一个位置两次?不知道那是做什么的。 (4认同)
  • 工作.一个细微差别,如果您通过FTP客户端登录,则必须注销才能成功卸载文件夹. (3认同)
  • `-l` / `--lazy` 不会损坏打开的文件,但在 Linux 上似乎 [你无法知道设备何时实际卸载并可以删除](https://github.com/karelzak/ util-linux/问题/493) (3认同)

Fra*_*dor 94

如果可能的话,让我们找到/识别繁忙的进程,终止进程,然后卸载samba共享以最小化损坏.

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

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

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

  • 这不会返回任何东西.我假设它是因为它是一个网络驱动器,我无法看到其他计算机访问该驱动器的过程.同样处理"fuser"命令. (4认同)
  • 你需要 sudo lsof 才能得到一些结果 (3认同)
  • smb命令实际上已被弃用,并由“ umount.cifs” ....代替,该命令也不起作用。看来我一直忙于无法卸载。 (2认同)

小智 63

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

  • 确实,只是简单地在终端中打开当前文件夹(位于目标设备上)(通过例如cd命令)就可以阻止该进程:) (3认同)
  • 是的,我在设备的目录中运行了一个shell。关闭终端窗口,瞧 (2认同)

Tom*_*ale 58

避免 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 -]/'
Run Code Online (Sandbox Code Playgroud)

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

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

只读重装成就解锁?

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

为什么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"
Run Code Online (Sandbox Code Playgroud)

然后你会有:

  1. 原始命名空间隐藏(无法打开更多文件,问题不会变得更糟)
  2. 在其上运行fuser.

这更复杂[1],但允许您使用:

fuser -vmMkiw <mountpoint>
Run Code Online (Sandbox Code Playgroud)

它将以交互方式要求终止打开文件进行写入的进程。当然,您可以在完全不隐藏挂载点的情况下执行此操作,但是上述模拟方法umount -l没有任何危险。

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

fuser -vmMk <mountpoint>
Run Code Online (Sandbox Code Playgroud)

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

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

或使用:

fuser -vmMki <mountpoint>
Run Code Online (Sandbox Code Playgroud)

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

该死的,我还是明白了target is busy

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

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

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


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

  • 如果 `--lazy` 如此危险,为什么 `umount` 手册页中没有警告呢?它只说“*延迟卸载。现在从文件层次结构中分离文件系统,并在该文件系统不再繁忙时清除对此文件系统的所有引用。*” (4认同)
  • 重新挂载为只读,然后重试卸载会有所帮助。因此,在可能浪费时间进行进一步故障排除之前,请务必先尝试一下。 (2认同)

小智 43

尝试以下操作,但在运行之前请注意该-k标志将终止任何正在运行的进程,以保持设备忙碌.

在杀戮之前,-i国旗会fuser问.

fuser -kim /address  # kill any processes accessing file
unmount /address
Run Code Online (Sandbox Code Playgroud)

  • `lsof | grep'/ dev/<my-device>`没有返回任何内容,但是效果很好!可能还想建议`fuser -m/dev/<my-device>`以防你想要在杀死它之前找出它. (5认同)
  • 运行fuser命令会立即将我与VPS断开连接. (3认同)

sha*_*ora 15

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

fuser -cu /local/mnt/

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

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

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

kill -9 pid

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


end*_*eus 7

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

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

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

$ sudo lsof | grep /dev/sda1
Run Code Online (Sandbox Code Playgroud)

其输出是:

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

由于 lsof 打嗝了两个保险丝警告,我在 /run/user/1000/* 中闲逛,并猜测它可能是打开的文件或安装点(或两者)干扰了事物。

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

$ sudo lsof | grep /media
Run Code Online (Sandbox Code Playgroud)

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

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 /媒体
lsof 36305根 cwd DIR 8,21 4096 1048577 /media

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

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


cho*_*own 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.


小智 6

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


Mar*_*iti 6

sudo fusermount -u -z <mounted path>
Run Code Online (Sandbox Code Playgroud)

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


Seb*_*bMa 5

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

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

以下是我输入的用于调查的命令:

$ 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
$
Run Code Online (Sandbox Code Playgroud)

如您所见,即使不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
$
Run Code Online (Sandbox Code Playgroud)

这是我创建的/mnt/dev绑定,/dev以便能够从 chroot jail 内部修复我的系统。

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