如何卸载繁忙的设备

我有一些samba驱动器,每天都有多个用户访问。我已经有了识别共享驱动器(从SQL表)的代码,并将它们挂载到所有用户都可以访问它们的特殊目录中。

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

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

1151388 次浏览

查看umount2:

Linux 2.1.116增加了umount2()系统调用,它和umount()一样, 卸载目标,但允许附加标志控制 操作行为:

MNT_FORCE (since Linux 2.1.116)强制卸载即使繁忙。(仅供 NFS挂载)。执行延迟卸载: 使挂载点对新访问不可用,实际上 当挂载点不再繁忙时执行卸载。MNT_EXPIRE (从Linux 2.6.8开始)将挂载点标记为过期。如果挂载点 当前没有使用,那么初始调用umount2()与此 标志失败,错误为EAGAIN,但将挂载点标记为 过期了。只要没有访问挂载点,它就会一直过期 通过任何过程。第二个umount2()调用指定MNT_EXPIRE卸载 一个过期的挂载点。此标志不能用任意一个指定 MNT_FORCE或MNT_DETACH。返回值< / p >

成功返回0。如果出错,返回-1,errno 适当的设置。< / p >

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

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

  • pkill target_process(通过| kill PID | killall target_process杀死busy proc.)

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

是的 ! !有一种方法可以立即分离繁忙的设备-即使它繁忙且不能强制卸载。你可以稍后清理:

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

注意/警告

  1. 这些命令可能会中断正在运行的进程,导致数据丢失或损坏打开的文件。在强制卸载后,访问目标DEVICE/NFS文件的程序可能会抛出错误或无法正常工作。
  2. 在挂载路径(文件夹/驱动器/设备)内部执行。首先,你可以使用pwd命令来验证你当前的目录路径(它不应该是挂载的路径),然后使用cd命令来退出挂载的路径-稍后使用上述命令卸载它。

使用exportfs -v检查导出的NFS文件系统。如果发现,使用exportfs -d share:/directory删除。这些不会在fuser/lsof列表中显示,并且会阻止umount成功。

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

-i标志使fuser在杀死之前询问。

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

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

当一切正常时,另一种选择是编辑/etc/fstab,添加noauto标志并重新启动机器。设备将不会被安装,当你完成任何操作时,移除标志并重新启动。

避免umount -l

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

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

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

绕开/替代方案

umount -l的有用行为是通过绝对路径名隐藏文件系统,从而最大限度地减少进一步使用挂点。

通过在要卸载的目录上挂载具有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 -]/'

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

如果此时不能重新挂载只读,请调查列出的其他一些可能原因在这里

只读重新挂载成就解锁🔓☑

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

为什么fuser不如lsof

为什么不早点使用fuser呢?好吧,你可以这样做,但是fuser操作的是目录,而不是设备,所以如果你想从文件名空间中删除挂载点,并且仍然使用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. 一个重复的绑定挂载目录(相对于一个设备)
  3. .执行fuser

这是更卷积的__abc0,但允许你使用:

fuser -vmMkiw <mountpoint>

它将交互式地要求杀死打开文件进行写入的进程。当然,你完全可以在不隐藏挂载点的情况下这样做,但上面的例子模仿了umount -l,没有任何危险。

-w开关限制写入进程,而-i是交互式的,所以在只读重新挂载之后,如果你很着急,你可以使用:

fuser -vmMk <mountpoint>

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

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

或者使用:

fuser -vmMki <mountpoint>

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

该死,我仍然得到target is busy!

打开的文件并不是唯一的卸载阻止程序。参见在这里在这里了解其他原因及其补救措施。

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

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


使用mount --move比较简单,但这需要mount --make-private /parent-mount-point,这意味着。基本上,如果挂载点挂载在/文件系统下,您将希望避免这种情况。

有人提到,如果你正在使用终端,而你的当前目录在你想要卸载的路径中,你会得到错误 作为补充,在这种情况下,你的lsof | grep path-to-be-unmounted必须有以下输出:

bash ... path-to-be-unmounted

众答:

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

sudo zpool export mypool

然后卸载。

文件夹内的多个挂载

另一个原因可能是在主挂载文件夹内的辅助挂载,例如,在您为嵌入式设备处理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

以防有人和你一样。:

我无法卸载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监狱中修复我的系统。

在umounting之后,我的pb。现在解决了。

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

/dev/sda1通过/etc/fstab以/media/myusername挂载。当尝试卸载失败时,我研究了这个错误。我忘了先卸载一个挂载点在/dev/hda1上的双分区u盘。

我给了'lsof'一个建议。

$ sudo lsof | grep /dev/sda1

其结果是:

lsof:警告:不能stat()熔断。Gvfsd-fuse file system /run/user/1000/gvfs
.使用实例
.输出信息可能不完整 lsof: WARNING: can't stat() fuse file system /run/user/1000/doc
. bat /run/user/1000/doc
. bat

.输出信息可能不完整

由于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

仍然抓着我的头,在这一点我记得u盘伸出USB端口。也许是抓挠起了作用。

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

sudo fusermount -u -z <mounted path>

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

在unmount filesysem之前。我们需要检查是否有任何进程持有或使用文件系统。这就是为什么它显示设备繁忙或文件系统正在使用。 查看文件系统所使用的进程

fuser -cu /local/mnt/

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

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

ps -ef | grep 1725 & lt;——比;ps -ef | grep <pid>

kill -9 pid

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

在我的例子中,我无法卸载挂载到AFP共享目录的分区。(分享到Apple bonjour/avahi mdns世界) 我把服务器上的所有登录都移动到它们的主目录;我把所有远程连接的mac电脑都移到了其他目录下。 即使使用umount -f,我仍然无法卸载分区 所以我重启了服务器上的netatalk守护进程。
(/etc/netatalk/afp.conf中有共享分配) 日志含义netatalk重启后umount成功,没有-f.