在Linux中显示“设备正忙”,强制卸载的3种方法,

时间:2020-03-05 15:29:04  来源:igfitidea点击:

在某些情况下,当我们尝试卸载文件系统(尤其是NFS)时,它会显示“设备正忙”消息。
当NFS服务器出现一些问题(主要是无法访问)并且我们具有软NFS挂载时,通常会发生这种情况。

如果正常的NFS卸载失败,我们可以尝试不同的方法和选项。
在本教程中,我将解释如何在Linux中执行强制卸载。

在我们的场景中,我们将一个NFS文件系统安装在'/var/theitroad'目录中。

首先使用df命令显示所有已挂载的目录。

# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/vda1 20G 1.3G 18G 7% /
devtmpfs 236M 0 236M 0% /dev
tmpfs 245M 0 245M 0% /dev/shm
tmpfs 245M 8.4M 237M 4% /run
tmpfs 245M 0 245M 0% /sys/fs/cgroup
tmpfs 49M 0 49M 0% /run/user/0
10.128.20.241:/var/theitroad 20G 1.3G 18G 7% /mnt/nfs/theitroad_srv
10.128.20.241:/home 20G 1.3G 18G 7% /mnt/nfs/home_srv

当我们尝试卸载远程分区时,我们收到一条错误消息。
以下示例显示由于设备繁忙而导致卸载失败:

# umount /mnt/nfs/theitroad_srv/
umount.nfs4: /mnt/nfs/theitroad_srv: device is busy

1)使用lsof

lsof(列出打开的文件)命令显示所有打开文件的列表以及在特定文件系统,目录或者设备上与它们关联的进程。

默认情况下,它列出当前打开的所有文件,共享库和目录,并提供有关它们的尽可能多的信息。

其中我们可以使用lsof命令来找到与我们的挂载点相对应的PID(进程ID),然后终止该进程。

# lsof /mnt/nfs/theitroad_srv/
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
bash 24098 root cwd DIR 253,1 4096 519062 /mnt/nfs/theitroad_srv
bash 24125 root cwd DIR 253,1 4096 519062 /mnt/nfs/theitroad_srv
vim 24144 theitroad cwd DIR 253,1 4096 519062 /mnt/nfs/theitroad_srv

其中我们使用已挂载的目录获得3个进程的PID。
我们会看到vim命令,这意味着“ theitroad”用户正在编辑文件。
我们可以通知用户停止其操作或者终止该过程。

现在,让我们看一下结果:

# lsof /mnt/nfs/theitroad_srv/
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
bash 24098 root cwd DIR 253,1 4096 519062 /mnt/nfs/theitroad_srv
bash 24125 root cwd DIR 253,1 4096 519062 /mnt/nfs/theitroad_srv

我们可以看到我们的用户已经停止了他的修改,但是我们仍在执行bash命令,但是我们不知道为什么。
现在,我们可以使用kill命令杀死这两个进程。

现在我们将杀死第一个bash进程

# kill -9 24098

我们可以验证结果

# lsof /mnt/nfs/theitroad_srv/
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
bash 24125 root cwd DIR 253,1 4096 519062 /mnt/nfs/theitroad_srv

我们可以看到一个进程被杀死了

# kill -9 24125

现在让我们验证第二个过程

# lsof /mnt/nfs/theitroad_srv/

现在让我们尝试卸载该文件夹

# umount /mnt/nfs/theitroad_srv/
umount: /mnt/nfs/theitroad_srv/: not mounted

我们的操作已自动卸载了该文件夹,但让我们使用df命令进行检查。

# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/vda1 20G 1.3G 18G 7% /
devtmpfs 236M 0 236M 0% /dev
tmpfs 245M 0 245M 0% /dev/shm
tmpfs 245M 8.3M 237M 4% /run
tmpfs 245M 0 245M 0% /sys/fs/cgroup
tmpfs 49M 0 49M 0% /run/user/0
10.128.20.241:/home 20G 1.3G 18G 7% /mnt/nfs/home_srv

从输出中,我们可以看到目录“/mnt/nfs/theitroad_srv”已从系统中卸载。

2)使用fuser

fuser(查找用户进程)命令有助于识别阻止我们卸载文件系统的进程。
它查找与我们作为命令行参数提供的任何文件,目录或者文件系统安装点关联的用户进程。

