Content-type: text/html
At remount-time, the options are interpreted in the given order, e.g. left to right.
Aufs rejects the branch which is an ancestor or a descendant of another branch. It is called overlapped. When the branch is loopback-mounted directory, aufs also checks the source fs-image file of loopback device. If the source file is a descendant of another branch, it will be rejected too.
After mounting aufs or adding a branch, if you move a branch under another branch and make it descendant of another branch, aufs will not work correctly.
If there is the same named file on the lower branch (larger index), aufs will hide the lower file. You can only see the highest file. You will be confused if the added branch has whiteouts (including diropq), they may or may not hide the lower entries.
Even if a process have once mapped a file by mmap(2) with MAP_SHARED and the same named file exists on the lower branch, the process still refers the file on the lower(hidden) branch after adding the branch. If you want to update the contents of a process address space after adding, you need to restart your process or open/mmap the file again. (cf. Branch Syntax).
If a process is referencing the file/directory on the deleting branch (by open, mmap, current working directory, etc.), aufs will return an error EBUSY.
If the branch permission is been changing [oq]rw[cq] to [oq]ro[cq], and a process is mapping a file by mmap(2) on the branch, the process may or may not be able to modify its mapped memory region after modifying branch permission flags. Additioanlly when you enable CONFIG_IMA (in linux-2.6.30 and later), IMA may produce some wrong messages. But this is equivalent when the filesystem is changed [oq]ro[cq] in emergency. (cf. Branch Syntax).
The files are created per an aufs and per a branch filesystem, and unlinked. So you cannot find this file, but it exists and is read/written frequently by aufs. (cf. External Inode Number Bitmap, Translation Table and Generation Table).
If you enable CONFIG_SYSFS, the path of xino files are not shown in /proc/mounts (and /etc/mtab), instead it is shown in <sysfs>/fs/aufs/si_<id>/xi_path. Otherwise, it is shown in /proc/mounts unless it is not the default path.
If you use this option, Some applications will not work correctly. (cf. External Inode Number Bitmap, Translation Table and Generation Table).
If the target dir which is being removed or renamed (destination dir) has a huge number of whiteouts, i.e. the dir is empty logically but physically, the cost to remove/rename the single dir may be very high. It is required to unlink all of whiteouts internally before issuing rmdir/rename to the branch. To reduce the cost of single systemcall, aufs renames the target dir to a whiteout-ed temporary name and invokes a pre-created kernel thread to remove whiteout-ed children and the target dir. The rmdir/rename systemcall returns just after kicking the thread.
When the number of whiteout-ed children is less than the value of dirwh, aufs remove them in a single systemcall instead of passing another thread. This value is ignored when the branch is NFS. The default value is AUFS_DIRWH_DEF].
Those threads stay in the system while the aufs module is loaded, and handle the special I/O requests from aufs. The default value is AUFS_NWKQ_DEF].
The special I/O requests from aufs include a part of copy-up, lookup, directory handling, pseudo-link, xino file operations and the delegated access to branches. For example, Unix filesystems allow you to rmdir(2) which has no write permission bit, if its parent directory has write permission bit. In aufs, the removing directory may or may not have whiteout or [oq]dir opaque[cq] mark as its child. And aufs needs to unlink(2) them before rmdir(2). Therefore aufs delegates the actual unlink(2) and rmdir(2) to another kernel thread which has been created already and has a superuser privilege.
If you enable CONFIG_SYSFS, you can check this value through <sysfs>/module/aufs/parameters/nwkq.
If the number of your branches is large or their path is long and you meet the limitation of mount(8) ro /etc/mtab, you need to enable CONFIG_SYSFS and set aufs module parameter brs=1.
When this parameter is set as 1, aufs does not show [oq]br:[cq] (or dirs=) mount option through /proc/mounts (and /etc/mtab). So you can keep yourself from the page limitation of mount(8) or /etc/mtab. Aufs shows branch paths through <sysfs>/fs/aufs/si_XXX/brNNN. Actually the file under sysfs has also a size limitation, but I don[aq]t think it is harmful.
There is one more side effect in setting 1 to this parameter. If you rename your branch, the branch path written in /etc/mtab will be obsoleted and the future remount will meet some error due to the unmatched parameters (Remember that mount(8) may take the options from /etc/mtab and pass them to the systemcall). If you set 1, /etc/mtab will not hold the branch path and you will not meet such trouble. On the other hand, the entries for the branch path under sysfs are generated dynamically. So it must not be obsoleted. But I don[aq]t think users want to rename branches so often.
If CONFIG_SYSFS is disable, this parameter is always set to 0.
Any filesystem can be a branch, But some are not accepted such like sysfs, procfs and unionfs. If you specify such filesystems as an aufs branch, aufs will return an error saying it is unsupported.
Cramfs in linux stable release has strange inodes and it makes aufs confused. For example,
$ mkdir -p w/d1 w/d2 $ > w/z1 $ > w/z2 $ mkcramfs w cramfs $ sudo mount -t cramfs -o ro,loop cramfs /mnt $ find /mnt -ls 76 1 drwxr-xr-x 1 jro 232 64 Jan 1 1970 /mnt 1 1 drwxr-xr-x 1 jro 232 0 Jan 1 1970 /mnt/d1 1 1 drwxr-xr-x 1 jro 232 0 Jan 1 1970 /mnt/d2 1 1 -rw-r--r-- 1 jro 232 0 Jan 1 1970 /mnt/z1 1 1 -rw-r--r-- 1 jro 232 0 Jan 1 1970 /mnt/z2
All these two directories and two files have the same inode with one as their link count. Aufs cannot handle such inode correctly. Currently, aufs involves a tiny workaround for such inodes. But some applications may not work correctly since aufs inode number for such inode will change silently. If you do not have any empty files, empty directories or special files, inodes on cramfs will be all fine.
A branch should not be shared as the writable branch between multiple aufs. A readonly branch can be shared.
The maximum number of branches is configurable at compile time (127 by default).
When an unknown permission or attribute is given, aufs sets ro to that branch silently.
When your branch exists on slower device and you have some capacity on your hdd, you may want to try ulobdev tool in ULOOP sample. It can cache the contents of the real devices on another faster device, so you will be able to get the better access performance. The ulobdev tool is for a generic block device, and the ulohttp is for a filesystem image on http server. If you want to spin down your hdd to save the battery life or something, then you may want to use ulobdev to save the access to the hdd, too. See $AufsCVS/sample/uloop in detail.
If you enable CONFIG_SYSFS, the path of xino files are not shown in /proc/mounts (and /etc/mtab), instead it is shown in <sysfs>/fs/aufs/si_<id>/xi_path. Otherwise, it is shown in /proc/mounts unless it is not the default path.
Those files are always opened and read/write by aufs frequently. If your writable branch is on flash memory device, it is recommended to put xino files on other than flash memory by specifying [oq]xino=[cq] mount option.
The maximum file size of the bitmap is, basically, the amount of the number of all the files on all branches divided by 8 (the number of bits in a byte). For example, on a 4KB page size system, if you have 32,768 (or 2,599,968) files in aufs world, then the maximum file size of the bitmap is 4KB (or 320KB).
The maximum file size of the table will be [oq]max inode number on the branch x size of an inode number[cq]. For example in 32bit environment,
$ df -i /branch_fs /dev/hda14 2599968 203127 2396841 8% /branch_fs
and /branch_fs is an branch of the aufs. When the inode number is assigned contiguously (without [oq]hole[cq]), the maximum xino file size for /branch_fs will be 2,599,968 x 4 bytes = about 10 MB. But it might not be allocated all of disk blocks. When the inode number is assigned discontinuously, the maximum size of xino file will be the largest inode number on a branch x 4 bytes. Additionally, the file size is limited to LLONG_MAX or the s_maxbytes in filesystem[aq]s superblock (s_maxbytes may be smaller than LLONG_MAX). So the support-able largest inode number on a branch is less than 2305843009213693950 (LLONG_MAX/4-1). This is the current limitation of aufs. On 64bit environment, this limitation becomes more strict and the supported largest inode number is less than LLONG_MAX/8-1.
The xino files are always hidden, i.e. removed. So you cannot do [oq]ls -l xino_file[cq]. If you enable CONFIG_DEBUG_FS, you can check these information through <debugfs>/aufs/<si_id>/{xib,xi[0-9]*,xigen}. xib is for the bitmap file, xi0 ix for the first branch, and xi1 is for the next. xigen is for the generation table. xib and xigen are in the format of,
<blocks>x<block size> <file size>
Note that a filesystem usually has a feature called pre-allocation, which means a number of blocks are allocated automatically, and then deallocated silently when the filesystem thinks they are unnecessary. You do not have to be surprised the sudden changes of the number of blocks, when your filesystem which xino files are placed supports the pre-allocation feature.
The rests are hidden xino file information in the format of,
<file count>, <blocks>x<block size> <file size>
If the file count is larger than 1, it means some of your branches are on the same filesystem and the xino file is shared by them. Note that the file size may not be equal to the actual consuming blocks since xino file is a sparse file, i.e. a hole in a file which does not consume any disk blocks.
Once you unmount aufs, the xino files for that aufs are totally gone. It means that the inode number is not permanent across umount or shutdown.
The xino files should be created on the filesystem except NFS. If your first writable branch is NFS, you will need to specify xino file path other than NFS. Also if you are going to remove the branch where xino files exist or change the branch permission to readonly, you need to use xino option before del/mod the branch.
The bitmap file can be truncated. For example, if you delete a branch which has huge number of files, many inode numbers will be recycled and the bitmap will be truncated to smaller size. Aufs does this automatically when a branch is deleted. You can truncate it anytime you like if you specify [oq]trunc_xib[cq] mount option. But when the accessed inode number was not deleted, nothing will be truncated. If you do not want to truncate it (it may be slow) when you delete a branch, specify [oq]notrunc_xib[cq] after [oq]del[cq] mount option.
If you do not want to use xino, use noxino mount option. Use this option with care, since the inode number may be changed silently and unexpectedly anytime. For example, rmdir failure, recursive chmod/chown/etc to a large and deep directory or anything else. And some applications will not work correctly. If you want to change the xino default path, use xino mount option.
After you add branches, the persistence of inode number may not be guaranteed. At remount time, cached but unused inodes are discarded. And the newly appeared inode may have different inode number at the next access time. The inodes in use have the persistent inode number.
When aufs assigned an inode number to a file, and if you create the same named file on the upper branch directly, then the next time you access the file, aufs may assign another inode number to the file even if you use xino option. Some applications may treat the file whose inode number has been changed as totally different file.
When you have files named fileA and fileB which are hardlinked on a readonly branch, if you write something into fileA, aufs copies-up fileA to a writable branch, and write(2) the originally requested thing to the copied-up fileA. On the writable branch, fileA is not hardlinked. But aufs remembers it was hardlinked, and handles fileB as if it existed on the writable branch, by referencing fileA[aq]s inode on the writable branch as fileB[aq]s inode.
Once you unmount aufs, the plink info for that aufs kept in memory are totally gone. It means that the pseudo-link is not permanent. If you want to make plink permanent, try [oq]auplink[cq] utility just before one of these operations, unmounting your aufs, using [oq]ro[cq] or [oq]noplink[cq] mount option, deleting a branch from aufs, adding a branch into aufs, or changing your writable branch to readonly.
This utility will reproduces all real hardlinks on a writable branch by linking them, and removes pseudo-link info in memory and temporary link on the writable branch. Since this utility access your branches directly, you cannot hide them by [oq]mount --bind /tmp /branch[cq] or something.
If you are willing to rebuild your aufs with the same branches later, you should use auplink utility before you umount your aufs. If you installed both of /sbin/mount.aufs and /sbin/umount.aufs, and your mount(8) and umount(8) support them, [oq]auplink[cq] utility will be executed automatically and flush pseudo-links.
# auplink /your/aufs/root flush # umount /your/aufs/root or # auplink /your/aufs/root flush # mount -o remount,mod:/your/writable/branch=ro /your/aufs/root or # auplink /your/aufs/root flush # mount -o remount,noplink /your/aufs/root or # auplink /your/aufs/root flush # mount -o remount,del:/your/aufs/branch /your/aufs/root or # auplink /your/aufs/root flush # mount -o remount,append:/your/aufs/branch /your/aufs/root
The plinks are kept both in memory and on disk. When they consumes too much resources on your system, you can use the [oq]auplink[cq] utility at anytime and throw away the unnecessary pseudo-links in safe.
Additionally, the [oq]auplink[cq] utility is very useful for some security reasons. For example, when you have a directory whose permission flags are 0700, and a file who is 0644 under the 0700 directory. Usually, all files under the 0700 directory are private and no one else can see the file. But when the directory is 0711 and someone else knows the 0644 filename, he can read the file.
Basically, aufs pseudo-link feature creates a temporary link under the directory whose owner is root and the permission flags are 0700. But when the writable branch is NFS, aufs sets 0711 to the directory. When the 0644 file is pseudo-linked, the temporary link, of course the contents of the file is totally equivalent, will be created under the 0711 directory. The filename will be generated by its inode number. While it is hard to know the generated filename, someone else may try peeping the temporary pseudo-linked file by his software tool which may try the name from one to MAX_INT or something. In this case, the 0644 file will be read unexpectedly. I am afraid that leaving the temporary pseudo-links can be a security hole. It makes sense to execute [oq]auplink /your/aufs/root flush[cq] periodically, when your writable branch is NFS.
When your writable branch is not NFS, or all users are careful enough to set 0600 to their private files, you do not have to worry about this issue.
If you do not want this feature, use [oq]noplink[cq] mount option.
none on /dev/shm/u type aufs (rw,xino=/dev/shm/rw/.aufs.xino,br:/dev/shm/rw=rw:/dev/shm/ro=ro) $ ls -li ../r?/f_src_linked* ./f_src_linked* ./copied ls: ./copied: No such file or directory 15 -rw-r--r-- 2 jro jro 2 Dec 22 11:03 ../ro/f_src_linked 15 -rw-r--r-- 2 jro jro 2 Dec 22 11:03 ../ro/f_src_linked2 22 -rw-r--r-- 2 jro jro 2 Dec 22 11:03 ./f_src_linked 22 -rw-r--r-- 2 jro jro 2 Dec 22 11:03 ./f_src_linked2 $ echo abc >> f_src_linked $ cp f_src_linked copied $ ls -li ../r?/f_src_linked* ./f_src_linked* ./copied 15 -rw-r--r-- 2 jro jro 2 Dec 22 11:03 ../ro/f_src_linked 15 -rw-r--r-- 2 jro jro 2 Dec 22 11:03 ../ro/f_src_linked2 36 -rw-r--r-- 2 jro jro 6 Dec 22 11:03 ../rw/f_src_linked 53 -rw-r--r-- 1 jro jro 6 Dec 22 11:03 ./copied 22 -rw-r--r-- 2 jro jro 6 Dec 22 11:03 ./f_src_linked 22 -rw-r--r-- 2 jro jro 6 Dec 22 11:03 ./f_src_linked2 $ cmp copied f_src_linked2 $ none on /dev/shm/u type aufs (rw,xino=/dev/shm/rw/.aufs.xino,noplink,br:/dev/shm/rw=rw:/dev/shm/ro=ro) $ ls -li ../r?/f_src_linked* ./f_src_linked* ./copied ls: ./copied: No such file or directory 17 -rw-r--r-- 2 jro jro 2 Dec 22 11:03 ../ro/f_src_linked 17 -rw-r--r-- 2 jro jro 2 Dec 22 11:03 ../ro/f_src_linked2 23 -rw-r--r-- 2 jro jro 2 Dec 22 11:03 ./f_src_linked 23 -rw-r--r-- 2 jro jro 2 Dec 22 11:03 ./f_src_linked2 $ echo abc >> f_src_linked $ cp f_src_linked copied $ ls -li ../r?/f_src_linked* ./f_src_linked* ./copied 17 -rw-r--r-- 2 jro jro 2 Dec 22 11:03 ../ro/f_src_linked 17 -rw-r--r-- 2 jro jro 2 Dec 22 11:03 ../ro/f_src_linked2 36 -rw-r--r-- 1 jro jro 6 Dec 22 11:03 ../rw/f_src_linked 53 -rw-r--r-- 1 jro jro 6 Dec 22 11:03 ./copied 23 -rw-r--r-- 2 jro jro 6 Dec 22 11:03 ./f_src_linked 23 -rw-r--r-- 2 jro jro 6 Dec 22 11:03 ./f_src_linked2 $ cmp copied f_src_linked2 cmp: EOF on f_src_linked2 $
If you add a branch which has fileA or fileB, aufs does not follow the pseudo link. The file on the added branch has no relation to the same named file(s) on the lower branch(es). If you use noxino mount option, pseudo link will not work after the kernel shrinks the inode cache.
This feature will not work for squashfs before version 3.2 since its inode is tricky. When the inode is hardlinked, squashfs inodes has the same inode number and correct link count, but the inode memory object is different. Squashfs inodes (before v3.2) are generated for each, even they are hardlinked.
Aufs has a mount option named [oq]udba[cq] which specifies the test level at access time whether UDBA was happened or not.
It is recommended to use this option only when you are sure that nobody access a file on a branch. It might be difficult for you to achieve real [oq]no UDBA[cq] world when you cannot stop your users doing [oq]find / -ls[cq] or something. If you really want to forbid all of your users to UDBA, here is a trick for it. With this trick, users cannot see the branches directly and aufs runs with no problem, except [oq]auplink[cq] utility. But if you are not familiar with aufs, this trick may make yourself confused.
# d=/tmp/.aufs.hide # mkdir $d # for i in $branches_you_want_to_hide > do > mount -n --bind $d $i > done
When you unmount the aufs, delete/modify the branch by remount, or you want to show the hidden branches again, unmount the bound /tmp/.aufs.hide.
# umount -n $branches_you_want_to_unbound
If you use FUSE filesystem as an aufs branch which supports hardlink, you should not set this option, since FUSE makes inode objects for each hardlinks (at least in linux-2.6.23). When your FUSE filesystem maintains them at link/unlinking, it is equivalent to [oq]direct branch access[cq] for aufs.
This rule leads to some unexpected situation, but I hope it is harmless. Those are totally depends upon cache. Here are just a few examples.
If your outer modification (UDBA) is rare and you can ignore the temporary and minor differences between virtual aufs world and real branch filesystem, then try this mount option.
When a user accesses the file which was notified UDBA before, the cached data about the file will be discarded and aufs re-lookup it. So the data will be updated. When an error condition occurs between UDBA and aufs operation, aufs will return an error, including EIO. To use this option, you need to enable CONFIG_INOTIFY and CONFIG_AUFS_UDBA_INOTIFY.
To rename/rmdir a directory on a branch directory may reveal the same named directory on the lower branch. Aufs tries re-lookuping the renamed directory and the revealed directory and assigning different inode number to them. But the inode number including their children can be a problem. The inode numbers will be changed silently, and aufs may produce a warning. If you rename a directory repeatedly and reveal/hide the lower directory, then aufs may confuse their inode numbers too. It depends upon the system cache.
When you make a directory in aufs and mount other filesystem on it, the directory in aufs cannot be removed expectedly because it is a mount point. But the same named directory on the writable branch can be removed, if someone wants. It is just an empty directory, instead of a mount point. Aufs cannot stop such direct rmdir, but produces a warning about it.
If the pseudo-linked file is hardlinked or unlinked on the branch directly, its inode link count in aufs may be incorrect. It is recommended to flush the pseudo-links by auplink script.
Some people may call it can be a security hole or invite DoS attack since the opened and once readdir-ed dir (file object) holds its entry list and becomes a pressure for system memory. But I would say it is similar to files under /proc or /sys. The virtual files in them also holds a memory page (generally) while they are opened. When an idea to reduce memory for them is introduced, it will be applied to aufs too.
The dynamically allocated memory block for the name of entries has a unit of AUFS_RDBLK_DEF] bytes by default. During building dir blocks, aufs creates hash list (hashed and divided by AUFS_RDHASH_DEF] by default) and judging whether the entry is whiteouted by its upper branch or already listed.
These values are suitable for normal environments. But you may have millions of files or very long filenames under a single directory. For such cases, you may need to customize these values by specifying rdblk= and rdhash= aufs mount options.
For instance, there are 97 files under my /bin, and the total name length is 597 bytes.
$ \ls -1 /bin | wc 97 97 597
Strictly speaking, 97 end-of-line codes are included. But it is OK since aufs VDIR also stores the name length in 1 byte. In this case, you do not need to customize the default values. 597 bytes filenames will be stored in 2 VDIR memory blocks (597 < AUFS_RDBLK_DEF] x 2). And 97 filenames are distributed among AUFS_RDHASH_DEF] lists, so one list will point 4 names in average. To judge the names is whiteouted or not, the number of comparison will be 4. 2 memory allocations and 4 comparison costs low (even if the directory is opened for a long time). So you do not need to customize.
If your directory has millions of files, the you will need to specify rdblk= and rdhash=.
$ ls -U /mnt/rotating-rust | wc -l 1382438
In this case, assuming the average length of filenames is 6, in order to get better time performance I would recommend to set $((128*1024)) or $((64*1024)) for rdblk, and $((8*1024)) or $((4*1024)) for rdhash. You can change these values of the active aufs mount by "mount -o remount".
This customization is not for reducing the memory space, but for reducing time for the number of memory allocation and the name comparison. The larger value is faster, in general. Of course, you will need system memory. This is a generic "time-vs-space" problem.
If you enable CONFIG_AUFS_RDU at compiling aufs, and install libau.so in aufs2-util GIT tree (by "make install_ulib"), then you can use RDU. Just simply set the environment variable "LD_PRELOAD=libau.so" and run your application. The dynamic link library libau.so implements another readdir routine, and all readdir(3) calls in your application will be handled by libau.so.
When you call readdir(3), the dynamic linker calls readdir in libau.so. If it finds the passed dir is NOT aufs, it calls the usual readdir(3). It the dir is aufs, then libau.so gets all filenames under the dir by aufs specific ioctl(2)s, instead of regular readdir(3), and merges them by itself. In other words, libau.so moves the memory consumption in kernel-space to user-space.
While it is good to stop consuming much memory in kernel-space, sometimes the speed performance may be damaged a little as a side effect. It is just a little, I hope. At the same time, I won[aq]t be surprised if readdir(3) runs faster.
It is recommended to specify rdblk=0 when you use this library.
If your directory is not so huge and you don[aq]t meet the out of memory situation, probably you don[aq]t need this library. The original VDIR in kernel-space is still alive, and you can live without libau.so.
You may see the message when you change the xino file path or truncate the xino/xib files. Sometimes those files can be large and may take a long time to handle them.
/aufs = /rw1 + /ro+wh/diropq + /rw2 /aufs = /rw1 + /ro+wh/wh.tgt + /rw2
/aufs = /rw1/diropq + /rw2 /aufs = /rw1/wh.tgt + /rw2
There are some limitations or requirements.
If you want to discard cache within a certain filesystem, try [oq]mount -o remount /your/mntpnt[cq]. Some filesystem may return an error of EINVAL or something, but VFS discards the unused dentry/inode caches on the specified filesystem.
Ignoring [oq]delete[cq] option, and to keep filesystem consistency, aufs tries writing something to only one branch in a single systemcall. It means aufs may copyup even if the copyup-src branch is specified as writable. For example, you have two writable branches and a large regular file on the lower writable branch. When you issue rename(2) to the file on aufs, aufs may copyup it to the upper writable branch. If this behaviour is not what you want, then you should rename(2) it on the lower branch directly.
And there is a simple shell script [oq]unionctl[cq] under sample subdirectory, which is compatible with unionctl(8) in Unionfs Version 1.x series, except --query action. This script executes mount(8) with [oq]remount[cq] option and uses add/del/mod aufs mount options. If you are familiar with Unionfs Version 1.x series and want to use unionctl(8), you can try this script instead of using mount -o remount,... directly. Aufs does not support ioctl(2) interface. This script is highly depending upon mount(8) in util-linux-2.12p package, and you need to mount /proc to use this script. If your mount(8) version differs, you can try modifying this script. It is very easy. The unionctl script is just for a sample usage of aufs remount interface.
Aufs uses the external inode number bitmap and translation table by default.
The default branch permission for the first branch is [oq]rw[cq], and the rest is [oq]ro.[cq]
The whiteout is for hiding files on lower branches. Also it is applied to stop readdir going lower branches. The latter case is called [oq]opaque directory.[cq] Any whiteout is an empty file, it means whiteout is just an mark. In the case of hiding lower files, the name of whiteout is [oq]AUFS_WH_PFX]<filename>.[cq] And in the case of stopping readdir, the name is [oq]AUFS_WH_PFX]AUFS_WH_PFX].opq[cq] or [oq]AUFS_WH_PFX]__dir_opaque.[cq] The name depends upon your compile configuration CONFIG_AUFS_COMPAT. All whiteouts are hardlinked, including [oq]<writable branch top dir>/AUFS_WH_BASE].[cq]
The hardlink on an ordinary (disk based) filesystem does not consume inode resource newly. But in linux tmpfs, the number of free inodes will be decremented by link(2). It is recommended to specify nr_inodes option to your tmpfs if you meet ENOSPC. Use this option after checking by [oq]df -i.[cq]
When you rmdir or rename-to the dir who has a number of whiteouts, aufs rename the dir to the temporary whiteouted-name like [oq]AUFS_WH_PFX]<dir>.<random hex>.[cq] Then remove it after actual operation. cf. mount option [oq]dirwh.[cq]
The test for permission bits has two cases. One is for a directory, and the other is for a non-directory. In the case of a directory, aufs checks the permission bits of all existing directories. It means you need the correct privilege for the directories including the lower branches. The test for a non-directory is more simple. It checks only the topmost inode.
statfs(2) returns the information of the first branch info except namelen when [oq]nosum[cq] is specified (the default). The namelen is decreased by the whiteout prefix length. And the block size may differ from st_blksize which is obtained by stat(2).
Remember, seekdir(3) and telldir(3) are not defined in POSIX. They may not work as you expect. Try rewinddir(3) or re-open the dir.
The whiteout prefix (AUFS_WH_PFX]) is reserved on all branches. Users should not handle the filename begins with this prefix. In order to future whiteout, the maximum filename length is limited by the longest value - AUFS_WH_PFX_LEN]. It may be a violation of POSIX.
If you dislike the difference between the aufs entries in /etc/mtab and /proc/mounts, and if you are using mount(8) in util-linux package, then try ./mount.aufs utility. Copy the script to /sbin/mount.aufs. This simple utility tries updating /etc/mtab. If you do not care about /etc/mtab, you can ignore this utility. Remember this utility is highly depending upon mount(8) in util-linux-2.12p package, and you need to mount /proc.
Since aufs uses its own inode and dentry, your system may cache huge number of inodes and dentries. It can be as twice as all of the files in your union. It means that unmounting or remounting readonly at shutdown time may take a long time, since mount(2) in VFS tries freeing all of the cache on the target filesystem.
When you open a directory, aufs will open several directories internally. It means you may reach the limit of the number of file descriptor. And when the lower directory cannot be opened, aufs will close all the opened upper directories and return an error.
The sub-mount under the branch of local filesystem is ignored. For example, if you have mount another filesystem on /branch/another/mntpnt, the files under [oq]mntpnt[cq] will be ignored by aufs. It is recommended to mount the sub-mount under the mounted aufs. For example,
# sudo mount /dev/sdaXX /ro_branch # d=another/mntpnt # sudo mount /dev/sdbXX /ro_branch/$d # mkdir -p /rw_branch/$d # sudo mount -t aufs -o br:/rw_branch:/ro_branch none /aufs # sudo mount -t aufs -o br:/rw_branch/${d}:/ro_branch/${d} none /aufs/another/$d
There are several characters which are not allowed to use in a branch directory path and xino filename. See detail in Branch Syntax and Mount Option.
The file-lock which means fcntl(2) with F_SETLK, F_SETLKW or F_GETLK, flock(2) and lockf(3), is applied to virtual aufs file only, not to the file on a branch. It means you can break the lock by accessing a branch directly. TODO: check [oq]security[cq] to hook locks, as inotify does.
The I/O to the named pipe or local socket are not handled by aufs, even if it exists in aufs. After the reader and the writer established their connection if the pipe/socket are copied-up, they keep using the old one instead of the copied-up one.
The fsync(2) and fdatasync(2) systemcalls return 0 which means success, even if the given file descriptor is not opened for writing. I am afraid this behaviour may violate some standards. Checking the behaviour of fsync(2) on ext2, aufs decided to return success.
If you want to use disk-quota, you should set it up to your writable branch since aufs does not have its own block device.
When your aufs is the root directory of your system, and your system tells you some of the filesystem were not unmounted cleanly, try these procedure when you shutdown your system.
# mount -no remount,ro / # for i in $writable_branches # do mount -no remount,ro $i # doneIf your xino file is on a hard drive, you also need to specify [oq]noxino[cq] option or [oq]xino=/your/tmpfs/xino[cq] at remounting root directory.
To rename(2) directory may return EXDEV even if both of src and tgt are on the same aufs. When the rename-src dir exists on multiple branches and the lower dir has child(ren), aufs has to copyup all his children. It can be recursive copyup. Current aufs does not support such huge copyup operation at one time in kernel space, instead produces a warning and returns EXDEV. Generally, mv(1) detects this error and tries mkdir(2) and rename(2) or copy/unlink recursively. So the result is harmless. If your application which issues rename(2) for a directory does not support EXDEV, it will not work on aufs. Also this specification is applied to the case when the src directory exists on the lower readonly branch and it has child(ren).
If a sudden accident such like a power failure happens during aufs is performing, and regular fsck for branch filesystems is completed after the disaster, you need to extra fsck for aufs writable branches. It is necessary to check whether the whiteout remains incorrectly or not, eg. the real filename and the whiteout for it under the same parent directory. If such whiteout remains, aufs cannot handle the file correctly. To check the consistency from the aufs[aq] point of view, you can use a simple shell script called /sbin/auchk. Its purpose is a fsck tool for aufs, and it checks the illegal whiteout, the remained pseudo-links and the remained aufs-temp files. If they are found, the utility reports you and asks whether to delete or not. It is recommended to execute /sbin/auchk for every writable branch filesystem before mounting aufs if the system experienced crash.
# mount -v -t aufs br:/day0:/base none /u none on /u type aufs (rw,xino=/day0/.aufs.xino,br:/day0=rw:/base=ro) # mount -v -o remount,\ prepend:/day1,\ xino=/day1/xino,\ mod:/day0=ro,\ del:/day0 \ /u none on /u type aufs (rw,xino=/day1/xino,br:/day1=rw:/base=ro)
# mount -t aufs br:/rw none /u # mount -o remount,append:/ro /u different uid/gid/permission, /ro # mount -o remount,del:/ro /u # mount -o remount,nowarn_perm,append:/ro /u # (there is no warning)
When you use aufs as root filesystem, it is recommended to consider to exclude some directories. For example, /tmp and /var/log are not need to stack in many cases. They do not usually need to copyup or to whiteout. Also the swapfile on aufs (a regular file, not a block device) is not supported. In order to exclude the specific dir from aufs, try bind mounting.
And there is a good sample which is for network booted diskless machines. See sample/ in detail.
When you mount or remount your union without -o ro common mount option and without writable branch, aufs will warn you that the first branch should be writable.
When you set udba other than inotify and change something on your branch filesystem directly, later aufs may detect some mismatches to its cache. If it is a critical mismatch, aufs returns EIO.
When an error occurs in aufs, aufs prints the kernel message with [oq]errno.[cq] The priority of the message (log level) is ERR or WARNING which depends upon the message itself. You can convert the [oq]errno[cq] into the error message by perror(3), strerror(3) or something. For example, the [oq]errno[cq] in the message [oq]I/O Error, write failed (-28)[cq] is 28 which means ENOSPC or [oq]No space left on device.[cq]
When CONFIG_AUFS_BR_RAMFS is enabled, you can specify ramfs as an aufs branch. Since ramfs is simple, it does not set the maximum link count originally. In aufs, it is very dangerous, particularly for whiteouts. Finally aufs sets the maximum link count for ramfs. The value is 32000 which is borrowed from ext2.