I'm using a custom script to enter a chroot environment (this is not a security jail; it exists so that I can compile and do a few other things with a controlled set of installed packages and tools that is different from the host environment -- the host is Ubuntu and the chroot is Debian).
The script does what I think is a fairly standard set of mounts for this case:
mount -t proc "$ROOTPATH/proc"
mount -t sysfs "$ROOTPATH/sys"
mount --bind /dev "$ROOTPATH/dev"
mount --bind /dev/pts "$ROOTPATH/dev/pts"
But I also want to be able to access the host filesystem from within the chroot, so that I can copy files back and forth (as I said, this is not intended as a jail):
mount --rbind / "$ROOTPATH/host"
mount --make-rslave "$ROOTPATH/host"
(This sequence was suggested by this answer.)
Most of the time, this works entirely as expected.
However after entering and exiting the chroot environment several times (where exiting performs the corresponding umounts, of course), eventually the rbind
call above fails with:
mount(2) system call failed: No space left on device.
There's plenty of disk space (and inodes, according to df -i
) free, and of course this should just be binding the existing filesystem, not actually using space.
Naturally there's a bit of recursive weirdness involved, since the root filesystem does of course contain $ROOTPATH/host
itself (or actually in this case only sort of -- it's actually in a different filesystem which is itself mounted under /mnt
. But I do want the mounted filesystems of the host to be visible to the chroot as well, which is why I'm using a recursive mount). But as I said, most of the time this just works.
I assume that the problem is somehow related to this. But I definitely do want the filesystem containing $ROOTPATH
to be accessible inside the chroot. I thought it was smart enough to not do infinite recursion (and have $ROOTPATH/host/$ROOTPATH
be empty, not another mount point) -- and indeed that is the case when the commands work.
Using the single command:
mount --rbind --make-rslave / "$ROOTPATH/host"
does run successfully even when the system is in the ENOSPC state, but only performs a simple bind mount, not a recursive mount.
Is there something different I should be doing instead, or some way to "clear" the error and get it working again?
(Rebooting the system does get it working again, but I'd rather not have to do that each time.)
/
to a subtree of itself, that it's making some sort of loop/chain that isn't actually being cleared when you try to clean up the chroot, and that you're eventually hitting some sort of length limit of it.$ROOTPATH/host/$ROOTPATH
directory exists but is empty, so it doesn't actually loop.