2007-11-11 10:07:06

by Frans Pop

[permalink] [raw]
Subject: Bind mount bug?

I'm not sure whether this is a bug or expected behavior.
Suppose I create a "looped" bind mount situation as follows.

# mkdir test
# touch test/foo
# mkdir bindtest
# touch bindtest/bar
# mkdir bindtest/test
# mount --bind test/ bindtest/test/
# ls bindtest/test/
foo
# mount --bind bindtest/ test/
# ls test/
bar test
# ls test/test/
#

I'd expected the last command to list "foo", but it shows an empty dir.
Shouldn't it also show the original contents of test (as they were before
the first bind mount)?

# mount | grep test
/root/test on /root/bindtest/test type none (rw,bind)
/root/bindtest on /root/test type none (rw,bind)

Cheers,
Frans Pop


2007-11-11 10:22:48

by Frans Pop

[permalink] [raw]
Subject: Re: Bind mount bug?

On Sunday 11 November 2007, Frans Pop wrote:
> I'd expected the last command to list "foo", but it shows an empty dir.
> Shouldn't it also show the original contents of test (as they were before
> the first bind mount)?

The problem is of course also that any changes made into /test/test will get
lost into thin space:

# touch test/test/baz
# ls bindtest/test
foo
# umount test
# ls test
foo
#

2007-11-11 22:10:35

by Roland Kuhn

[permalink] [raw]
Subject: Re: Bind mount bug?

Hi Frans!

Let's see whether I can explain this (I'm not a guru...)

On 11 Nov 2007, at 11:06, Frans Pop wrote:

> I'm not sure whether this is a bug or expected behavior.
> Suppose I create a "looped" bind mount situation as follows.
>
> # mkdir test
> # touch test/foo
> # mkdir bindtest
> # touch bindtest/bar
> # mkdir bindtest/test
> # mount --bind test/ bindtest/test/
> # ls bindtest/test/
> foo
> # mount --bind bindtest/ test/

This mounts the bindtest/ tree on test/ _without_ copying the mount
points which are found on subtrees. This is necessary to avoid loops
in the filesystem (bind mounts are somewhat like hardlinks on
directories, just without the headaches).

> # ls test/
> bar test
> # ls test/test/
> #
>
This lists the contents of the original bintest/test/ directory which
you created above. Creating e.g. a file in there stores that file
physically in bindtest/test/bla, where "test" does _not_ mean the
bind mount but the underlying directory here.

> I'd expected the last command to list "foo", but it shows an empty
> dir.
> Shouldn't it also show the original contents of test (as they were
> before
> the first bind mount)?
>
> # mount | grep test
> /root/test on /root/bindtest/test type none (rw,bind)
> /root/bindtest on /root/test type none (rw,bind)
>
You see, the bindtest/test/ mount was not propagated to test/test/.
This is very much by design. You can e.g. do

# mkdir -p test/test
# mount --bind test test/test
# ls test/test
test
# ls test/test/test
#

so there is no loop (`find test` would actually say that it
terminates because it has detected a loop, so it cannot be used to
test this).

# touch test/test/test/a
# ls test/test/test
a
# ls test/test
# umount test/test
# ls test/test
a
#

So, you see, test/test/test/a was (as it should) physically created
in test/test, where it is shadowed by the bind mount as long as that
is not removed. Nothing vanishes into "thin air" ;-)

Ciao,
Roland

--
TU Muenchen, Physik-Department E18, James-Franck-Str., 85748 Garching
Telefon 089/289-12575; Telefax 089/289-12570
--
CERN office: 892-1-D23 phone: +41 22 7676540 mobile: +41 76 487 4482
--
Any society that would give up a little liberty to gain a little
security will deserve neither and lose both. - Benjamin Franklin
-----BEGIN GEEK CODE BLOCK-----
Version: 3.12
GS/CS/M/MU d-(++) s:+ a-> C+++ UL++++ P+++ L+++ E(+) W+ !N K- w--- M
+ !V Y+
PGP++ t+(++) 5 R+ tv-- b+ DI++ e+++>++++ h---- y+++
------END GEEK CODE BLOCK------



Attachments:
PGP.sig (186.00 B)
This is a digitally signed message part

2007-11-11 22:29:27

by Jan Engelhardt

[permalink] [raw]
Subject: Re: Bind mount bug?


>> I'm not sure whether this is a bug or expected behavior.
>> Suppose I create a "looped" bind mount situation as follows.
>>
>> # mkdir test
>> # touch test/foo
>> # mkdir bindtest
>> # touch bindtest/bar
>> # mkdir bindtest/test
>> # mount --bind test/ bindtest/test/
>> # ls bindtest/test/
>> foo
>> # mount --bind bindtest/ test/
>
>This mounts the bindtest/ tree on test/ _without_ copying the mount
>points which are found on subtrees. This is necessary to avoid loops
>in the filesystem (bind mounts are somewhat like hardlinks on
>directories, just without the headaches).

What you seek is mount --rbind.

2007-11-11 22:40:57

by Frans Pop

[permalink] [raw]
Subject: Re: Bind mount bug?

On Sunday 11 November 2007, Roland Kuhn wrote:
> This mounts the bindtest/ tree on test/ _without_ copying the mount
> points which are found on subtrees.

Right. I guess this is the key point that tripped me up.

> So, you see, test/test/test/a was (as it should) physically created  
> in test/test, where it is shadowed by the bind mount as long as that  
> is not removed.

Which means that to continue the example from my follw-up mail:

> # ls bindtest/test
> foo
> # umount test
> # ls test
> foo
# umount bindtest/test
# ls bindtest/test
baz

And there indeed is the missing file.

> Nothing vanishes into "thin air" ;-)

Yeah, I saw that syntax error after sending the mail "into space" would have
been OK too, but not my combining the two :-)

Thanks for the explanation!

Cheers,
FJP

2007-11-11 23:42:36

by Frans Pop

[permalink] [raw]
Subject: Re: Bind mount bug?

On Sunday 11 November 2007, Jan Engelhardt wrote:
> >This mounts the bindtest/ tree on test/ _without_ copying the mount
> >points which are found on subtrees. This is necessary to avoid loops
> >in the filesystem (bind mounts are somewhat like hardlinks on
> >directories, just without the headaches).
>
> What you seek is mount --rbind.

Thanks! That works fine with mount from util-linux-ng.

Busybox' mount (at least Debian's admittedly old 1.1.3 version) seems to
fail to do the recursing. I'll file a BR against busybox in Debian and
check that again when we have a more current version.