aufs of Linux File System

Keywords: Linux Ubuntu sudo Docker

The full name of aufs is advanced multi-layered unification filesystem. Its main function is to merge the contents of multiple folders together to provide a unified view. It is mainly used in livecd of various Linux distributions and in docker to organize image s.

It is said that because the aufs code is not maintainable (code readability and annotations are not good), it has not been merged into the mainline of the Linux kernel, but some distributions of kernels maintain the file system, such as in the kernel code of ubuntu 16.04.

All examples in this article are executed under ubuntu-server-x86_64 16.04.

Check whether the system supports aufs

Before using aufs, you can confirm whether the current system supports aufs by following commands. If not, install it according to the documents of the corresponding distribution.

#The following command does not support aufs if it is not output
#Because ubuntu 16.04 has this file system in its kernel, it is supported by default.
dev@ubuntu:~$ grep aufs /proc/filesystems
nodev   aufs
#Here nodev means that the file system does not need to be built on the device

Mount aufs

Choose the appropriate parameters (reference) Help document Call mount command, as shown below

# mount -t aufs -o br=./Branch-0:./Branch-0:./Branch-2 none ./MountPoint
  • - t aufs: Specifies the mount type as aufs

  • - o br=./Branch-0:./Branch-0:./Branch-2: Represents that three folders of Branch-0, Branch-1 and Branch-2 under the current directory are joined together.

  • None: aufs doesn't need devices, it only depends on the folder specified by - o br, so fill in none here.

  • / MountPoint: Represents that the final joint result is mounted in the current MountPoint directory, and then we can read and write files to that directory.

Suppose there are files 001.txt and 003.txt in Branch-0, 001.txt, 003.txt and 004.txt in Branch-1, 002.txt and 003.txt in Branch-2.

When mount is completed, the result will be as follows

              /*001.txt(b0)Represents Branch-0's 001.txt file, others, and so on*/
           +-------------+-------------+-------------+-------------+
MountPoint | 001.txt(b0) | 002.txt(b2) | 003.txt(b0) | 004.txt(b1) |    
           +-------------+-------------+-------------+-------------+
                  ↑             ↑             ↑             ↑
                  |             |             |             |
           +-------------+-------------+-------------+-------------+
Branch-0   |   001.txt   |             |   003.txt   |             |
           +-------------+-------------+-------------+-------------+
Branch-1   |   001.txt   |             |   003.txt   |   004.txt   |
           +-------------+-------------+-------------+-------------+
Branch-2   |             |   002.txt   |   003.txt   |             |
           +-------------+-------------+-------------+-------------+

After joining up, you will see four files under Branch Point: 001.txt under Branch-0, 003.txt under Branch-1, 04.txt under Branch-1, and 002.txt under Branch-2.

  • Branch is a concept in aufs. In fact, a branch is a directory, so the Branch-0,1,2 above is three directories.

  • Branch has index. The smaller the index, the higher the branch will be. If multiple branchs have the same file, only the file under the smallest index will be accessed.

  • MountPoint is where the last three directories are mounted after they are combined. Accessing files in this directory will go through the aufs file system. In other words, accessing Branch-0,1,2 directly is unknown to aufs.

Note: Not all directories in the filesystem can be used as branch es of aufs. Currently, aufs do not support btrfs aufs eCryptfs

When you read these files, you access the top-level files, but what if you want to write them? Or create a new file under the mount point? See the following example

Read only mount

When mounting, you can specify the read and write permissions of each branch. If not, the first directory will be writable and the other directories will be read-only. In practical use, it is better to show the read and write attributes of each branch, so that everyone can understand them at a glance. Here's a demonstration of read-only mounting:

#Prepare corresponding catalogues and documents
dev@ubuntu:~$ mkdir /tmp/aufs && cd /tmp/aufs
dev@ubuntu:/tmp/aufs$ mkdir dir0 dir1 root
dev@ubuntu:/tmp/aufs$ echo dir0 > dir0/001.txt
dev@ubuntu:/tmp/aufs$ echo dir0 > dir0/002.txt
dev@ubuntu:/tmp/aufs$ echo dir1 > dir1/002.txt
dev@ubuntu:/tmp/aufs$ echo dir1 > dir1/003.txt
#Finally, use the tree command to see the final directory structure
dev@ubuntu:/tmp/aufs$ tree
.
├── dir0
│   ├── 001.txt
│   └── 002.txt
├── dir1
│   ├── 002.txt
│   └── 003.txt
└── root

#Make both branch s read-only by specifying the ro parameter
dev@ubuntu:/tmp/aufs$ sudo mount -t aufs -o br=./dir0=ro:./dir1=ro none ./root
#You will see three files in the final root directory after the Union
dev@ubuntu:/tmp/aufs$ ls root/
001.txt  002.txt  003.txt
#The content of 002.txt is 002.txt in dir0, which indicates that the index of dir0 is smaller than that of dir1.
dev@ubuntu:/tmp/aufs$ cat root/002.txt
dir0

#touch failed because it was a read-only mount
dev@ubuntu:/tmp/aufs$ touch root/001.txt
touch: cannot touch 'root/001.txt': Read-only file system
dev@ubuntu:/tmp/aufs$ touch root/003.txt
touch: cannot touch 'root/003.txt': Read-only file system

