执行 chroot 后如何正确卸载已挂载的目录?

执行 chroot 后如何正确卸载已挂载的目录?

通常,我将一些目录挂载到 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“外部”),如果您不关心它们的状态等。

相关内容