1. Overview
We use the commands mount and umount in the process of mounting devices in Linux. However, there is another mount point type, called bind mount. In this tutorial, we’ll learn what a bind mount is, and we’ll also see some examples of when we can use it.
2. Introduction to mount
First, let’s do a quick recap on the mount command. In Linux systems, we can mount a device in a directory using the mount command. This allows us to access the device’s filesystem. Let’s mount a USB stick represented by the device /dev/sdc1 on /mnt/usb, and then list its contents:
$ mkdir /mnt/usb
$ mount /dev/sdc1 /mnt/usb
$ ls /mnt/usb
appendix.pdf pictures/
We can see that there’s a file and a folder in the USB stick we’ve just mounted. Now, we can list all the mounted devices using findmnt –real:
$ findmnt --real
TARGET SOURCE FSTYPE OPTIONS
/ /dev/sda2 ext4 rw,relatime
├─/home /dev/sdb1 ext4 rw,relatime
├─/mnt/usb /dev/sdc1 vfat rw,relatime,fmask=0022,dmask=0022,codepage=437,errors=remount-ro
└─/boot/efi /dev/sda1 vfat rw,relatime,fmask=0022,dmask=0022,codepage=437,errors=remount-ro
As we can see, there are four devices mounted on the system, including our USB stick. Each device has a target directory from where we can access the device’s filesystem. Finally, we can unmount the USB stick:
$ umount /dev/sdc1
3. Bind Mounts
As we saw in the previous section, we usually mount a device in a directory. However, we can also mount a directory on another directory. We do this by using the mount command with the –bind parameter. We can think of the bind mount as an alias. For example, when we bind mount the directory /tmp/foo on /tmp/bar, both will reference the same content. We can access the files in /tmp/foo from /tmp/bar, and vice versa. We can use any directory as the bind mount source. If the source directory is a device’s mount point, then the whole device is bind-mounted on the destination directory. If instead, the source is a device’s subdirectory, then the device is bind-mounted starting from that subdirectory. When we use the –bind parameter, mount points inside the source directory aren’t remounted. So, if we want to bind mount a directory and all submounts inside that directory, we have to use the –rbind parameter instead. After doing a bind mount, we won’t have access to the original content in the target directory. The same happens when we mount devices. Let’s create a directory /tmp/foo with some files in it:
$ mkdir /tmp/foo
$ touch /tmp/foo/bind_mount_example
$ touch /tmp/foo/baeldung
Now, let’s create a /tmp/bar directory and bind mount our /tmp/foo directory to it:
$ mkdir /tmp/bar
$ mount --bind /tmp/foo /tmp/bar
Now, let’s see the content on both folders:
$ ls -l /tmp/foo
total 0
-rw-r--r-- 1 baeldung users 0 Oct 30 19:26 baeldung
-rw-r--r-- 1 baeldung users 0 Oct 30 19:26 bind_mount_example
$ ls -l /tmp/bar
total 0
-rw-r--r-- 1 baeldung users 0 Oct 30 19:26 baeldung
-rw-r--r-- 1 baeldung users 0 Oct 30 19:26 bind_mount_example
We can see both folders have the same content. Let’s create a new file in /tmp/bar and we’ll see the content is also accessible from /tmp/foo:
$ echo "new file" > /tmp/bar/new_file
$ cat /tmp/foo/new_file
new file
We can use findmnt –real to list all the mount points, including the bind mount:
$ findmnt --real
TARGET SOURCE FSTYPE OPTIONS
/ /dev/sda2 ext4 rw,relatime
├─/home /dev/sdb1 ext4 rw,relatime
├─/boot/efi /dev/sda1 vfat rw,relatime,fmask=0022,dmask=0022,codepage=437,errors=remount-ro
└─/tmp/bar /dev/sda2[/tmp/foo] ext4 rw,relatime
Finally, let’s unmount /tmp/bar:
$ umount /tmp/bar
4. Use Cases
In this section, we’ll see two examples of when using a bind mount is useful. One provides us with a method to access files hidden by a mount point. The other one is useful when working with chroot environments, and allows us to access files outside of it.
4.1. Accessing Files Hidden by a Mount Point
When we mount a device on a directory, the previous content of that directory becomes hidden by the mount point. Therefore, we lose access to the original content by traditional means. However, we have learned from the previous section that when we use the –bind parameter, mount doesn’t bind the submounts from the source directory. So, we can use this functionality to access hidden files. Let’s suppose we have the /mnt/usb directory and we haven’t mounted any USB stick yet. Let’s write some files on it:
$ echo baeldung > /mnt/usb/hidden_file_example
$ ls /mnt/usb
hidden_file_example
Then, let’s mount the USB stick, and we’ll see that hidden_file_example file isn’t listed anymore:
$ mount /dev/sdc1 /mnt/usb
$ ls /mnt/usb
appendix.pdf pictures/
So now, we can use a bind mount to access the hidden_file_example file. We’ll first create the /tmp/oldmnt directory and then let’s do a bind mount of /mnt onto our new directory:
$ mkdir /tmp/oldmnt
$ mount --bind /mnt /tmp/oldmnt
Then, we can see the original /mnt/usb content in /tmp/oldmnt/usb:
$ ls /tmp/oldmnt/usb
hidden_file_example
$ cat /tmp/oldmnt/usb/hidden_file_example
baeldung
As we can notice, we used /mnt as the source directory when doing the bind mount. This is because the –bind parameter only ignores submounts. If we’d used /mnt/usb, we would’ve bind-mounted the USB stick in /tmp/oldmnt. Finally, let’s unmount both mount points, /mnt/usb and /tmp/oldmnt:
$ umount /mnt/usb /tmp/oldmnt
4.2. Accessing Files Outside of a chroot Environment
Another example of when to use a bind mount is to mount directories inside a chroot environment. chroot is a program that provides limited isolation to processes. With chroot, we can set the root directory when executing a program. For instance, we can use chroot to run httpd with the root directory /home/apache. This will effectively make /home/apache as the root directory / for that process. So, for example, the directory /home/apache/www would become /www. This way, the httpd process won’t have access to any file outside of /home/apache. Now, how can the process executed in a chroot environment access files outside of it? For instance, the process may need access to libraries from /lib64, and binaries from /bin. To solve this, we can use a bind mount to make those directories accessible from the chroot directory. Let’s prepare a directory /home/chroot to use the chroot command. First, let’s create the directory /home/chroot, with two directories inside, bin and lib64:
$ mkdir /home/chroot
$ mkdir /home/chroot/bin
$ mkdir /home/chroot/lib64
Then, let’s bind mount /bin to /home/chroot/bin and /lib64 to /home/chroot/lib64:
$ mount --bind /bin /home/chroot/bin
$ mount --bind /lib64 /home/chroot/lib64
Finally, we can use chroot to change the root directory to /home/chroot:
$ chroot /home/chroot
Now, we have shell with /home/chroot as its root directory. Let’s use ls to list the root’s content:
$ ls -l /
total 16
drwxr-xr-x 2 0 0 4096 Oct 29 21:47 bin
drwxr-xr-x 8 0 0 12288 Oct 29 17:02 lib64
$ ls -l /bin/bash
-rwxr-xr-x 1 0 0 1218032 May 5 16:37 /bin/bash
$ ls -l /lib64/libc-*.so
-rwxr-xr-x 1 0 0 2173576 Aug 17 20:03 /lib64/libc-2.33.so
As we can see, we are inside the chroot environment and have access only to /bin and /lib64. Also, we can list files from inside of them.
5. Conclusion
In this article, we started with a brief introduction to the mount command. Then, we learned about bind mounts and how to use them. Finally, we saw two examples of when it’s useful to use bind mounts.