Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1858041
  • 博文数量: 473
  • 博客积分: 13997
  • 博客等级: 上将
  • 技术积分: 5953
  • 用 户 组: 普通用户
  • 注册时间: 2010-01-22 11:52
文章分类

全部博文(473)

文章存档

2014年(8)

2013年(38)

2012年(95)

2011年(181)

2010年(151)

分类: LINUX

2010-02-02 20:05:40

aufs
--------------------------------------------------------------------------------
名称
        aufs - 另一个 unionfs. 版本 20090126

描述
        Aufs是一个类似于Unionfs的可堆叠联合文件系统,它将多个目录整合成单一的目录。早些时候aufs致力于重新设计并重新实现 Unionfs版本1.x系列。但经过许多的原创、改进以及提高后,在保持基本特性的前提下已经变得与Unionfs截然不同了。基本功能可以参考 Unionfs版本1.x系列。最近,Unionfs版本2.x系列已经开始向aufs靠拢。

MOUNT 选项
        mount的时候,选项的解释顺序为,
           
· 简单标志,除了xino/noxino,udba=inotify 和dlgt
            · 分支
            · xino/noxino
            · udba=inotify
            · dlgt
        在remount的时候,选项被按照给定的顺序解释,例如从左至右,除了dlgt。
'dlgt'选项是不会被解释的。
           
· 如果需要则创建或者删除 whiteout-base(.wh..wh.aufs) 和 whplink-dir(.wh..wh.plnk)
            · 如果需要则重新使 dlgt 生效

        br:分支[:分支 ...] (dirs=分支[:分支 ...])

           
添加新的分支。 (参考分支语法)
            Aufs拒绝那些身为其它分的支祖先或者后裔的分支。这被称为重叠。如果一个分支是loop mount的目录,aufs还会检查loopback设备的fs-image源文件。如果源文件是另一个分支的后裔,它也会被拒绝。
            aufsmount或者添加一个分支后,如果你将一个分支移动到另一个分支的分支下层并且将其设为另一个分支的后裔,aufs将无法正常工作。

       
[ add | ins ]:index:分支

           
添加一个新的分支。index0开始。如果需要的话Aufs创建whiteout-base(.wh..wh.aufs)whplink-dir(.wh..wh.plnk)
            如果有同名文件为于低层分支(index较大),aufs将隐藏低层的文件。你仅能看到高层的文件。你可能会感到迷惑如果分支使用了whiteouts(包括diropq),它们可以隐藏低层的入口或反之。
            如果一个进程曾经使用带MAP_SHAREDmmap(2)映射了一个文件,并且有一个同名文件位于低层分支,这个进程将在添加分支后引用低层(隐藏)分支的文件。如果你想在添加分支后更新进程地址空间,你需要重启你的进程或者再一次open/mmap这个文件。 (参考分支语法)

       
del:dir

            删除一个分支。aufs不会自动删除whiteout-base(.wh..wh.aufs)和whplink-dir(.wh..wh.plnk)。例如,当你将一个曾经的RW分支重新添加为RO的时候,你将会看到whiteout-base或者whplink-dir存在于这个RO分支。
           
如果一个进程正在引用位于即将删除分支的文件/目录的时候(通过openmmap,当前工作目录,等)aufs将会返回一个EBUSY错误。

       
mod:BRANCH

            改变分支的权限标志。如果需要的话Aufs会创建或者删除whiteout-base(.wh..wh.aufs)和/或whplink-dir(.wh..wh.plnk)。
           
如果分支权限从'rw'变为'ro',并且一个进程正在通过mmap(2)映射一个位于此分支的文件,在修改分支权限标志后进程可能无法修改它所映射的内存区域或反之。(参考分支语法)

       
append:BRANCH

            等价于'addlast index + 1):BRANCH'。
(参考分支语法)

       
prepend:BRANCH

            等价于'add:0:BRANCH'。
(参考分支语法)

       
xino=filename

            使用外部inode数字位图和转换表。当CONFIG_AUFS_EXPORT无效时,外部的inode生成表也随之无效。它被默认置为<第一个可写层>/.aufs.xino,或者/tmp/.aufs.xino。
文件名中禁止使用点。
            每个aufs和每个分支文件系统都会创建文件,并且不被链接。所以你无法找到这些文件,但它们确实存在并且被aufs频繁读写。(参考外部Inode数字位图, 转换表和世代表)

        noxino
            停止使用外部inode数字位图,转换表和世代表。

            如果你使用这个选项,有些应用可能无法正常工作。(参考外部Inode数字位图,转换表和世代表)

        trunc_xib

            压缩外部inode数字位图文件。压缩动作将在你删除一个分支时自动执行除非你指定了'notrunc_xib'(参考外部Inode数字位图, 转换表和世代表)

        notrunc_xib

            当你删除一个分支的时候不压缩外部inode数字位图文件。(参考External Inode 数字位图, 转换表和世代表)

        create_policy | create=CREATE_POLICY
        copyup_policy | copyup | cpup=COPYUP_POLICY

            多个可写分支选择策略。默认值是'create=tdp''cpup=tdp。系统调用link(2)rename(2)例外。在aufs中,它们尽量在源数据所在分支执行操作。(参考多个可写分支中的选择策略)

        verbose | v

            打印详细信息。目前,它仅仅在文件(inode)位于要删除的分支时工作。

       
noverbose | quiet | q | silent

           
关闭'verbose'选项,这是默认值。

       
sum
            df(1)/statfs(2)返回所有分支的块和inodes总数。注意有时候系统调用会返回ENOSPC,即使df(1)/statfs(2)显示aufs仍然有一些空余间/inode。

        nosum
            关闭'sum'选项,这是默认值。

       
dirwh=N

            rmdir(2)rename(2)目录时实际上只将其记为删除。
            如果将被删除或者重命名(目的目录)的目标目录存在大量的whiteouts,也就是这个目录是逻辑上空而物理上非空的,那么rmdir/rename 的开销将非常大。这需要在分支上执行rmdir/rename操作之前必须首先删除所有内部的whiteouts。为了减少单一系统调用的开销,aufs 把目标目录重命名为一个whiteout-ed的临时名并调用一个预先创建好的内核线程去删除whiteout-ed的子目录以及它本身。系统调用 rmdir/rename只要开启线程后即可返回。
            如果whiteout-ed的子目录少于dirwh指定的数字,aufs将在同一个系统调用中删除它们而非再启动一个线程。如果分支为NFS,这个值将被忽略,默认值为3

       
