Linux/Unix环境中如何卸载一个处于繁忙状态的设备: /xxx device is busy.

【问题】
  熟悉Linux开发的同学应该经常遇到这样一个问题:尝试卸载一个处于繁忙状态的磁盘分区或者光盘时,出现系统错误:/xxx device is busy.


【分析】
  这一错误出现的根本原因是Linux/Unix系统为了避免数据丢失,不允许卸载一个处于繁忙状态的设备。设想一个进程正在访问(读写)当前设备,若该设备允许被轻易的卸载掉,那极有可能会导致数据丢失。这一默认的数据保护措施完好的保证了用户及系统数据的一致性和完整性。


【解决方案】
  既然明白了错误的缘由,那我们就可以通过以下途径来解决此问题。

  • 查询当前设备繁忙的原因,然后尝试卸载
    此处假设要卸载的设备为/dev/sdc1。
/*
* Find out which processes have activities on the device/partition
*/
#lsof | grep '/dev/sdc1'

/*
* Output
*/
#vi 3902       vivek    3u      BLK        8,1                 8167 /dev/sdc1

   从Output中可以看到进程vi(pid 3902)正在访问当前设备。所以,首先我们需要强制结束vi进程,然后使用umount命令来卸载设备/dev/sdc1.

#kill -9 3902
#umount /dev/sdc1

   看到此处的你可能会思考:是否有一个更加直接的方式,直接强制卸载处于繁忙状态的设备?请继续往下看!

  • 强制卸载处于繁忙状态的设备
    此处假设挂载点为/data,我们将使用命令fuser或者umount -l 来强制执行卸载操作。
/*
* DESC:
* -k : Kill processes accessing the file.
* -m : Name specifies a file on a mounted file system or a block device that is mounted. In above example you are using /mnt
*/
#fuser -km /data
/*
* DESC:
* -l: Also known as Lazy unmount. Detach the filesystem from the filesystem hierarchy now, and cleanup all references to the filesystem as soon as it is not busy anymore. Note that this option works with kernel version 2.4.11+ and above only.
*/
#umount -l /data

  若待强制卸载过载点是NFS类型(/data_nfs),可以有另一种选择:

/*
* DESC:
* -f: Force unmount in case of an unreachable NFS system
*/
#umount -f /data_nfs

【总结】
   显而易见,上述解决方案中fuser最为简单、粗暴且有效。umount -l可以优雅的等待设备状态改变但你可能要一万年!熟悉存储开发的同学会深有体会!最常见的方案是采用lsof确定哪些进程依赖于当前设备,进一步确认这些进程的重要程度来确定是否可以采用kill -9来强制结束,最后使用umount来卸载。对我而言,一点可以借鉴的经验是,如果只有一两个熟知进程依赖当前设备,且强制结束这些进程造成的数据丢失可以接收,那就简单粗暴有效的使用fuser即可,业务逻辑中简单总好过复杂!

你可能感兴趣的:(后端开发,umount,卸载,mount,point,挂载点)