Difference between --rbind and --bind in mounting
I am confused. Linux filesystem is a tree structure, with the root node(starting node) as the root directory.
Now let's suppose I have a folder abc
at location /home/abc
and another folder xyz
at location /home/xyz
Folder xyz
consists of some other folders and files inside it. (ex def
and mno
are folders inside it)
/
├── home/
│ ├── abc
│ └── xyz
│ ├── def
│ └── mno
When I run the command
mount --rbind /home/xyz /home/abc
(rbind is recursively bind)
I see all the contents of the folder xyz
in abc
.
Now, when I just run the command
mount --bind /home/xyz /home/abc
I still see all the contents of xyz
in abc
.
Why is that?
--bind
to work just as similarly to --rbind
.
Solution 1:
You've rightly observed that, with both --bind
and --rbind
, you see directories under the bind mount.
The difference is that, with --rbind
but not with --bind
, you see the contents of other bind mounts under the bind mount.
As applied to your example, suppose for simplicity that /home/xyz/def
and /home/xyz/mno
are empty directories. Suppose further that you then use them as bind mounts, i.e., you use them as mount points in mount --bind
or mount --rbind
. This causes them to appear nonempty. Then, suppose you run:
mount --bind /home/xyz /home/abc
Then, /home/abc/def
and /home/abc/mno
both exist, but they appear empty, because you used mount --bind
, which is nonrecursive.
In contrast, suppose you instead made /home/abc
a bind mount by running this command:
mount --rbind /home/xyz /home/abc
Then, /home/abc/def
and /home/abc/mno
both exist and they appear nonempty--they have the contents of the /home/xyz/def
and /home/xyz/mno
bind mounts--because you used mount --rbind
, which is recursive.
Here's a fully worked-out example:
ek@Gnar:~$ mkdir original
ek@Gnar:~$ touch original/a-regular-file
ek@Gnar:~$ mkdir original/a-directory
ek@Gnar:~$ mkdir parent-of-mountpoint
ek@Gnar:~$ mkdir parent-of-mountpoint/mountpoint
ek@Gnar:~$ sudo mount --bind ~/original ~/parent-of-mountpoint/mountpoint
ek@Gnar:~$ mkdir nonrecursive-other-mountpoint recursive-other-mountpoint
ek@Gnar:~$ sudo mount --bind ~/parent-of-mountpoint ~/nonrecursive-other-mountpoint
ek@Gnar:~$ sudo mount --rbind ~/parent-of-mountpoint ~/recursive-other-mountpoint
ek@Gnar:~$ tree -F original/
original/
├── a-directory/
└── a-regular-file
1 directory, 1 file
ek@Gnar:~$ tree -F parent-of-mountpoint/
parent-of-mountpoint/
└── mountpoint/
├── a-directory/
└── a-regular-file
2 directories, 1 file
ek@Gnar:~$ tree -F nonrecursive-other-mountpoint/
nonrecursive-other-mountpoint/
└── mountpoint/
1 directory, 0 files
ek@Gnar:~$ tree -F recursive-other-mountpoint/
recursive-other-mountpoint/
└── mountpoint/
├── a-directory/
└── a-regular-file
2 directories, 1 file
ek@Gnar:~$ mount | grep ~
/dev/sda2 on /home/ek/parent-of-mountpoint/mountpoint type ext4 (rw,relatime)
/dev/sda2 on /home/ek/nonrecursive-other-mountpoint type ext4 (rw,relatime)
/dev/sda2 on /home/ek/recursive-other-mountpoint type ext4 (rw,relatime)
/dev/sda2 on /home/ek/recursive-other-mountpoint/mountpoint type ext4 (rw,relatime)
Solution 2:
Read man 8 mount
. It says (emphasis added):
Bind mounts
Remount part of the file hierarchy somewhere else. The call is:
mount --bind olddir newdir
or by using this fstab entry:
/olddir /newdir none bind
After this call the same contents are accessible in two places. One can also remount a single file (on a single file). It's also possible to use the bind mount to create a mountpoint from a regular directory, for example:
mount --bind foo foo
The bind mount call attaches only (part of) a single filesystem, not possible submounts. The entire file hierarchy including submounts is attached a second place by using:
mount --rbind olddir newdir
Note that the filesystem mount options will remain the same as those on the original mount point.