# fuser /mnt/nfs/theitroad_srv/
/mnt/nfs/theitroad_srv: 24191c

我们可以使用带有“ -m”选项的“ fuser”命令,该选项列出了访问文件或者文件系统上安装点的所有进程,而“ -v”选项显示的结果类似于带有PID,用户和已执行命令的ps命令。

# fuser -mv /mnt/nfs/theitroad_srv/
 USER PID ACCESS COMMAND
/mnt/nfs/theitroad_srv:
 root kernel mount /mnt/nfs/home_srv
 root 24191 ..c.. bash
 root 24275 ..c.. bash
 theitroad 24290 ..c.. vim

我们可以看到正在执行的命令。

# fuser -mv /mnt/nfs/theitroad_srv/
 USER PID ACCESS COMMAND
/mnt/nfs/theitroad_srv:
 root kernel mount /mnt/nfs/home_srv
 root 24191 ..c.. bash
 root 24275 ..c.. bash

使用fuser命令,可以使用-k选项直接终止正在执行的进程,而无需使用kill命令

# fuser -kmv /mnt/nfs/theitroad_srv/
 USER PID ACCESS COMMAND
/mnt/nfs/theitroad_srv:
 root kernel mount /mnt/nfs/home_srv
 root 24191 ..c.. bash
 root 24275 ..c.. bash

检查结果

# fuser -mv /mnt/nfs/theitroad_srv/
 USER PID ACCESS COMMAND
/mnt/nfs/theitroad_srv:
 root kernel mount /mnt/nfs/home_srv

似乎只有挂载正在执行。
让我们尝试卸载该文件夹

# umount /mnt/nfs/theitroad_srv/

我们没有其他错误消息。
检查安装点

# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/vda1 20G 1.3G 18G 7% /
devtmpfs 236M 0 236M 0% /dev
tmpfs 245M 0 245M 0% /dev/shm
tmpfs 245M 8.3M 237M 4% /run
tmpfs 245M 0 245M 0% /sys/fs/cgroup
tmpfs 49M 0 49M 0% /run/user/0
10.128.20.241:/home 20G 1.3G 18G 7% /mnt/nfs/home_srv

我们可以看到,'/mnt/nfs/theitroad_srv'文件夹已根据需要卸载。

3)延迟卸载 Lazy unmount

Umount命令具有“ -l”选项来执行延迟卸载(需要内核2.4.11或者更高版本)。
该挂载将从文件系统名称空间中删除(因此我们将不再在'/mnt/nfs/theitroad'下看到它),但仍保持挂载状态,因此访问该挂载的程序可以继续这样做。
当最后一个访问它的程序退出时,卸载实际上会发生。

# fuser -mv /mnt/nfs/theitroad_srv/
 USER PID ACCESS COMMAND
/mnt/nfs/theitroad_srv:
 root kernel mount /mnt/nfs/home_srv
 root 24366 ..c.. bash
 root 24381 ..c.. bash
 theitroad 24398 ..c.. vim

我们可以看到该文件夹正忙。
现在让我们尝试进行懒惰卸载

# umount -l /mnt/nfs/theitroad_srv/

我们没有错误消息。
我们将检查命令是否正在正确执行

# echo $?
0

现在让我们检查挂载点

# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/vda1 20G 1.3G 18G 7% /
devtmpfs 236M 0 236M 0% /dev
tmpfs 245M 0 245M 0% /dev/shm
tmpfs 245M 8.4M 237M 4% /run
tmpfs 245M 0 245M 0% /sys/fs/cgroup
tmpfs 49M 0 49M 0% /run/user/0
10.128.20.241:/home 20G 1.3G 18G 7% /mnt/nfs/home_srv

我们可以看到挂载点'/mnt/nfs/theitroad_srv'不再出现,但是正如我们前面所说,例如,我们的'theitroad'用户仍在修改其文件,可以创建新文件,等等。
在服务器上,我们可以看到用户正在修改的文件。

由于紧急情况,我们可能需要卸载分区,或者只是删除设备而已,但是由于该设备正忙,可能会出现问题。
在决定解决问题的方法之前,务必检查系统上的每个进程。
使用lsof和fuser命令可以轻松识别阻止我们卸载文件系统的进程。
最后,如果要使用强制卸载,请使用“ -f”选项。

umount -f -l /mnt/nfs/theitroad_srv /