当前位置: 首页 > Linux

Linux文件系统aufs

时间:2023-04-06 19:30:33 Linux

aufs的全称是advancedmulti-layeredunifiedfilesystem。它的主要功能是将多个文件夹的内容合并在一起,提供一个统一的视图。主要用于各种Linux发行版的livecd。而docker就是用来整理镜像的。据说由于aufs代码的可维护性很差(代码可读性和注释都不是很好),所以一直没有合并到linux内核的主线中,但是有些发行版在内核中维护了这个文件系统,比如在ubuntu16.04的内核代码中,有这个文件系统。本文所有示例均在ubuntu-server-x86_6416.04下执行。检查系统是否支持aufs。在使用aufs之前,可以使用如下命令确认当前系统是否支持aufs。如果没有,请根据对应release版本的文档自行安装。#如果下面的命令没有输出,说明内核不支持aufs#由于aufs已经编译进了ubuntu16.04的内核,支持dev@ubuntu:~$grepaufs/proc/filesystemsnodevaufs#这里nodev表示该文件系统不需要在设备上构建。注意:有些Linux发行版可能会把aufs编译成一个模块,所以虽然内核不支持,但是下面的命令其实是可以正常运行的。挂载aufs并选择相应参数(参考帮助文档),调用mount命令即可,示例如下#mount-taufs-obr=./Branch-0:./Branch-1:./Branch-2none./MountPoint-taufs:指定挂载类型为aufs-obr=./Branch-0:./Branch-1:./Branch-2:表示合并Branch-0,Branch-三个文件夹1、和当前目录下的Branch-2一起none:aufs不需要设备,只依赖于-obr指定的文件夹,所以这里填none。/MountPoint:表示将最终的联合结果挂载到当前的MountPoint目录下,然后我们就可以在该目录下读写文件假设Branch-0中有文件001.txt和003.txt,文件001.txt,003Branch-1中的.txt和004.txt,Branch-2中的文件002.txt和003.txt。挂载完成后结果如下图/*001.txt(b0)表示Branch-0的001.txt文件,其他依此类推*/+--------------+------------+------------+------------+MountPoint|001.txt(b0)|002.txt(b2)|003.txt(b0)|004.txt(b1)|+------------+---------------+------------+------------+↑↑↑↑||||+----------------+------------+------------+--------------+分支-0|001.txt||003.txt||+------------+------------+---------------+------------+分支-1|001.txt||003.txt|004.txt|+------------+------------+------------+------------+分支-2||002.txt|003.txt||+------------+------------+------------+------------+合并后会看到MountPoint下有四个文件,分别是Branch-0下的001.txt和003.txt,Branch-1下的04.txt,Branch-2下的002.txtbranch是aufs中的一个概念。其实一个branch就是一个目录,所以上面的Branch-0、1、2就是三个目录。树枝有索引,索引越小,树枝越靠下。以上,如果多个分支中有相同的文件,只有索引最小的分支下的文件会被访问到MountPoint,也就是最后三个目录合并挂载的位置,这个目录下的文件会被通过aufs访问的文件系统,换句话说,如果直接访问Branch-0、1、2这三个目录,aufs是不会知道的。注意:并不是文件系统中的所有目录都可以作为aufs的分支。目前aufs不支持一些:btrfsaufseCryptfs读取这些文件时,它访问的是最顶层文件,但是如果你想写这些文件怎么办?或者在挂载点下新建一个文件?只读挂载请看下面的例子。挂载时可以指定每个分支的读写权限。如果不指定,第一个目录是可写的,其他目录是只读的。在实际使用的时候,最好明确指定每个分支的读写属性,让大家一目了然。dev@ubuntu:~$mkdir/tmp/aufs&&cd/tmp/aufsdev@ubuntu:/tmp/aufs$mkdirdir0dir1rootdev@ubuntu:/tmp/aufs$echodir0>dir0/001.txtdev@ubuntu:/tmp/aufs$echodir0>dir0/002.txtdev@ubuntu:/tmp/aufs$echodir1>dir1/002.txtdev@ubuntu:/tmp/aufs$echodir1>dir1/003.txt#最后使用tree命令查看最终目录结构root#通过指定ro参数dev@ubuntu:/tmp/aufs$将两个分支设置为只读sudomount-taufs-obr=./dir0=ro:./dir1=ronone。/root#最终根目录会看到三个文件dev@ubuntu:/tmp/aufs$lsroot/001.txt002.txt003.txt002.txt的内容比dir1的内容小dev@ubuntu:/tmp/aufs$catroot/002.txtdir0#因为只是Readdev@ubuntu:/tmp/aufs$touchroot/001.txttouch:cannottouch'root/001.txt':Read-onlyfilesystemdev@ubuntu:/tmp/aufs$touchroot/003.txttouch:cannottouch'root/003.txt':只读文件系统#3.txt,#因为跳过了根目录,所以不受aufsdev@ubuntu:/tmp/aufs$touchdir0/001.txtdev@ubuntu:/tmp/aufs$touchdir1/003.txt#Westill可以在如下目录下新建一个文件dev@ubuntu:/tmp/aufs$touchdir1/004.txt#新建的文件可以及时反映到挂载点dev@ubuntu:/tmp/aufs$ls。/root/001.txt002.txt003.txt004.txt#删除这个文件以免影响后面的演示dev@ubuntu:/tmp/aufs$rm./dir1/004.txt从上面的演示中,我们可以看到,我们可以跳过挂载点,直接读写底层目录,这样就不受aufs的控制了,但是挂载点下还是可以看到我们修改的内容(004.txt创建在dir1中),因为aufs在访问文件的时候,默认的方式是如果顶层目录没有这个文件,就会一层层往下找,所以如果下层有变化,aufs会自动找那个参数给控制这种行为的是“udba”。有兴趣的可以参考帮助文档。由于访问一个文件需要一层层往下查找,如果合并的目录(层级)过多,会影响性能。读写挂载如果组合文件夹有写权限,所有的修改都会写入可写文件夹。如果有多个可写文件夹,写入哪个文件夹取决于相应的策略,比如round-robin,最大剩余空间等,具体可以参考帮助文档中的“create”参数,这里不再介绍.dev@ubuntu:/tmp/aufs$sudoumount./root#dir0有读写权限,dir1有只读权限dev@ubuntu:/tmp/aufs$sudomount-taufs-obr=./dir0=rw:./dir1=ronone./rootdev@ubuntu:/tmp/aufs$echo"root->write">>./root/001.txtdev@ubuntu:/tmp/aufs$echo"root->write">>./root/002.txtdev@ubuntu:/tmp/aufs$echo"root->write">>./root/003.txtdev@ubuntu:/tmp/aufs$echo"root->write">>./root/005.txt#与开始前相比,dir0目录下多了003.txt和005.txt,其他不变dev@ubuntu:/tmp/aufs$ls./root/001。txt002.txt003.txt005.txtdev@ubuntu:/tmp/aufs$ls./dir0/001.txt002.txt003.txt005.txtdev@ubuntu:/tmp/aufs$ls./dir1/002。txt003.txt#再看一下内容,dir1中的内容不变dev@ubuntu:/tmp/aufs$cat./dir1/002.txtdir1dev@ubuntu:/tmp/aufs$cat./dir1/003.txtdir1#dir0文件内容变了dev@ubuntu:/tmp/aufs$cat./dir0/001.txtdir0root->writtenev@ubuntu:/tmp/aufs$cat./dir0/002.txtdir0root->writtenev@ubuntu:/tmp/aufs$cat./dir0/003.txtdir1root->writedev@ubuntu:/tmp/aufs$cat./dir0/005.txtroot->write创建新文件时,会将新文件写入具有rw权限的目录。如果有多个具有rw权限的目录,则取决于挂载时配置的创建策略。修改具有rw权限的文件时修改目录下具有rw权限的文件时,直接修改该文件即可。当修改一个只有ro权限的目录下的文件时,aufs会先把文件复制到一个有rw权限的目录下,然后再进行修改。这就是所谓的COW(copyonwrite),复制的速度取决于底层分支所在的文件系统。从上面可以看出,对于大文件,COW的性能还是很低的,而且也会占用很大的空间,但是因为只有第一个修改的时候会复制一次,所以还是在许多情况下可以接受。删除文件删除文件时,如果该文件只存在于rw目录下,则直接删除rw目录下的文件。如果ro目录下存在该文件,那么aufs会在rw目录文件中创建一个.wh开头的文件,表示该文件已经被删除#Deleteallfilesthroughaufsdev@ubuntu:/tmp/aufs$rm./root/001.txt./root/002.txt./root/003.txt./root/005.txt#dir0下的所有文件都删除了,dir1目录下的文件没有动dev@ubuntu:/tmp/aufs$tree.├──dir0├──dir1│├──002.txt│└──003.txt└──root#通过-a参数查看dir0目录下的内容#你可以看到aufs为002.txt和003.txt创建了两个.wh开头的特殊文件,#用来表示这两个文件已经被删除了#其他.wh开头的文件这里是aufsdev@使用的一些属性文件Ubuntu:/tmp/aufs$ls./dir0/-a...wh.002.txt.wh.003.txt.wh..wh.aufs.wh..wh.orph.wh..wh.plnk结论这里只介绍aufs的基本功能,其他高级配置项暂不涉及,如dynamic增加和删除分支等。使用aufs时,建议参考livecd和docker的用法,就是将所有目录以只读方式组合一个支持读写的空目录,这样所有的修改都会存储在指定的空目录中directory,without则直接删除那个目录即可,使用过程中不要绕过aufs直接操作底层分支,也不要动态增删分支。如果使用场景太过复杂,因为aufs里面有很多细节,很可能会因为对aufs不了解而踩坑。参考aufsaufs手册LinuxAuFSExamples