#But we can change 001.txt and 003.txt by skipping the root directory.
#Because the root directory is skipped, it is not controlled by aufs
dev@ubuntu:/tmp/aufs$ touch dir0/001.txt
dev@ubuntu:/tmp/aufs$ touch dir1/003.txt

#We can also create new files in the following directory
dev@ubuntu:/tmp/aufs$ touch dir1/004.txt
#Newly created files can react to the mount point in time
dev@ubuntu:/tmp/aufs$ ls ./root/
001.txt  002.txt  003.txt  004.txt

#Delete the file to avoid affecting subsequent presentations
dev@ubuntu:/tmp/aufs$ rm ./dir1/004.txt

As can be seen from the above demonstration, we can skip the mount point to read and write the underlying directory directly, so it is not controlled by aufs, but the content we modify (004.txt created in dir1) can still be seen under the mount point. This is because when aufs accesses files, the default way is to look down layer by layer if there is no file in the top directory. If the layer changes, aufs will automatically find out. The parameter to control this behavior is udba, which is interesting to refer to. Help document

Since access to a file requires a level-by-level look-down, too many federated directories (levels) can affect performance.

Read and write mount

If the joint folder has write permission, then all modifications will be written to the writable folder. If there are more than one writable folder, which folder to write depends on the corresponding strategy, such as round-robin, maximum remaining space, etc. For details, please refer to Help document The "create" parameter is not introduced here.

dev@ubuntu:/tmp/aufs$ sudo umount ./root
#dir0 has read-write permission, dir1 is read-only permission
dev@ubuntu:/tmp/aufs$ sudo mount -t aufs -o br=./dir0=rw:./dir1=ro none ./root
dev@ubuntu:/tmp/aufs$ echo "root->write" >> ./root/001.txt
dev@ubuntu:/tmp/aufs$ echo "root->write" >> ./root/002.txt
dev@ubuntu:/tmp/aufs$ echo "root->write" >> ./root/003.txt
dev@ubuntu:/tmp/aufs$ echo "root->write" >> ./root/005.txt

#Compared with before, there are 003.txt and 005.txt in the dir0 directory, and the rest remain unchanged.
dev@ubuntu:/tmp/aufs$ ls ./root/
001.txt  002.txt  003.txt  005.txt
dev@ubuntu:/tmp/aufs$ ls ./dir0/
001.txt  002.txt  003.txt  005.txt
dev@ubuntu:/tmp/aufs$ ls ./dir1/
002.txt  003.txt

#Let's look at the content again. The content in dir1 remains unchanged.
dev@ubuntu:/tmp/aufs$ cat ./dir1/002.txt
dir1
dev@ubuntu:/tmp/aufs$ cat ./dir1/003.txt
dir1

#The contents of the files under dir0 have changed
dev@ubuntu:/tmp/aufs$ cat ./dir0/001.txt
dir0
root->write
dev@ubuntu:/tmp/aufs$ cat ./dir0/002.txt
dir0
root->write
dev@ubuntu:/tmp/aufs$ cat ./dir0/003.txt
dir1
root->write
dev@ubuntu:/tmp/aufs$ cat ./dir0/005.txt
root->write
  • When a new file is created, the new file is written to the directory with rw privileges. If more than one directory has rw privileges, it depends on the creation strategy configured at Mount time.

  • When modifying a file in a directory with rw privileges, modify the file directly

  • When modifying a file in a directory with only ro permission, aufs copies the file into an rw permission directory and then modifies it on it. This is called COW(copy on write). The speed of copy depends on the file system where the underlying branch is located.

As can be seen from the above, COW is still very low performance for large files, but it also takes up a lot of space, but because it only needs to be copied once when the first modification, it is still acceptable in many cases.

Delete files

When deleting a file, if the file only exists in the rw directory, delete the file directly in the rw directory. If the file exists in the ro directory, then aufs will create a file beginning with. wh in the rw directory to indicate that the file has been deleted.

#Delete all files through aufs
dev@ubuntu:/tmp/aufs$ rm ./root/001.txt ./root/002.txt ./root/003.txt ./root/005.txt

#All files under dir0 have been deleted, but the files under dir1 directory have not been moved.
dev@ubuntu:/tmp/aufs$ tree
.
├── dir0
├── dir1
│   ├── 002.txt
│   └── 003.txt
└── root

#Look at the contents of the dir0 directory through the - a parameter
#You can see that aufs has created two special files starting with. wh for 002.txt and 003.txt.
#Used to indicate that the two files have been deleted
#The other. wh files here are all properties files used by aufs
dev@ubuntu:/tmp/aufs$ ls ./dir0/ -a
.  ..  .wh.002.txt  .wh.003.txt  .wh..wh.aufs  .wh..wh.orph  .wh..wh.plnk

Concluding remarks

This article only introduces the basic functions of aufs, other advanced configuration items are not involved, such as dynamic addition and deletion of branch.

When using aufs, it is recommended to refer to the use of Live CD and docker, that is, to combine all directories in a read-only manner with an empty directory that supports reading and writing, so that all modifications can be stored in the specified empty directory, and then delete that directory, and do not bypass aufs in the process of using directly to operate the underlying branch, nor do you want to use it. Dynamic addition and deletion of branches, if the use of scenarios are too complex, because there are many details in aufs, it is likely that because of the understanding of aufs is not deep and trample.

Reference resources

aufs
aufs manual
Linux AuFS Examples

Posted by andylyon87 on Sun, 07 Apr 2019 16:48:30 -0700