Hi Wim,

Apologies for the decade late response.

Wim Hueskes said:

> stat -c%m does not seem to work correctly with bind mounts.
> I have tested the following on Debian Jessie:
> 
> # mkdir /home/root ; touch /home/zero
> # mount -o bind /root /home/root
> # mount -o bind /dev/zero /home/zero
> # mount -o bind /tmp /tmp
> # ./src/df -P /home/root /home/zero /tmp
> Filesystem     1024-blocks    Used Available Capacity Mounted on
> /dev/sda1          7736784 2431152   4889584      34% /home/root
> udev                 10240       0     10240       0% /home/zero
> /dev/sda1          7736784 2431152   4889584      34% /tmp
> # ./src/stat -c%m /home/root /home/zero /tmp
> /
> /
> /
> # ./src/stat --version
> stat (GNU coreutils) 8.26.4-ca52f
> 
> 
> The documentation explains:
> 
> stat outputs the alias for a bind mounted file, rather than the
> initial mount point of its backing device. One can recursively call
> stat until there is no change in output, to get the current base mount
> point
> (https://www.gnu.org/software/coreutils/manual/html_node/stat-invocation.html#index-bind-mount-1)
> 
> At least the documentation does not match the result. Note that the
> documented behaviour would not work for /tmp bind mounted to itself.

It looks like back when this feature implemented mountlist in Gnulib
used /etc/mtab. Back then, it was very easy to find the alias for a
mounted file. Using the following setup:

    $ mkdir -p /tmp/test
    $ mount -t tmpfs tmpfs /tmp/test
    $ mkdir -p /tmp/test/source /tmp/test/dest
    $ mount --bind /tmp/test/source /tmp/test/dest

Here is what I see on a Debian 6 install:

    $ uname -sr
    Linux 2.6.32-5-amd64
    $ src/stat --version | head -n 1
    stat (GNU coreutils) 8.6
    $ src/stat -c %m /tmp/test/dest
    /tmp/test/source
    $ strace src/stat -c %m /tmp/test/dest 2>&1 >/dev/null \
        | grep '^open' | tail -n 1
    open("/etc/mtab", O_RDONLY)             = 3
    $ tail -n 1 /etc/mtab
    /tmp/test/source /tmp/test/dest none rw,bind 0 0
    $ tail -n 1 /proc/self/mountinfo
    23 22 0:17 /source /tmp/test/dest rw,relatime - tmpfs tmpfs rw

That made it very simple to get the alias. However, the format of
/etc/mtab changed at some point, such that it is no longer easy to get
the alias. Here is an example from my Fedora 44 machine, where you can
also see that we use /proc/self/mountinfo nowadays:

     $ uname -sr
     Linux 7.1.10-200.fc44.x86_64
     $ stat --version | head -n 1
     stat (GNU coreutils) 9.11.252-aea70
     $ src/stat -c %m /tmp/test/dest
     /tmp/test
     $ strace src/stat -c %m /tmp/test/dest 2>&1 >/dev/null | grep '^open' | 
sed -n 'x;$p'
     openat(AT_FDCWD, "/proc/self/mountinfo", O_RDONLY|O_CLOEXEC) = 3
     $ tail -n 1 /etc/mtab
     tmpfs /tmp/test/dest tmpfs rw,seclabel,relatime,inode64 0 0
     $ tail -n 1 /proc/self/mountinfo
     1570 1446 0:143 /source /tmp/test/dest rw,relatime shared:1267 - tmpfs 
tmpfs rw,seclabel,inode64

So, I guess we would have to get the parent mount point and then stat
the root (i.e., "source" in the above example) relative to it.

Thanks for the detailed report.

Collin

P.S. Trying to SSH into a Debian 6 machine is a bit of a chore. If only
we didn't need security. :)



Reply via email to