RFC on FileStore and /proc/mounts on Linux in a chroot jail, Docker overlayfs and with btrfs

David M. Lloyd david.lloyd at redhat.com
Thu Jun 15 13:10:00 UTC 2017


Sorry for the late response on this.  I asked around a bit and so far 
have turned up at least one possibly useful insight: 
/proc/self/mountinfo might be a more useful source of information than 
/proc[/self]/mounts.

This is because mountinfo correlates the major:minor device number with 
the mount point/filesystem.  So you can lstat a file and derive useful 
information by correlating the major/minor fields in mountinfo with 
st_dev.  You could perhaps iterate all the matching filesystems looking 
for one which is a prefix match.

The fields in mountinfo are also interesting in that they contain a 
unique (for at least that particular iteration of the file) ID for each 
mount, plus a link to the "parent" ID.  More info on this file is in the 
proc(5) manpage.

If the question is "what is the mount point", and nothing matches, then 
I think it's (probably?) safe to conclude that the mount point is "/". 
Using lstat and mountinfo, even if there is no "/" entry, you will know 
the de-facto mount point (which must be "/") and the device major:minor. 
  You won't have the mount options, but maybe there are ways you can 
infer them.

One other oddball thing I remember from my initramfs-tinkering days is 
that you can end up in a situation where there are multiple mounts on 
the same mount point.  Using mountinfo also helps this case because you 
can use the device number to eliminate the wrong answer.

The btrfs problem seems to be evidence that the assumption that there is 
a mount entry for every device major:minor might be flawed.  If there's 
a device ID transition and there is no matching mountinfo entry, perhaps 
the best option is to simply continue traversing upwards until an 
existent device ID is found.

Hope this helps.

On 10/06/2016 07:18 PM, Brian Burkhalter wrote:
> 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.
> 


-- 
- DML


More information about the nio-dev mailing list