Chinaunix首页 | 论坛 | 博客
  • 博客访问: 9182065
  • 博文数量: 1728
  • 博客积分: 12961
  • 博客等级: 上将
  • 技术积分: 19870
  • 用 户 组: 普通用户
  • 注册时间: 2009-01-09 11:25
个人简介

偷得浮生半桶水(半日闲), 好记性不如抄下来(烂笔头). 信息爆炸的时代, 学习是一项持续的工作.

文章分类

全部博文(1728)

文章存档

2024年(4)

2023年(26)

2022年(112)

2021年(217)

2020年(157)

2019年(192)

2018年(81)

2017年(78)

2016年(70)

2015年(52)

2014年(40)

2013年(51)

2012年(85)

2011年(45)

2010年(231)

2009年(287)

分类: 其他平台

2021-08-24 15:31:09

从linux 4.x 开始, 在很多产品级rootfs 采用了支持 overlayfs. 其实很早就在容器上用了.
首先说下缺点
尽管Overlayfs看起来是这么的优秀,但是当前(202)它还并不是那么的完美,依然存在一些缺点和使用限制(还没有完全支持POSIX标准)
0. Mount Overlayfs之后就不允许在对原lower dir和upper dir进行操作, 对文件系统的任何操作都只能在merge dir中进行
1. Overlayfs 写复制会让多用户操作过程中存在不一致的情况, 尤其在大文件进行操作时.

2. Rename directory(POSIX标准支持问题)
3. Hard link break(POSIX标准支持问题)

该问题源自copy-up机制,当lower dir目录中某个文件拥有多个硬链接时,若用户在merge layer对其中一个写入了一些数据,那将触发copy-up,由此该文件将拷贝到upper dir,那么和原始文件的hard link也就断开了,变成了一个单独的文件,用户在merge layer通过stat和ls命令能够直接看到这个变化。在Linux-4.13起内核引入了“index feature”来修复这个问题,同样引入了一个内核选项:CONFIG_OVERLAY_FS_INDEX,用户想要修复该问题可以打开这个选项,不过该选项不具有向前兼容性,请谨慎使用。

4. Unconstant st_dev&st_ino(POSIX标准支持问题)

该问题同样源自copy-up机制,当原来在lower dir中的文件触发了copy-up以后,那用户在merge layer见到的将是来自upper dir的新文件,那也就意味着它俩的inode是不同的,虽然inode中很多的attr和xattr是可以copy的,但是st_dev和st_ino这两个字段却具有唯一性,是不可以复制的,所以用户可以通过ls和stat命令看到的该字段将发生变化。在Linux-4.12和Linux-4.13分别进行了部分的修复,目前在lower dir和upper dir都在同一个文件系统挂载点的场景下,问题已经修复,但lower dir和upper dir若来自不同的文件系统,问题依然存在。

5. File descriptor change(POSIX标准支持问题)

该问题也同样源自copy-up机制,用户在文件发生copy-up之前以只读方式open文件(这操作不会触发copy-up)得到的文件描述符fd1和copy-up之后open文件得到的文件描述符fd2指向不同的文件,用户通过fd2写入的新数据,将无法从fd1中获取到,只能重新open一个新的fd。该问题目前社区主线内核依然存在,暂未修复。

以上这6点列出了目前Overlayfs的主要问题和限制,将在后文中陆续展开。社区为了让Overlayfs能够更加向支持Posix标准的文件系统靠拢,做出了很多的努力,后续将进一步修复上面提到且未修复的问题,还会增加对NFS Export、freeze snapshots、overlayfs snapshots等的支持,进一步完善overlayfs。

如果Overlayfs的某一个目录是单纯来自lower layer或是lower layer和upper layer合并的,那默认情况下,用户无法对该目录执行rename系统调用,否则会返回-EXDEV错误。不过你会发现通过mv命令重命名该目录依然可以成功,那是因为mv命令的实现对rename系统调用的-EXDEV错误进行规避(这当然是有缺点的,先暂不展开)。在Linux-4.10起内核引入了“redirect dir”特性来修复这个问题,为此引入了一个内核选项:CONFIG_OVERLAY_FS_REDIRECT_DIR,用户想要支持该特性可以在内核中开启这个选项,否则就应避免对这两类目录使用rename系统调用。

-------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------

Overlayfs是一种堆叠文件系统,它依赖并建立在其它的文件系统之上(例如ext4fs和xfs等等),并不直接参与磁盘空间结构的划分,仅仅将原来底层文件系统中不同的目录进行“合并”,然后向用户呈现。因此对于用户来说,它所见到的overlay文件系统根目录下的内容就来自挂载时所指定的不同目录的“合集”

其中lower dirA / lower dirB目录和upper dir目录为来自底层文件系统的不同目录,用户可以自行指定,内部包含了用户想要合并的文件和目录,merge dir目录为挂载点。当文件系统挂载后,在merge目录下将会同时看到来自各lower和upper目录下的内容,并且用户也无法(无需)感知这些文件分别哪些来自lower dir,哪些来自upper dir,用户看见的只是一个普通的文件系统根目录而已(lower dir可以有多个也可以只有一个)。

虽然overlayfs将不同的各层目录进行合并,但是upper dir和各lower dir这几个不同的目录并不完全等价,存在层次关系。首先当upper dir和lower dir两个目录存在同名文件时,lower dir的文件将会被隐藏,用户只能看见来自upper dir的文件,然后各个lower dir也存在相同的层次关系,较上层屏蔽叫下层的同名文件。除此之外,如果存在同名的目录,那就继续合并(lower dir和upper dir合并到挂载点目录其实就是合并的一个典型例子)。

