Link to home
Start Free TrialLog in
Avatar of skullnobrains
skullnobrains

asked on

mount bind reports wrong mount source

i'm running ubuntu 16.04 ( xenial ) with 4.4.0-128-generic kernel

i create a bind mount using the following commands

root@sqlbol115:/usr/local/gitclones-hbs/User# mkdir /tmp/testmountsrc
root@sqlbol115:/usr/local/gitclones-hbs/User# touch  /tmp/testmountsrc/a

root@sqlbol115:/usr/local/gitclones-hbs/User# mkdir  /tmp/testmountdst
root@sqlbol115:/usr/local/gitclones-hbs/User# mount --bind -o ro /tmp/testmountsrc/ /tmp/testmountdst/

Open in new window


the mount does work as expected :
root@sqlbol115:/usr/local/gitclones-hbs/User# ls /tmp/testmountdst/
a

Open in new window


but the mount command reports something clearly wrong
root@sqlbol115:/usr/local/gitclones-hbs/User# mount | grep testmount
/dev/sda5 on /tmp/testmountdst type ext4 (ro,relatime,data=ordered)

Open in new window


/dev/sda5 is actually the mount point for /tmp and the flags have been copied.
i tested with a real world scenario while creating a chroot environment and this seems to be consistent behavior

is that a feature or a bug ?
any way i can prevent this obviously idiotic behavior ?

i recollect this is not my first time seing this on linux boxes ... this makes scripting unsafe in so many ways :(

thanks a bunch
Avatar of David Favor
David Favor
Flag of United States of America image

This is correct behavior.

Once you do the mount --bind -o ro /tmp/testmountsrc/ /tmp/testmountdst/ the mount point become /tmp/testmountdst which is what will show up in your mount reports.

The /tmp/testmountsrc directory is still there, it's just not a mount point.
Avatar of skullnobrains
skullnobrains

ASKER

/tmp/testmountsrc IS the mount point
my questions are

- why the hell does the mount not show as
"src on dst type bind"
like any other OS would show ( possibly using a different vocabulary )
sda5 is NOT the mountpoint of the displayed destination, there is no way to know there is a bind mount, much less which directory

- can this behavior be changed ?

- circumvented at least for my use case ?
namely i'd like to be able to check which dir is actually mounted with a script and possibly change the source dir on the fly
additionally,
rm --one-file-system
will happily traverse the mountpoint when and only when the device is the same
i'm unsure this is a bug, but i view it as inconsistent behavior
mounting the same dir verbosely ( or remounting it ) produces the expected output

for example

mount: /var/log/php-fpm.Support bound on /usr/local/gitclones-hbs/Support/var/log/php-fpm.Support

but nevertheless mount displays the same mount as

/dev/sda1 on /usr/local/gitclones-hbs/Support/lib/x86_64-linux-gnu type xfs (ro,relatime,attr2,inode64,noquota)

the ro flag is added by the bind mount. the other flags are inherited from the original mount

/dev/sda1 on / type xfs (rw,relatime,attr2,inode64,noquota)

my guess would currently be that the linux kernel needs to know the device so the parent device could not be unmounted by accident so this would be a voluntary dirty hack in the mtab registration
i guess this could be patchable into a slightly different output : something like

/dev/whatever on mountpoint type xfs ( bind=SRC,... )

or possibly ( less intuitive )

/dev/whatever on mountpoint type bind ( subdir=SRC,fstype=xfs,... )

but obviously this is what it should actually look like

SRC on DST type bind ( ... )

--

here is an example of the equivalent freebsd commands :

cd /tmp
mkdir a
mkdir b
mount -t nullfs a b

mount | grep /tmp/b
/tmp/a on /tmp/b (nullfs, local)

which is 100% consistent with any other type of mount
/tmp/testmountsrc - directory, will show up in ls + will be missing from mount.

/tmp/testmountdst - mount point, will show up in ls + mount both.
i have no concern with the behavior of ls
my concern is what the mount command reports

/tmp/testmountdst - mount point, will show up in ls + mount both.

obviously. great. but it is displayed in mount as an xfs mount of the whole partition which is just plain wrong

i fail to understand your point

--

as an example : "mount| grep sda1" displays the following
/dev/sda1 on / type xfs (rw,relatime,attr2,inode64,noquota)
/dev/sda1 on /usr/local/gitclones-hbs/Support/lib/x86_64-linux-gnu type xfs (ro,relatime,attr2,inode64,noquota)
/dev/sda1 on /usr/local/gitclones-hbs/Support/usr/share/zoneinfo type xfs (ro,relatime,attr2,inode64,noquota)
/dev/sda1 on /usr/local/gitclones-hbs/Support.dev/lib/x86_64-linux-gnu type xfs (ro,relatime,attr2,inode64,noquota)
/dev/sda1 on /usr/local/gitclones-hbs/Support.dev/usr/share/zoneinfo type xfs (ro,relatime,attr2,inode64,noquota)
/dev/sda1 on /usr/local/gitclones-hbs/Support.feature.ticketing/lib/x86_64-linux-gnu type xfs (ro,relatime,attr2,inode64,noquota)
/dev/sda1 on /usr/local/gitclones-hbs/Support.feature.ticketing/usr/share/zoneinfo type xfs (ro,relatime,attr2,inode64,noquota)
/dev/sda1 on /usr/local/gitclones-hbs/User/lib/x86_64-linux-gnu type xfs (ro,relatime,attr2,inode64,noquota)
/dev/sda1 on /usr/local/gitclones-hbs/User/usr/share/zoneinfo type xfs (ro,relatime,attr2,inode64,noquota)

Open in new window


only the first line is correct

all the other mount points are actually bind mounts of the zoneinfo subdirectory, and there is no way to determine that from the output of the mount command ( the ro flag does not help : some bind mounts won't be mounted ro and there is no way to determine the source dir based on mount's output )

i'm expecting a way to circumvent : either use a different type of mount that would achieve the same goal with a proper output, or a way to change this buggy behavior.

... or possibly a way to know what is actually mounted on what.
i'd assume there is a way ( maybe in /proc ) to determine what is mounted on what since the kernel has to keep that information somewhere.
i'll be happy to close this question and award points to whoever provides a proper way to determine which directory was mounted on another one

for now i'm approaching that goal using the mountinfo of the init process

root@sqlbol115:~# grep zoneinfo /proc/1/mountinfo
179 24 8:1 /usr/share/zoneinfo /usr/local/gitclones-hbs/Support.dev/usr/share/zoneinfo ro,relatime shared:1 - xfs /dev/sda1 rw,attr2,inode64,noquota
199 24 8:1 /usr/share/zoneinfo /usr/local/gitclones-hbs/Support.feature.ticketing/usr/share/zoneinfo ro,relatime shared:1 - xfs /dev/sda1 rw,attr2,inode64,noquota
159 24 8:1 /usr/share/zoneinfo /usr/local/gitclones-hbs/User/usr/share/zoneinfo ro,relatime shared:1 - xfs /dev/sda1 rw,attr2,inode64,noquota

at least i can determine that /usr/share/zoneinfo subdirectory is mounted on the above directories rather than the whole partition

id assume any mount with field#4 != "/" to be a --bind mount of some sort

obviously the above does not take chrooting or namespaces into account. for the current namespace, we can use /proc/self/mountinfo instead

i'll accept this post as a ( rather incomplete ) answer if nothing better comes by
ASKER CERTIFIED SOLUTION
Avatar of skullnobrains
skullnobrains

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial