A stackable or unification filesystem (referred to as a “union” filesystem) is one that combines the contents of many directories into a single directory. Junjiro Okajima’s AUFS (“aufs-tools”, under Ubuntu) is such an FS. However, there are some neat attributes that tools, such as Docker, take advantage of, and this is where it really gets interesting. I’ll discuss only one such feature, here.
AUFS has the concept of “branches”, where each branch is one directory to be combined. In addition, each branch has permissions imposed upon them: essentially “read-only” or “read-write”. By default, the first branch is read-write, and all others are read-only. With this as the foundation, AUFS presents a single, stacked filesystem, but begins to impose special handling on what can be modified, internally, while providing traditional filesystem behavior, externally.
When a delete is performed on a read-only branch, AUFS performs a “whiteout”, where the readonly director[y,ies] are untouched, but hidden files are created in the writable director[y,ies] to record the changes. Similar tracking, along with any, actual, new files, occurs when any change is applied to read-only directories. This also incorporates “copy on write” functionality, where copies of files are made only by necessity, and on demand.
$ mkdir /tmp/dir_a $ mkdir /tmp/dir_b $ mkdir /tmp/dir_c $ touch /tmp/dir_a/file_a $ touch /tmp/dir_b/file_b $ touch /tmp/dir_c/file_c $ sudo mount -t aufs -o br=/tmp/dir_a:/tmp/dir_b:/tmp/dir_c none /mnt/aufs_test/ $ ls -l /mnt/aufs_test/ total 0 -rw-r--r-- 1 dustin dustin 0 Feb 11 23:31 file_a -rw-r--r-- 1 dustin dustin 0 Feb 11 23:31 file_b -rw-r--r-- 1 dustin dustin 0 Feb 11 23:31 file_c $ ls -l /tmp/dir_c total 0 -rw-r--r-- 1 dustin dustin 0 Feb 11 23:31 file_c $ touch /mnt/aufs_test/new_file_in_unwritable $ ls -l /tmp/dir_c total 0 -rw-r--r-- 1 dustin dustin 0 Feb 11 23:31 file_c $ ls -l /tmp/dir_a total 0 -rw-r--r-- 1 dustin dustin 0 Feb 11 23:31 file_a -rw-r--r-- 1 dustin dustin 0 Feb 11 23:33 new_file_in_unwritable $ rm /mnt/aufs_test/file_c $ ls -l /tmp/dir_c total 0 -rw-r--r-- 1 dustin dustin 0 Feb 11 23:31 file_c $ ls -l /tmp/dir_a total 0 -rw-r--r-- 1 dustin dustin 0 Feb 11 23:31 file_a -rw-r--r-- 1 dustin dustin 0 Feb 11 23:33 new_file_in_unwritable $ ls -la /tmp/dir_a total 16 drwxr-xr-x 4 dustin dustin 4096 Feb 11 23:35 . drwxrwxrwt 17 root root 4096 Feb 11 23:35 .. -rw-r--r-- 1 dustin dustin 0 Feb 11 23:31 file_a -rw-r--r-- 1 dustin dustin 0 Feb 11 23:33 new_file_in_unwritable -r--r--r-- 2 root root 0 Feb 11 23:31 .wh.file_c -r--r--r-- 2 root root 0 Feb 11 23:31 .wh..wh.aufs drwx------ 2 root root 4096 Feb 11 23:31 .wh..wh.orph drwx------ 2 root root 4096 Feb 11 23:31 .wh..wh.plnk
Notice that we use mount rather than mount.aufs. It should also be mentioned that some filesystems on which the subordinate directories might be hosted could be problematic if they’re prone to bizarre behavior. cramfs, for example, is specifically mentioned in the manpage to have certain cases under which its behavior might be considered to be undefined.
AUFS seems to especially lend itself to process-containers.
For more information, visit the homepage and Okajima’s original announcement (2008).
Image may be NSFW.
Clik here to view.
Clik here to view.