各层目录中的upper dir是可读写的目录,当用户通过merge dir向其中一个来自upper dir的文件写入数据时,那数据将直接写入upper dir下原来的文件中,删除文件也是同理;而各lower dir则是只读的,在overlayfs挂载后无论如何操作merge目录中对应来自lower dir的文件或目录,lower dir中的内容均不会发生任何的改变(理论设计如此,但实际在一些极端场景存在偏差,后面我会详细介绍)。既然lower dir是只读的,那当用户想要往来自lower层的文件添加或修改内容时,overlayfs首先会拷贝一份lower dir中的文件副本到upper dir中,后续的写入和修改操作将会在upper dir下的copy-up的副本文件中进行,lower dir原文件被隐藏。

以上就是overlayfs最基本的特性,简单的总结为以下3点:(1)上下层同名目录合并;(2)上下层同名文件覆盖;(3)lower dir - 文件写时拷贝到upper dir。这三点对用户都是不感知的。



应用场景

在同一个设备上,用户A和用户B有一些共同使用的共享文件(例如运行程序所依赖的动态链接库等),一般是只读的;同时也有自己的私有文件(例如系统配置文件等),往往是需要能够写入修改的;最后即使用户A修改了被共享的文件也不会影响到用户B。

对于以上的需求场景,我们并不希望每个用户都有一份完全一样的文件副本,因为这样不仅带来空间的浪费也会影响性能,因此overlayfs是一个较为完美的解决方案。我们将这些共享的文件和目录所在的目录设定为lower dir (1~n),将用户私有的文件和目录所在的目录设定为upper dir,然后挂载到用户指定的挂载点,这样即能够保证前面列出的3点需求,同时也能够保证用户A和B独有的目录树结构。最后最为关键的是用户A和用户B在各自挂载目录下看见的共享文件其实是同一个文件,这样磁盘空间的节省自是不必说了,还有就是共享同一份cache而减少内存的使用和提高访问性能,因为只要cache不被回收,只需某个用户首次访问时创建cache,后续其他所有用户都可以通过访问cache来提高IO性能。
-------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------
挂载文件系统 
mount -t overlay overlay -o lowerdir=lower1:lower2:lower3,upperdir=upper,workdir=work merged
其中"lower1:lower2:lower3"表示不同的lower层目录,不同的目录使用":"分隔层次关系依次为lower1 > lower2 > lower3(注:多lower层功能支持在Linux-4.0合入,Linux-3.18版本只能指定一个lower dir);然后upper和work目录分别表示upper层目录和文件系统挂载后用于存放临时和间接文件的工作基目录(work base dir),最后的merged目录就是最终的挂载点目录。若一切顺利,在执行以上命令后,overlayfs就成功挂载到merged目录下了。

挂载选项支持(即"-o"参数):
1)lowerdir=xxx:指定用户需要挂载的lower层目录(支持多lower,最大支持500层);
2)upperdir=xxx:指定用户需要挂载的upper层目录;
3)workdir=xxx:指定文件系统的工作基础目录,挂载后内容会被清空,且在使用过程中其内容用户不可见;
4)default_permissions:功能未使用;
5)redirect_dir=on/off:开启或关闭redirect directory特性,开启后可支持merged目录和纯lower层目录的rename/renameat系统调用;
6)index=on/off:开启或关闭index特性,开启后可避免hardlink copyup broken问题。


其中lowerdir、upperdir和workdir为基本的挂载选项,redirect_dir和index涉及overlayfs为功能支持选项,除非内核编译时默认启动,否则默认情况下这两个选项不启用

挂载文件系统的特性与限制条件:
1、用户可以不指定upperdir和workdir,但同时必须保证lowerdir >= 2层,此时的文件系统为只读挂载(这也是只读挂载overlayfs的唯一方法);如果用户指定upperdir,则必须保证upperdir所在的文件系统是可读写的,同时还需指定workdir,并且workdir不能和upperdir是父子目录关系。
2、常见的文件系统中,upperdir所在的文件系统不能是nfs、cifs、gfs2、vfat、ocfs2、fuse、isofs、jfs和另一个overlayfs等文件系统,而lowerdir所在的文件系统可以是nfs、cifs这样的远程文件系统,也可以是另一个overlayfs。因为upperdir是可以写入的,所以需要避免一些特性上的不兼容(例如vfat是大小写不敏感的文件系统),而lowerdir是只读文件系统,相对要求会低一些。
3、用户应该尽量避免多个overlayfs使用同一个upperdir或workdir,尽管默认情况下是可以挂载成功的,但是内核还是会输出告警日志来提示用户。
4、用户指定的lowerdir最多可以支持500层。虽然如此,但是由于mount的挂载选项最多支持1个page的输入(默认大小为4KB),所以如果指定的lowerdir数量较多且长度较长,会有溢出而导致挂载失败的风险(目前内核的-o挂载选项不支持超过1个内存页,即4KB大小)。
5、指定的upperdir和workdir所在的基础文件系统的readdir接口需要支持dtype返回参数,否则将会导致本应该隐藏的whiteout文件(后文介绍)暴露,当然目前ext4和xfs等主流的文件系统都是支持的,如果不支持那内核会给出警告提示但不会直接拒绝挂载。
6、指定的upperdir和workdir所在的基础文件系统需要支持xattr扩展属性,否则在功能方面会受到限制,例如后面的opaque目录将无法生成,并且redirect dir特性和index特性也无法使用。
7、如果upperdir和各lowerdir是来自同一个基础文件系统,那在文件触发copyup前后,用户在merge层通过ls命令或stat命令看到的Device和inode值保持不变,否则会发生改变。

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

上一篇:linux tar 包加密

下一篇:HMOS - S0: 立项

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