plink
        noplink

            指定是否使用使用'plink'特性。
默认值是'plink'意味着使用此特性。(参考伪链接)

       
clean_plink

            删除内存中的所有伪链接。为了使伪链接永久有效应该在执行以下操作前首先调用'auplink'脚本:卸载aufs、使用'ro'或者 'noplink' mount选项、从aufs删除一个分支、向aufs添加一个分支、或者将你的可写分支变成只读。如果你安装了/sbin/mount.aufs和 /sbin/umount.aufs,并且你的mount(和umount(支持它们,并且/etc/default/auplink已经配置好了,那么'auplink'脚本将被自动执行并更新伪链接。
(参考伪链接)

       
udba=none | reval | inotify

           
指定UDBA(用户直接分支访问)测试级别。(参考用户直接分支访问和Inotify限制)

       
diropq=whiteouted | w | always | a

            指定mkdir(2)和rename(2)目录时是否创建'opaque'目录。也就是在被创建或重命名的目录下创建'.wh..wh..opq',或反之。当你指定了diropq=w或diropq=whiteouted,如果目录没有被whiteouted或opaqued的话aufs不会创建它。如果目录被whiteouted或者opaqued,被创建或重命名的目录将会被隐藏。当你指定了diropq=a或 diropq==always,aufs将会强制创建它而不管这个目录是否被whiteouted/opaqued。默认值为diropq=w,它意味着如果不是必需就不创建。
如果你在编译aufs的时候打开了CONFIG_AUFS_COMPAT,那么默认值则为diropq=a,如果你打算以后添加一个分支你需要认真考虑这个选项因为'diropq’会对新添加的同名目录产生影响。

       
warn_perm
        nowarn_perm

           
添加一个分支,aufs将会对于新添加分支的uid/gid/permission抛出警告,当它们与已经存在的分支存在差异的时候。这种差异有可能会导致一个安全风险或反之。如果你确定没有问题并且想停止这些警告,使用'nowarn_perm'选项。默认值是'warn_perm'(参考诊断)

        coo=none | leaf | all

            指定打开拷贝级别。当你打开一个只读分支的文件时,aufs将其拷贝至上层的可写分支然后打开它。这个选项对于想降低磁盘转速以省电的人很有用,或者是那些想监视哪些文件被访问过的人。如果指定了关键字'all'的话,aufs将向上拷贝目标哪怕它是目录。这样的话,简单的’ls’或者’find’都会导致向上拷贝从而使你的可写分支产生大量的空目录。如果指定了关键字’leaf’的话,aufs将向上拷贝那些非目录的打开目标。关键字’none’将关闭打开时拷贝。当aufs自己被mounted为只读的时候,’coo=none’将强制生效而不管是否指定了其它值。其它的会返回一个错误。默认值是 ’coo=none’

        dlgt
        nodlgt
            如果你不希望你的应用通过aufs访问分支或者被任务I/O统计严格追溯的话,你可以在aufs中使用内核线程。如果你打开了 CONFIG_AUFS_DLGT并且mount选项中指定了’dlgt’,那么aufs把它的内部分支访问委托给内核线程。

            当你打开了CONFIG_SECURITY并且使用任意了一种Linux安全模块(LSM),例如SUSE AppArmor,你可能会从你的安全模块得到一些错误或警告。因为aufs把分支的内部访问委托给内核线程,你的安全模块将会检测到、报告、或阻止它。这种行为严重依赖于你的安全模块以及它的配置。既然这样,使用’dlgt’mount选项也同样如此。你的LSM将会察觉到aufs内核线程访问分支,而非你的应用。
            这种委托可能会对性能产生负面的影响因为其中包含任务切换(调度)以及等待线程完成被委托的访问。你应该关心内核线程数的增加并指定aufs模块参数’nwkq’
           
目前,aufs不会在mount和remount时进行委托。默认值是nodlgt意味着aufs不会委托内部访问。

        shwh
        noshwh
            默认情况下(noshwh),aufs不显示whiteouts并且它们仅仅掩藏低层分支的同名entries。whiteout本身也一直不可见。如果你打开了CONFIG_AUFS_SHWH并且指定了’shwh’选项,aufs将会让你看见那些whiteouts的名字并保持它的隐藏低层的特性。说实话,我对这个’visible whiteouts’相当迷惑。
但是最初对此特性提出需求的用户写了一个针对这一特性非常好的how-to文档。可以看看aufs CVS树的置顶文件。

模块参数
        nwkq=N
            名为aufsd的内核线程数。
 
            aufs模块载入后这些线程驻留于系统,负责处理aufs的专有I/O请求。默认值是4
            来自于aufs的专有I/O请求包含一部分的向上拷贝、检测、目录操作、伪链接、xino文件操作以及委托分支访问。例如,Unix文件系统允许你 rmdir(2)那些没有写权限的目录,只要它的父目录有写权限。在aufs中,被删除的目录可能包含标记为whiteout目录不可见子项或反之。aufs需要在rmdir(2)它们之前首先unlink(2)它们。因此aufs将实际的unlink(2)rmdir(2)委托给另一个已经事先创建好并拥有超级用户权限的线程。
           
如果你打开了CONFIG_SYSFS,你可以通过/module/aufs/parameters/nwkq检查这个值。
            那么多少线程就足够了呢?你可以通过/fs/aufs/stat检查它,如果你打开了 CONFIG_AUFS_SYSAUFS(内核2.6.24及以前)或者CONFIG_AUFS_STAT(内核2.6.25及以后)。
它显示某一时刻每一个线程的最大已排队任务数。通常它们都是比较小的数字或者0。如果的负荷压力很大并且你感觉到反应很慢,那么检查一下这些值。如果存在非0且任何一个大于23的值,你就应该把模块参数’nwkq’设得比默认值更大些。但是如果反应慢的原因是由于你分支上的文件系统所导致的,那么增加这个值将于事无补。
            /fs/aufs/stat中逗号后最后一个数字是某一时刻最大非等待已排队任务。Aufs把那些称之为事件的任务排队到全局任务队列,但是并不等待它们完成。通常它们不会影响aufs的时效性。

       
brs=1 | 0

            指定是否使用sysfs中的分支路径数据文件。
            如果分支的数目很多或者它们的路径很长你可能会遇到mount(或者/etc/mtab的限制,你需要打开CONFIG_SYSFS并且设置aufs模块参数brs=1。如果你的linux版本是linux 2.6.24或者更早,你还需要打开CONFIG_AUFS_SYSAUFS。
            当这个参数被设置为1,aufs不通过/proc/mounts显示’br:’(或dirs=)mount选项,而且/sbin/mount.aufs不将其放到/etc/mtab中。因此你可以避免受到mount(或者/etc/mtab的版面限制。Aufs在/fs/aufs/si_XXX/brNNN中显示分支路径。实际上sysfs中的文件也有大小限制,但我不认为那会有问题。
            默认值是brs=0,它意味着/fs/aufs/si_XXX/brNNN不会存在而且’br:’选项会出现在/proc /mounts,以及/etc/mtab中如果你安装了/sbin/mount.aufs的话。
如果你没有打开 CONFIG_AUFS_SYSAUFS(内核2.6.24以及更早),这个参数将被忽略。
            这个参数设为1还有另一个效果。如果你给你的分支重命名,写入/etc/mtab的分支路径将过期而且在将来remount时由于不匹配的参数将会导致错误(请记住mount(会从/etc/mtab中取得参数并把它们传递给系统调用)。如果你设置为1/etc/mtab中没有记录分支路径而你将不会遇到这个麻烦。另一方面,位于sysfs的分支路径的entires是动态生成的。所以它不会过期。不过我并不认为用户会频繁重命名分支。

       
sysrq=key

            为调试aufs指定MagicSysRq key。你需要打开CONFIG_MAGIC_SYSRQ和CONFIG_AUFS_DEBUG。如果你的linux版本是linux-2.6.24或更早,你还需要打开CONFIG_AUFS_SYSAUFS。
目前这仅仅适用于开发者。默认值是’a’

分支语法
        dir_path[ =permission [ + attribute ] ]
        permission := rw | ro | rr
        attribute := wh | nolwh

            dir_path是一个目录路径。’dir_path=’后面的关键字是那个分支的权限标志。
路径中禁止使用逗号、冒号和权限标志字符串(包括’=’)
            任何的文件系统都可以作为一个分支,除了aufssysfsprocfsunionfs。如果你指定了这些文件系统作为一个分支,aufs将会返回一个错误并说不支持它。如果你打开了CONFIG_AUFS_ROBR,你可以把aufs作为另一个aufs的不可写分支。
            linux稳定版中的Cramfs使用怪异的inodes所以它会导致aufs困惑。例如,
           
$ 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
           
两个目录和两个文件都有相同的链接数为1inodeAufs无法正确处理这样的inode。目前,aufs专为这种inodes投入了一个很小的外围工作。但是有些应用可能无法正常工作因为对于这种inodeaufs中的inode数会悄悄改变。如果你没有空文件、空目录或者特殊文件,cramfs上面的inodes是可以很好地工作的。
            一个分支不应该在多个aufs中作为可写分支而共享。一个只读分支可以被共享。
            最大分支数可以在编译时配置。可配置的值当前为127
            如果给定一个不明的权限或属性,aufs会悄悄地把那个分支设为只读。

   
Permission

        rw
            可读写分支。第一个分支被默认设定如此。如果一个分支的文件系统是被mounted为只读,你不能把它设为’rw’。

        ro
            只读分支并且不包含whiteouts。除了第一个分支的所有的分支被默认设定如此。Aufs绝不会向这个分支派发写操作和whiteout的检测操作。

       
rr
       
            真正的只读分支,’ro’的一种特例,适用于原生的只读分支。假定这个分支是原生只读的,aufs可以优化一些内部操作。例如,如果你指定 ’udba=inotify’选项,aufs并不会在rr分支上面设定inotify。文件系统为’iso9660’’cramfs’’romfs’ ’squashfs’时为默认设定。

        当你的分支位于一个低层设备并且你的磁盘上还有些容量的话,你可能想尝试使用ULOOP示例中的ulobdev工具。它能够缓存真实设备中的内容到另一个高速设备上,因此你可以得到更好的访问效率。ulobdev工具适用于通用块设备,而ulohttp适用于http服务器上的文件系统镜像。如果你想调低你硬盘转速以省电或别的什么,那么你可能也会用到ulobdev把访问保存到硬盘上。详细信息可以查看$AufsCVS/sample /uloop

    Attribute

        wh
       
            只读分支其上可能有whiteout或反之。Aufs从不向这个分支发送写操作,但会检测whiteout。像这样使用=ro+wh’

       
nolwh
            通常,aufs把whiteout创建为一个可写分支的硬链接。这个属性禁止aufs创建被硬链接的whiteout,包括所有被硬链接的 whiteout的源文件(.wh..wh.aufs)。如果你不喜欢硬链接,或者你的可写分支不支持link(2),那么请使用这个属性。
不过我担心一个不支持link(2)的原生文家系统可能会在其它地方诸如向上拷贝等操作时失败。可以这样使用=rw+nolwh’。你也可以尝试使用’noplink’mount选项,尽管它并不被推荐。

外部Inode数字位图,转换表和世代表(xino)


        Aufs默认为每一个分支使用一个外部位图文件和一个外部inode数字转换表文件。此外当打开了CONFIG_AUFS_EXPORT,还会增加一个外部inode 世代表。位图(和世代表)用于循环使用aufsinode数字而其余的则是一张将分支的inode数字转换为aufsinode数的表。默认的路径是第一个可写分支’/.aufs.xino。如果没有可写分支,默认的路径变为/tmp/.aufs.xino
        这些文件总是会被aufs频繁的打开并读写。如果你的可写分支是位于闪存设备上的,建议通过指定’xino=’mount选项将xino文件放到其它非闪存设备上。
        位图的文件最大体积,基本上,是所有分支上的所有文件总数除以8(以字节方式表示位)。例如,在页面为4KB的系统上,如果你有32,768(或者2,599,96aufs文件,那么位图文件的最大体积为4KB(或者320KB).
        表文件的最大体积为分支上的最大inode * 一个inode数字的大小。例如在32位的环境上,
       
$ df -i /branch_fs
        /dev/hda14           2599968  203127 2396841    8% /branch_fs
        /branch_fs是aufs的一个分支。当inode数字为连续排列时(没有出现’空洞’),/branch_fs的xino文件最大体积将是:2,599,968 * 4字节 = 大约10 MB。
但是不会磁盘所有的块都被分配。当inode数字没有连续排列时,xino文件最大体积将是:分支上inode数目的最大值 * 4字节。此外,文件大小受LLONG_MAX或位于文件系统超级块中的s_maxbytes所限制(s_maxbytes可能小于LLONG_MAX)。所以一个分支可以支持的最大inode数字是小于2305843009213693950(LLONG_MAX/4 - 1)。这是当前aufs的限制。在64位环境中,这个限定更为严格而所支持的最大inode数字小于LLONG_MAX/8 - 1
        xino文件是永远被隐藏的,也就是被隔离的。所以你无法执行’ls -l xino_file’。如果你打开了CONFIG_SYSFS,你可能通过/fs/aufs/ /xino检查它(对于内核2.6.24及更早,你需要再打开CONFIG_AUFS_SYSAUFS)。文件/fs /aufs//xino(xigen)的第一行显示了位图文件的信息,格式如下,
        <块数> * <块大小> <文件大小>
        注意文件系统通常有一种称为预分配的特性,这意味着一些块被自动分配了,而当文件系统不再需要的时候又悄悄地释放了它们。当你的文件系统的xino文件被设置为支持预分配特性的时候,你无需因为突然改变块数而惊讶。
        其余的是被隐藏的xino文件信息格式如下,
        <分支索引>: <文件数> <块数> * <块大小> <文件大小>
        如果文件数大于1,它意味着你的一些分支位于同一个文件系统而xino文件被它们共享。注意文件大小可能不等于实际消耗的块数因为xino文件是一个稀疏文件,也就是说在没有消耗任何磁盘块的文件中有一个空洞。
       
一旦你unmount aufs,它的xino文件会彻底消失。它意味着inode数是非持久的。
        xino文件会被创建于非NFS的文件系统。如果你的第一个可写分支是NFS,你需要另外指定一个非NFS的xino文件路径。
如果你打算删除有xino文件的分支或者将分支的属性改为只读,你也需要在del/mod这个分区前使用xino选项。
        位图文件可以被压缩。例如,如果你删除了一个有大量文件的分支,许多inode数字将会被回收而位图将被压缩到较小的体积。当一个分支被删除时 Aufs自动执行此操作。如果你指定了’trunc_xib’mount选项你可以随时压缩它。但是当正在被访问的inode数字不会被删除时,没有什么可被压缩的。当你删除一个分支而不打算压缩它(它可能很慢),可以在’del’后面指定’notrunc_xib’mount选项。
        如果你不打算使用xino文件,可以使用noxino mount选项。小心使用这个选项,因为inode数字可能随时悄悄地出人意料地改变。例如,rmdir失败、对层次很深的目录递归 chmod/chown/等或者别的什么。而且有些应用可能无法正常工作。如果你想改变xino的默认路径,可以使用xino mount选项。
        你添加了一个分支后,inode数字的持久性可能无法被保证。在remount的时候,被缓存但没有使用的inodes被丢弃。下次访问时新的inode可能会是不同的inode数字。正在使用的inodes拥有持续的inode数字。
        aufs分配一个inode数字给一个文件,如果你直接在上层分支创建了同名文件,那么下次你访问这个文件,aufs可能分配另一个inode数字给这个文件即使你使用了xino选项。有些应用可能把inode改变了的文件当做完全不同的文件对待。

伪连接(跨分支硬链接)

        Aufs支持名为伪链接的跨分支逻辑硬链接(参考ln(1)link(2))。换句话说,就是一个通过link(2)生成的向上拷贝的文件和一个位于只读分支文件系统的指向向上拷贝文件的硬链接。

        当你在一个只读分支上有两个名为fileAfileB的硬链接文件,如果你向fileA中写入数据,aufsfileA向上拷贝到一个可写分支,并write(2)原始请求数据到向上拷贝的fileA。在可写分支上,fileA没有被硬链接。但是aufs记得它被硬链接过,于是就好像file 存在于可写分支一样对其处理,通过引用位于可写分支的fileAinode作为fileBinode

        一旦你卸载aufs,此aufs保存于内存中的伪链接信息将全部丢失。这意味着伪链接是非持久的。如果你想使伪链接有持久性,可以在执行下列操作之前试试’auplink’脚本:unmounting你的aufs、使用’ro’或者’noplink’mount选项、从aufs删除一个分支、向 aufs添加一个分支、或者把你的可写分支变为只读。

        这个脚本可以通过链接复制所有位于可写分支的真实硬链接,并且删除内存中的伪链接信息和位于可写分支的临时链接。因为这个脚本直接访问你的分支,你不能使用’mount --bind /tmp /branch’或其它什么方式隐藏它们。

        如果你打算稍后使用相同的分支重构你的aufs,你应该在umount你的aufs前使用auplink脚本。如果你安装了/sbin/mount.aufs/sbin/umount.aufs,并且你的mount(umount(支持它们,并且/etc/default/auplink已经被配置好,’auplink’脚本将会自动被执行并更新伪链接。

       
/etc/default/auplink是一个简单的shell脚本只执行已定义的$FLUSH。如果你的aufs mount点设置到了$FLUSH中,’auplink’会更新那个mount点的伪链接。如果$FLUSH被设置为’ALL’,’auplink’将会对所有的aufs执行操作。

        ’auplink’脚本使用二进制文件’aulchown’,你也需要安装它。’auplink’脚本执行’find’和’mount -o remount’,它们可能花费较长时间并且影响以后的系统性能。如果你没有安装/sbin/mount.aufs,/sbin/umount.aufs 或者/sbin/auplink,但是你希望更新伪链接,那么你需要手动执行’auplink’。如果你已经安装并配置了它们,但是不想在umount的时候执行’auplink’,可以使用’-i’umount(选项。

        # auplink /your/aufs/root flush
        # umount /your/aufs/root
        或者
        # auplink /your/aufs/root flush
        # mount -o remount,mod:/your/writable/branch=ro /your/aufs/root
        或者
        # auplink /your/aufs/root flush
        # mount -o remount,noplink /your/aufs/root
        或者
        # auplink /your/aufs/root flush
        # mount -o remount,del:/your/aufs/branch /your/aufs/root
        或者
        # auplink /your/aufs/root flush
        # mount -o remount,append:/your/aufs/branch /your/aufs/root

       
伪链接同时保存于内存和磁盘。当它们消耗了你系统的过多资源时,你可以随时使用’auplink’脚本安全地丢掉那些不必要的伪链接。

        此外,出于安全原因’auplink’是一个非常有用的脚本。例如,假设你有一个权限标志为0700的目录,而且有一个为0644的文件位于这个 0700目录。通常情况下,所有位于0700目录的文件都是私有且没有别人能够看见的文件。但是当这个目录为0711而有人知道这个0644的文件名时,他就可以读取这个文件。

        基本上,aufs伪链接特性会在所有者为root且权限标志为0700的目录中创建一个临时链接。但是当这个可写分支是NFS是,aufs设置这个目录为0711。当0644文件被伪链接后,临时链接,当然文件的内容完全一致,将会被创建到这个0711目录。文件名会根据它的inode数字而生成。虽然很难知道生成的文件名,但是可能会有人使用穷举1MAX_INT或别的什么的工具尝试偷窥临时伪链接文件。这种情况下,0644文件可能被意外读取。我担心遗留临时硬链接可能是一个安全漏洞。定期执行’auplink /your/aufs/root flush’是非常有意义的,当你的可写分支为NFS时。

        当你的可写分支不是NFS,或者所有的用户都足够小心地把他们的私有文件设为了0600,你不用为此问题担心。

        如果你不想要这个特性,使用’noplink’mount选项而且你不用安装’auplink’脚本和’aulchown’二进制文件。

   
plink和noplink特性

        这个示例展示带有’noplink’选项的’f_src_linked2’无法读取链接。

        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
       
$

        如果你添加一个包含有fileAfileB的分支,aufs并不读取伪链接。新添加的分支上的文件与位于低层的同名文件(们)没有关系。如果你使用noxino mount选项,在内核压缩inode缓存后伪链接将不工作。

        由于其inode难于处理所以这个特性可能在3.2版本以前的squashfs上无法工作。当inode是硬链接时,squashfs inodes拥有相同的inode数以及正确的链接计数,但是inode内存对象却是不同的。Squashfsinodes(v3.2之前)会为每一个而创建,甚至它们被硬链接。


用户直接分支访问(UDBA)


        UDBA就是手动地或者直接地对一个分支文件系统所有的修改,例如绕过aufs。虽然aufs被设计并实现为UDBA后依然安全,但是它可能导致你自己和你的aufs产生困惑。有些信息如aufsinode可能变得不正确。例如,如果你直接rename了一个分支上的文件,这个位于aufs的文件可能可以同时使用新的或者旧的文件名访问或反之。因为aufs缓存分支上文件的各种不同信息。而这些缓存在UDBA后依然还维持原来的状态。

        Aufs有一个mount选项名为 ’udba’它指定测试在访问时是否使用了UDBA的级别。

       
udba=none

            Aufs相信dentry和文件系统上的inode缓存,所以从不测试UDBA。使用这个选项,aufs运行很迅速,但是它可能会显示不正确的数据。此外,如果你经常直接修改一个分支,aufs可能无法追溯分支上面的inodes变动。
它可能引起一些错误的情况,死锁或者别的什么。

            只有你确信没有人会直接访问分支上的文件时才推荐你使用这个选项。如果你不能阻止你的用户使用诸如’find / -ls’的话实现真正的’no UDBA’是非常困难的。如果你真的希望禁止你的所有用户使用UDBA,这里有一个窍门。使用这个窍门,用户无法直接看到分支而aufs运行完全正常,除了’auplink’脚本。但是如果你不是十分熟悉aufs,这个窍门可能会弄晕你自己。

           
# d=/tmp/.aufs.hide
            # mkdir $d
            # for i in $branches_you_want_to_hide
            > do
            > mount -n --bind $d $i
            > done

            当你unmount这个aufs、使用remount delete/modify这个分支、或者你想重新看见这个隐藏的分支时,需要unmount/tmp/.aufs.hide集合。

            # umount -n $branches_you_want_to_unbound

           
如果你使用支持硬链接的FUSE文件系统作为aufs的一个分支,你不应设置这个选项,因为FUSE为每一个硬链接分配inode对象(至少在内核 2.6.23中如此)。你的FUSE文件系统在链接/反链接时维护它们,对aufs而言这等价于直接分支访问

        udba=reval

            Aufs仅仅检测曾经存在过的文件的存在性。如果曾经存在的文件被直接从分支上删除了,aufs废弃这个文件的缓存文件并重新检测它。这样数据将被更新。这个测试最低级别地保持了性能的同时确保了文件的存在性。这是默认选项而且aufs运行的依然迅速。

            这个规则会导致一些非预期的情况,但是我希望这是无害的。它们完全依赖于缓存。这里有一小部分例子。

            · 如果文件被缓存为否定或者不存在的,aufs不会测试它。而且用户直接在分支上创建了该文件后它依然被处理为否定的。如果这个文件没有被缓存,aufs将会正常检测并找到这个文件。

            · 如果文件被缓存为肯定或者存在的,用户直接在上层分支创建了了同名文件。Aufs检测缓存的文件inode依然存在会使用位于低层分支的旧的(被缓存)的文件。

            · 如果文件被缓存为肯定或者存在的,用户直接使用rename(2)改变了文件名。Aufs检测文件的inode依然存在。你有可能会同时看到旧文件和新文件。Todo:如果aufs也检查文件名,我们可以检测到这个情况。

        如果你的外部修正(UDBA)非常稀少而且你可以忽略虚拟aufs世界与真实分支文件系统之间临时性且细微的差异,那么可以试试这个选项。

        udba=inotify

            Aufs把它分支上所有的被访问目录都设为’inotify’并且接收目录及其子项的事件。这会消耗资源,包括cpu和内存。而且我认为性能也会受到影响,但是这是最为严格的测试级别。linuxinotify存在一些限制,可以参考Inotify限制。所以通常并不推荐它作为UDBA的默认选项,而是当你需要的时候通过remount手动设置为inotify

            当用户访问一个曾经被UDBA notified的文件,文件被缓存的数据将被抛弃aufs会重新检查它。所以这个数据会被更新。当在UDBAaufs操作之间有错误条件发生,aufs会返回一个错误,包括EIO。使用这个选项,需要在内核2.6.18及以后,而且需要打开CONFIG_INOTIFY CONFIG_AUFS_UDBA_INOTIFY

            直接rename/rmdir一个分支的目录可能会暴露出位于低层分支的同名文件。Aufs试着重新检查被重命名的目录以及被暴露出来的目录并对齐它们不同的inode数字。但是inode数字包括它们的子项可能存在问题。inode数字可能被悄悄地缓存过,因此aufs可能会产生一个警告。如果你反复 rename目录进而暴露/隐藏低层目录,aufs也会困惑于它们的inode数字。这取决于系统的缓存。

            当在aufs中创建了一个分支并且把另一个文件系统mount在上面,因为这个目录是一个mount点所以它按照预期不能被删除。但是位于可写分支的同名目录可以被删除,如果谁想要这么做的话。它将仅仅是一个空目录,以替代一个mount点。Aufs不能阻止这样的rmdir,但是可以对此产生一个警告。

            如果伪链接被直接从分支上创建硬链接或者被反链接,它在aufs中的的inode链接数将变得不正确。推荐使用auplink脚本更新所有伪链接。


Linux Inotify限制

       
很不幸,当前的inotify(内核2.6.1存在一些限制,aufs显然源自于它。我试着列举一些有害的情况。

   
IN_ATTRIB, updating atime

       
如果一个位于分支的文件/目录被直接访问,inodeatime(访问时间,参考stat(2))可能被更新或反之。一些情况下,inotify不会触发这个事件。所以aufsinodeatime可能仍然还是旧的。

    IN_ATTRIB, updating nlink

        如果一个位于分支的文件的链接数被直接使用link(2)而增加了,inotify发送IN_CREATE给它的父目录,但是发送IN_ATTRIB给这个文件。所以aufsinodenlink可能仍然还是旧的。

    IN_DELETE, removing file on NFS

        如果一个位于NFS 分支的文件被直接删除了,inotify可能会触发IN_DELETE事件或反之。这依赖于dentry的状态 (DCACHE_NFSFS_RENAMED标志)。这种情况下,位于aufs的文件好像仍然存在一样。Aufs以及其他用户可以看见这个文件。

    IN_IGNORED, deleted rename target

       
如果一个位于分支的文件/目录被直接使用rename(2)而反链接了,inotify触发IN_IGNORED意味着inode被删除了。实际上,某些情况下,inode仍然有效。例如,rename的目标被链接或者打开。这种情况下,被aufs设置的inotify监视会被VFS inotify删除。aufs将无法再接到任何事件。因此对于这个文件/目录aufs显示给你的可能是错误的数据。


写时拷贝,或者aufs内部向上拷贝和向下拷贝
       
        每一个实行写时拷贝的可堆叠文件系统都支持向上拷贝特性。这个特性就是内在地从低层分支拷贝一个文件/目录到上层目录。当有一个只读分支和一个上层可写分支,你向Z只读分支的文件中添加了一个字符串,aufs将会把这个文件连同它的目录结构一起从只读分支拷贝到可写分支。这意味着真正预期的 write(2)被执行之前还包含了许多逻辑的/内部的mkdir(2)creat(2)read(2)write(2)close(2)系统调。有时这会花费较长时间,特别是文件很大时。如果打开了CONFIG_AUFS_DEBUGaufs会打出一条写着正在拷贝一个大文件'的消息。

        当你改变xino文件路径或者压缩xino/xib文件的时候你可能看到这个消息。有时那些文件很大需要很长时间来处理。


多个可写分支中的选择策略

        当你打算写/修改什么东西的时候Aufs有一些策略允许你从众多的可写分支中选择一个。一共有两种策略,一个是新创建而另一个是内部向上拷贝。你可以通过mount选项’create=CREATE_POLICY’’cpup=COPYUP_POLICY’选择它们。当你只有一个可写分支时这些选项没什么意义。如果一定要说有的话,可能就是性能影响吧。

    策略中的例外

        在下面的每种情况中,即使策略声明新文件将会创建于/rw2的分支,但实际上文件依然被创建于/rw1

            · 如果在策略选定的分支之上有一个带有’wh’属性的只读分支并且它的父目录标记为opaque,或者在这个ro+wh分支目标(要创建的)文件是被 whiteouted的,这时策略将被忽略并且目标文件会被创建到离ro+wh分支最近的上层可写分支。
             
/aufs = /rw1 + /ro+wh/diropq + /rw2
              /aufs = /rw1 + /ro+wh/wh.tgt + /rw2

           
· 如果在策略选定的分支之上有一个可写分支而它的父目录被标记为opaque或者目标文件是在那个分支上是被whiteouted的,那么策略将会被忽略同时目标文件将会被创建到上层最高且带有diropqwhiteout的可写分支。whiteout的情况下,aufs照常删除它。

              /aufs = /rw1/diropq + /rw2
              /aufs = /rw1/wh.tgt + /rw2

            · 每个策略中link(2)rename(2)系统调用都是例外。它们会尽量尝试选用源文件所在的分支因为向上拷贝一个大文件将会花费很长时间。如果不行,也就是只有只读的源文件时,它们才会遵从向上拷贝策略。

            · 当文件存在的时候rename(2)存在一个例外。如果rename的目标存在,aufs比较源文件和目标文件所在分支间的索引并选择较高的一个。如果选中的分支是只读的,那么aufs将遵从向上拷贝策略。

   
创建策略

        create=tdp | top-down-parent

            选择其父目录存在的最高可写分支。如果父目录不存在于任何可写分支,那么执行内部向上拷贝。这个向上拷贝的策略总是’bottom-up’的。这是默认策略。

        create=rr | round-robin

           
循环选择可写分支。当你有2个可写分支而创建10个新文件时,每个分支将分别创建5个。系统调用mkdir(2)是个例外。当你创建10个目录,所有的都会创建在同一个分支。

       
create=mfs[:second] | most-free-space[:second]

           
选择空余空间最多的可写分支。为了保证性能,你可以指定持续时间(’second’)它使得aufs记住上次选中的可写分支索引号直到指定的秒超时。超时后第一次你在aufs中创建的东西时,aufs通过内部statfs调用检查所有可写分支的剩余空间总数因此被记住的分支索引号将被更新。默认值是30 秒。

       
create=mfsrr:low[:second]

           
首先选择空余空间最多的分支,然后使用循环选择方式。如果被选中分支的空余空间小于指定的字节数’low’,那么aufs使用循环选择方式重试。可以使用POSIX中定义的shell算术表达式。例如,$((10 * 1024 * 1024))表示10M。你也可以指定持续时间(’second’)就像’mfs’模式那样。

        create=pmfs[:second]

            选择存在父目录的可写分支,就像tdp模式。当多个可写分支都存在父目录的话,aufs选择空余空间最多的那个,就像mfs模式。

    向上拷贝策略

        
cpup=tdp | top-down-parent

           
等价于创建时的同名策略。这是默认策略。

       
cpup=bup | bottom-up-parent

           
选择父目录所在且距离向上拷贝源最近的上层可写分支。

       
cpup=bu | bottom-up

           
选择距离向上拷贝源最近的上层可写分支,不管父目录是否存在。

通过NFS导出aufs


        Aufs在内核2.6.18及以后支持NFS导出。因为aufs没有实际的块设备,你需要在导出时添加NFS’fsid’选项。关于这个选项的更多细节可以参考NFS的手册。
        在内核2.6.23以及更早,建议导出aufs之前先导出一次你的分支文件系统。通过一次导出,分支文件系统的内部名为 find_exported_dentry的指针被初始化。初始化以后,你可以不导出它们。另外,这个初始化每种文件系统都应该做。如果你的分支是同一种文件系统,你只需要把它们导出一次。如果你从没有导出过你的分支正在使用的文件系统,aufs将会使用默认值初始化内部指针,并且给出一个警告。虽然它可能工作地挺正常,我还是担心它将来会出问题。在内核2.6.24及以后,这种导出是非必需的。
        此外,还有一些限制或者要求。

           
· kernel的版本必需为2.6.18或者更高。

            · 你需要打开CONFIG_AUFS_EXPORT。

            · 分支文件系统必须支持NFS导出。例如,内核2.6.18(或更早)的tmpfs就不支持。

            · 不支持NFSv2。当你从NFS客户端mount导出的aufs,你需要一些如v3或者nfsvers=3的NFS选项,特别是当它为nfsroot的时候。

           
· 如果你的分支文件系统上NFS文件句柄的数目很大,aufs可能无法处理它。NFSv3中一个文件系统的最大文件句柄数为64字节。Aufs32位系统上使用使用24字节,64位系统增加12字节。剩余的分支文件系统的文件句柄区域。

            · 因为NFS文件句柄是基于inode数字的所以需要外部Inode数字位图,转换表和世代表(xino)。默认会打开mount选项’xino’。当你打开了CONFIG_AUFS_EXPORT时外部inode世代表和它的sysfs entry(/fs/aufs/si_*/xigen)就被创建出来即使你没有真的导出了aufs。外部世代表的体积只会增大,不会被压缩。你应该关注一下xino文件所处文件系统的剩余空间。默认情况下,它是第一个可写分支。

            · 分支文家系统必需是可访问的,也就是说不能被隐藏
这意味着你使用initramfs和switch_root(或者chroot(时需要执行’mount --move’。

Dentry和Inode缓存


        如果你想清除你的系统缓存,有个窍门。如果你的内存比较少,试试’find /large/dir -ls > /dev/null’。
它将会读取很多inodesdentries并缓存它们。旧的缓存将被丢弃。但是如果你有很大的内存并且你没有一个足够巨大的目录,那么这将没有效果。
       
如果你想从内部丢弃某个文件系统的缓存,试试’mount -o remount /your/mntpnt’。有的文件系统可能返回一个EINVAL错误或别的什么,但是VFS将会丢弃指定文家系统上没用的dentry/inode缓存。

与Unionfs版本1.x系列的兼容/不兼容


        如果你编译aufs使用了-DCONFIG_AUFS_COMPAT,dirs=选项和=nfsro分支权限标志即变为可用。它们分别用于解释 br:选项和=ro标志位。’debug’、’delete’、’imap’选项被默认忽略。
当你编译aufs时使用了 -DCONFIG_AUFS_COMPAT,这三个选项同样会被忽略,但是会给出警告信息。
        忽略’delete’选项,并且为了保证文件系统一致性,aufs会试着在单一系统调用中只向一个分支写入数据。这意味着无论源分支是否被指定为可写aufs都会执行向上拷贝。例如,你有两个可写分支以及一个巨大的位于低层可写分支的普通文件。当你对于aufs中这个文件执行rename(2)的时候,aufs可能将其向上拷贝至上层可写分支。如果这不是你所预期的状况的话,你应该直接在低层分支执行rename(2)
       
在sample目录下有一个简单的shell脚本’unionctl’,它与Unionfs版本1.x系列的unionctl(兼容,除了--query动作。这个脚本执行了带’remount’选项的mount(以及add/del/mod等aufs的mount选项。如果你熟悉Unionfs版本1.x系列并想使用unionctl(,你可以尝试直接用这个脚本代替mount -o remount等。Aufs不支持ioctl(2)接口。这个脚本高度依赖位于util-linux-2.12p包的mount(,而且你使用这个脚本需要mount /proc。如果你的mount(版本不同,你可以试着修改这个脚本。这很简单。unionctl脚本其实就是aufs remount界面的一个使用示例。
        Aufs默认使用外部inode数字位图和转换表。
        第一个分支默认分支权限是’rw’,其余的是’ro’
       
whiteout用于隐藏低层分支的文件,也用于阻止readdir进入低层分支。后一种情况称为’opaque directory’。任何whiteout都是一个空文件,这就是说whiteout仅仅是一个标记。在隐藏低层文件的情况下,whiteout的名字是’.wh.’。在阻止readdir的情况下,名字是’.wh..wh..opq’或者 ’.wh.__dir_opaque’。这个名字取决于你的编译配置CONFIG_AUFS_COMPAT。所有的whiteouts都被硬链接,包括 ’/.wh..wh.aufs’。
       
位于普通(基于磁盘)的文件系统的硬链接并不消耗新的inode资源。但是在linux tmpfs中,空余的inodes数量将会因为link(2)而减少。如果你遇到了ENOSPC推荐为你的tmpfs指定nr_inodes选项。使用这个选项后用’df -i’来检查。
       
当你rmdir或者rename-to一个拥有大量whiteouts的目录的时候,aufs把这个目录rename成类似 ’.wh.

.’的临时whiteouted名称。然后执行实际的删除操作。参考mount选项’dirwh’

与普通文件系统的不兼容


        stat(2)返回第一个存在此inode的分支上的inode信息,除了目录链接数。通常Aufs计算的目录链接数大于精确的数字,以便保持 UNIX文件系统语义,或者为了让find(1)闭嘴。目录的大小可能也存在错误,但这都是无害的。目录中的文件被创建或者删除时目录的时间戳不会改变,低层的分支会做相应变动。
        权限位测试有两种情况。一种是对目录,另一种是对非目录。对目录的情况下,aufs检查所有存在的目录的权限位。这意味着你需要拥有包括低层分支在内的正确的权限。对于非目录的测试简单得多。它只检测最上层的inode
       
statfs(2)返回第一个分支的信息如果指定了’nosum’(默认值)则不包括namelen。namelen由于whiteout前缀长度而减少。块大小可能不同于从stat(2)得到的st_blksize。
        请记住,seekdir(3)和telldir(3)并没有定义在在POSIX中。它们可能无法按照的你预期工作。试着rewinddir(3)或re-open目录。
        whiteout前缀(.wh.)在所有分支中都是被保留的。
用户应该私自处理带这种前缀的文件名。为了将来的whiteout,最大文件名长度被限定为:最大值 - 4。这可能违反了POSIX
       
如果你不喜欢/etc/mtab和/proc/mounts之间aufs entries的差异,你可以使用util-linux包中的mount(,试试./mount.aufs脚本。把这个脚本拷贝到/sbin/mount.aufs。这个简单的脚本能更新/etc/mtab。如果你不关心/etc/mtab,你可以忽略这个脚本。请记住这个脚本高度依赖util-linux-2.12p包中的mount(,而且你需要mount /proc
        因为aufs使用它自己的inodedentry,你的系统可能缓存大量的inodesdentries。它可能会是你联合上所有文件的两倍。它意味着在关机时unmountingremounting为只读会花费较长时间,因为VFS中的mount(2)会试图释放目标文件系统的所有缓存。
        当你打开一个目录,aufs可能内在地打开多个目录。它意味着可能会达到文件描述符的上限。当低层的目录无法被打开时,aufs会关闭所有打开的上层目录并返回一个错误。
       
位于分支之下本地文件系统的sub-mount将被忽略。例如,如果你已经mount另一个文件系统到/branch/another /mntpnt,’mntpnt’下面的文件将被aufs忽略。推荐在mounted好的aufs之下mount那些sub-mount。例如,
        # 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
       
有一些字符不允许在分支目录路径以及xino文件名中被使用。具体可以参考分支语法和Mount选项。
       
fcntl(2)通过F_SETLK、F_SETLKW或F_GETLK,flock(2)和lockf(3)所定义的文件锁,只作用于虚拟 aufs文件,并不作用于分支上的文件。它意味着你可以通过直接访问分支打破这个锁。TODO:检查’security’以便抓住锁,就像inotify 所做的。
        系统调用fsync(2)fdatasync(2)返回0意味着成功,即使给定的文件描述符被阻塞还未打开。我担心这种行为可能违反了某些标准。检查一下fsync(2)ext2上的行为,aufs决定返回成功。
        如果你想使用磁盘配额,你应该把它设定到你的可写分支上因为aufs并没有自己的块设备。
        如果你的aufs是你的根目录,而你的系统告诉你有些文件系统没有被干净地unmounted,可以在你关机的时候试试这些流程。
       
# mount -no remount,ro /
        # for i in $writable_branches
        # do mount -no remount,ro $i
        # done
        如果你的xino文件位于一个硬盘,你可能需要在remounting根目录的时候指定’noxino’选项或者’xino=/your/tmpfs/xino’。
        即使源和目标位于同一个aufs在rename(2)目录时也可能会返回EXDEV。
当源目录存在于多个分支而低层目录含有子目录时,aufs不得不向上拷贝它的所有子目录。这可能会递归向上拷贝。目前aufs并不支持在内核空间一次性执行如此巨大的向上拷贝操作,取而代之的就是警告并返回 EXDEV。通常,mv(1)检测这个错误并尝试使用mkdir(2)rename(2) 或者递归的copy/unlink。所以结果是无害的。如果你执行rename(2)的这个应用不支持EXDEV,它就不能工作在aufs上。这个规范也适用于当源目录位于低层的只读分支且它还有子目录的情况。
        一个突发事件如停电等在aufs正在运行过程中发生的话,灾难过后对于分支文件系统会完成一次常规fsck,你需要对于可写分支进行额外的 fsck。它必须检查whiteout是否停留在异常的状态,例如真实文件名和它的whiteout位于同一个父目录。如果存在一个这样的 whiteoutaufs将无法正确处理文件。从检查aufs的观点出发检查一致性,你可以使用一个简单的名为/sbin/auchkshell脚本。它的目的是一个适用于aufsfsck工具,它会检查错误的whiteout,遗留的伪链接以及遗留的aufs临时文件。如果它们被找到,工具会报告给你并询问是否删除它们。如果系统曾经挂过推荐你在mount aufs前对每一个可写分支执行/sbin/auchk

示例


        remount的时候mount选项被从左至右依次处理。示例展现了选项如何被处理。(假定/sbin/mount.aufs已经被安装)
        # 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)
       
当你把aufs作为根文件系统使用时,推荐考虑排除掉一些目录。例如,/tmp/var/log大多数情况下不需要堆叠。它们不经常需要向上拷贝或者whiteout。还有位于aufs之上的swapfile(一个常规文件,而非块设备)是不被支持的。为了排除掉特定的目录,可以尝试bind mounting
        有一个网络启动无盘机器的很好的示例。可以从sample/看到详细内容。

诊断


        当你添加一个分支到你的联合时,aufs可能会给你关于分支权限以及安全性的警告,包括那些分支的顶层目录的权限位、所有者以及所属组。例如,当你的顶层可写分支有一个全局可写顶层目录的话,一个恶意用户可以在这个可写分支直接创建任意文件,这就像向上拷贝并手动修改一样。我担心这可能会是一个安全问题。
        当你mount或者remount你的aufs而没有使用-o ro公共mount选项并且没有可写分支时,aufs可能警告你第一个分支应该是可写的。
        当你设定除inotify之外其它的udba并直接改变了你分支上的某些东西后,aufs可能会检测到缓存中的某些不匹配项。如果这是个致命的不匹配项,aufs会返回EIO并且给出警告信息说’try udba=inotify’
        如果aufs发生了一个错误,aufs会打印出带着'errno'的内核信息。信息的优先级(log级别)ERRWARNING这取决于信息本身。你可以通过perror(3)strerror(3)或者别的什么将’errno’转换为错误信息。例如,’I/O Error, write failed (-2’’errno’28含义为ENOSPC或者’No space left on device’

版权
        Copyright ? 2005-2009 Junjiro Okajima

作者
        Junjiro Okajima

原文
       

翻译
        水大
 

阅读(2554) | 评论(0) | 转发(0) |
0

上一篇:Ubuntu 启动过程

下一篇:Zenity 中文手册

给主人留下些什么吧!~~