在 chroot 中绑定 root 时的 ENOSPC

在 chroot 中绑定 root 时的 ENOSPC

我正在使用自定义脚本进入 chroot 环境(这不是安全监狱;它的存在是为了我可以使用一组受控的已安装软件包和工具(与主机环境不同)进行编译和执行一些其他操作 - - 主机是 Ubuntu,chroot 是 Debian)。

对于这种情况,该脚本执行了我认为相当标准的安装集:

mount -t proc "$ROOTPATH/proc"
mount -t sysfs "$ROOTPATH/sys"
mount --bind /dev "$ROOTPATH/dev"
mount --bind /dev/pts "$ROOTPATH/dev/pts"

但我也希望能够从 chroot 内部访问主机文件系统,以便我可以来回复制文件(正如我所说,这并不是一个监狱):

mount --rbind / "$ROOTPATH/host"
mount --make-rslave "$ROOTPATH/host"

(这个顺序是由这个答案.)

大多数时候,这完全按照预期工作。

然而,在多次进入和退出 chroot 环境后(当然,退出会执行相应的 umount),最终rbind上述调用会失败并显示:

mount(2) system call failed: No space left on device.

有大量可用的磁盘空间(以及 inode,根据df -i参考资料),当然这应该只是绑定现有的文件系统,而不是实际使用空间。

当然,这会涉及到一些递归的奇怪之处,因为根文件系统当然包含$ROOTPATH/host其自身(或者实际上在这种情况下只是某种程度 - 它实际上位于一个不同的文件系统中,该文件系统本身安装在 下/mnt。但我确实想要已安装的文件系统主机对 chroot 也是可见的,这就是我使用递归挂载的原因)。但正如我所说,大多数时候这都是有效的。

我认为这个问题与此有某种关系。但我确实希望包含的文件系统$ROOTPATH可以在 chroot 内访问。我认为它足够聪明,不会进行无限递归(并且为$ROOTPATH/host/$ROOTPATH空,而不是另一个安装点)——事实上,命令工作时就是这种情况。

使用单个命令:

mount --rbind --make-rslave / "$ROOTPATH/host"

即使系统处于ENOSPC状态也能成功运行,但仅执行简单的绑定挂载,而不是递归挂载。

我是否应该做一些不同的事情,或者某种方法来“清除”错误并使其再次工作?

(重新启动系统确实可以使其再次工作,但我不想每次都这样做。)

相关内容