通常,我将一些目录挂载到 chroot 环境,如下所示:
mount -t proc /proc /mnt/chroot/proc
mount --rbind /dev /mnt/chroot/dev
mount --rbind /sys /mnt/chroot/sys
mount --rbind /run /mnt/chroot/run
但是,完成后,我无法卸载那些已安装的目录,并且有一条消息要求获取使用目录的正在运行的进程列表,这给了我一堆进程列表行。那么,如何正确卸载这些目录呢?
答案1
查找阻止文件系统卸载的正常方法是列出在其上打开文件的进程(或文件描述符或其当前目录等):
lsof /path/to/mount/point
fuser -m /path/to/mount/point
查看进程列表并在必要时终止它们。
内核本身也可以通过几种方式阻止卸载,例如如果其下方有另一个挂载点(例如,在挂载/mnt/chroot
时无法卸载)。/mnt/chroot/proc
当您进行绑定安装时,诸如上面的命令会通过文件系统的任何路径打开列表文件。例如,fuser -m /mnt/chroot/run
列出在该文件系统上打开文件的进程,无论它们是通过/run
还是通过/mnt/chroot/run
.
要查找正在使用挂载点的进程,请列出进程及其打开文件的路径,并对路径进行一些过滤。例如:
lsof /mnt/chroot/run | grep /mnt/chroot
或获得全部
lsof | grep /mnt/chroot
或者您可以/proc
直接访问:
ls -l /proc/[0-9]*/fd/* | grep /mnt/chroot
对于自动处理(假设最近sed
支持-z
空分隔符):
find /proc/[0-9]*/fd -type l -printf '%p %l/\0' |
sed -nz 's!^/proc/\([0-9]*\)/fd/[0-9]* /mnt/chroot/.*!\1!p' |
sort -nu
如果您确实找不到挂载文件系统的内容,但需要取回挂载点,则可以通过在某处创建一个空目录并运行mount --move /current/mount/point /empty/directory/out/of/the/way
.您还可以执行延迟卸载 ( umount -l
),这会导致文件系统根本没有挂载点(因此无法再打开其上的文件),但只要其上有打开的文件或其他引用,仍然会挂载。
答案2
如果有进程在 chroot“内部”运行(即使在 shell 退出之后),您可能无法卸载文件系统(也就是说,您不能只是从这些进程脚下拉出文件系统)。
在这种情况下,重新输入 chroot(在 shell 中),然后停止服务,或者直接杀死它们(即使是从 chroot“外部”),如果您不关心它们的状态等。