RFC on FileStore and /proc/mounts on Linux in a chroot jail, Docker overlayfs and with btrfs
Brian Burkhalter
brian.burkhalter at oracle.com
Fri Oct 7 00:18:37 UTC 2016
I would be interested in any ideas anyone would like to share on this topic. There are three related issues [1, 2, 3] which have been filed. The most generic issue is [3] which has been observed in three different contexts:
A) chroot environment [1]
B) Docker container with overlay and overlay2 storage drivers [2]
C) btrfs file system with an unmounted sub-volume [2]
In all cases the failure was the IOException with message “Mount point not found” at line 91 in LinuxFileStore::findMountEntry [4]. This occurred because the directory identified in step 2 as the mount point of the path was not found in /proc/mounts in step 3. The mount point is either the root (/) of the path or the longest sub-path which has a different device ID from its parent. The device ID is obtained from the st_dev member of the struct stat populated by stat(2) [5].
In the chroot environment the contents of /proc/mounts was just
none /proc proc rw,relatime 0 0
and the mount point was determined to be “/“ which is not contained in /proc/mounts so the code falls through to the IOException.
In the overlayfs cases, when step 2 breaks out of the parent traversal loop, the device ID of the given path is valid in the operating system file system, but the device ID of the parent is not and apparently corresponds instead to a device ID in the overlayfs itself. As there is no entry in /proc/mounts for the identified mount point we get the IOException.
In the btrfs unmounted sub-volume case, for example, a btrfs file system is mounted on /mnt and contains a sub-volume /mnt/new_subvol which is not mounted. If an attempt is made to obtain the FileStore for example corresponding to /mnt/new_subvol/junk/junk.txt, step 2 traverses upwards and breaks when it finds that the device IDs of /mnt and /mnt/new_subvol differ. As /mnt/new_subvol is not in /proc/mounts the exception ensues.
In thinking about this I was wondering whether it could be solved by creating some “spoofed” mount entry not in /proc/mounts. This however does not seem like an inherently great idea and would probably create problems elsewhere.
Viewing it from a different angle, one could instead say that the chroot jail and btrfs sub-volume problems are actually due to incorrect or incomplete configurations and this is not an issue with findMountEntry() at all. The overlayfs problem could be viewed as a bug in the overlay and overlay2 storage driver implementations. This problem for example does not manifest when the aufs storage driver is used with Docker.
Comments and suggestions welcome.
Thanks,
Brian
[1] https://bugs.openjdk.java.net/browse/JDK-8165323 - cannot get FileStore in chroot environment (*)
[2] https://bugs.openjdk.java.net/browse/JDK-8165852 - cannot get FileStore for a file in overlayfs in Docker
[3] https://bugs.openjdk.java.net/browse/JDK-8166162 - cannot get FileStore if device of path is not in /proc/mounts
[4] http://hg.openjdk.java.net/jdk9/dev/jdk/file/65042b713b12/src/java.base/linux/classes/sun/nio/fs/LinuxFileStore.java
[5] https://linux.die.net/man/2/stat
(*) The immediate problem caused by [1] was fixed and [3] was filed to track the underlying cause.
More information about the nio-dev
mailing list