狠狠撸

狠狠撸Share a Scribd company logo
叠合式文件系统 — — overlayfs

                     核心系统部 - 内核组

        Robin Dong <hao.bigrat@gmail.com>
讲师介绍

? 核心系统部 - 内核组 - 董昊(花名:三百)

? 2006 年加入阿里巴巴 - 雅虎中国 从事 c/c++ 服务端程序开发

? 2008 年转入淘宝,继续从事 c/c++ 服务端程序及公用库开发
  ( tlock/tdbm/ 夸父)
? 2011 年转入核心系统部内核组,目前从事文件系统相关的内核
  开发和调优



? 内核组 wiki : http://kernel.taobao.org/
1. linux 文件系统的一些基础知识
2. 怎么发现 overlayfs (源起)

3. Linux 上 vfs 的原理

4. overlayfs 的原理

课程大纲页
基础知识
?
    Linux 的 page cache
       –    read/write
       –    mmap
?
    常见疑问:好多内存都被 cache 占了,我想手工释放它
       –    答:不需要, linux 系统在需要内存时,自己会释放
            cache
?
    常见疑问:我想让 cache 一直保留不被收回,怎么做?
       –    答: mmap 后 mlock
基础知识
   ?
       文件系统的“快照”( snapshot )
         –    多个 inode 指向相同的物理磁盘块
         –    需要引用计数以记录一个磁盘块被几个 inode 使
              用了




Image from http://sannasanalyst.blogspot.com/2010/06/netapp-fractional-
  reserve.html
1. linux 文件系统的一些基础知识


2. 怎么发现 overlayfs (源起)
3. Linux 上 vfs 的原理

4. overlayfs 的原理

OVERLAYFS 提纲
源起

?
    需求:在一个 linux 系统上,跑多个不同应用,这
    些应用由不同的运维人员来操作,为了避免互相干
    扰,希望运维只能看见自己的文件,而看不见别的
    应用的文件信息
?
    常见解决方案: linux 系统上装多个虚拟机
?
    缺陷:多个应用公用的一些动态链接库(比如
    libc.so )和配置文件(比如 hosts.conf )就复制了
    多份。
源起
?
    我们的最初方案:把 linux 系统装到 ext4 上,
    然后做 4 个 snapshot (“快照“),这 4 个
    snapshot 分别 mount 到 4 个目录, 4 个运维人
    员 chroot 到这 4 个目录里(我们最初以为一
    个文件和它的快照是共享 cache 的)
?
    疑问:直接把系统常用的动态链接库做 4 个
    软链接出来,给 4 个运维用不就行了?
源起

?
    ext4 snapshot 方案的纰漏:一个文件和它的
    snapshot 各自有自己的 page cache ,并非共享!
?
    我们还考虑过 link-ref (多个文件共享一样的磁盘
    块),但问题一样:不同的 inode 无法共享一套
    page cache
?
    mount –bind 的问题: clone 出来的新文件系统是
    只读的,运维人员无法单独改动系统文件
源起

?
    最终方案: overlayfs
?
    overlayfs 能将两个目录“合并”,比如两个目录:
       –   dir1/ 目录里有
       –           ./fire
       –           ./water
       –   dir2/ 目录里有

       –           ./apple
       –           ./banana
源起

mount -t overlayfs overlayfs -olowerdir=/dir1,upperdir=/dir2 /test1/

(我们不修改 dir1 目录里的文件)以后
       –    test1/ 目录里将会有
       –    ./fire
       –    ./water
       –    ./apple

       –    ./banana

其中 /test1/fire 和 /dir1/fire 其实是“同一个文件”,用的是一
  套 page cache
生产系统的做法

?
    1. 做一个 base 目录,比如 /base ,里面存放了所有
    系统文件,类似 /etc 、 /bin/ 、 /lib/ 等
?
    2. 准备 4 个目录来存储文件,比
    如 /store1,/store2,/store3,/store4
?
    3. 准备 4 个空目录(仅仅作为名字)比如
    /system1 、 /system2 、 /system3 、 /system4
生产系统的做法
?
    4. mount
        –      mount -t overlayfs overlayfs -olowerdir=/base,upperdir=/store1
               /system1/
        –      mount -t overlayfs overlayfs -olowerdir=/base,upperdir=/store2
               /system2/
        –      mount -t overlayfs overlayfs -olowerdir=/base,upperdir=/store3
               /system3/
        –      mount -t overlayfs overlayfs -olowerdir=/base,upperdir=/store4
               /system4/

运维人员执行:

cd /system2/; chroot .
Overlayfs 概览

?
    由 SUSE 的 Miklos Szeredi 开发,实现非常简洁
?
    设计用途
      –   各个 linux 发行版的 livecd (以前的方案是 union
          mount )
      –   很多嵌入式设备的“恢复原厂设置”功能
      –   “virtualized systems built on a common base
          filesystem”
1. linux 文件系统的一些基础知识

2. 怎么发现 overlayfs (源起)


3. Linux 上 vfs 的原理
4. overlayfs 的原理

OVERLAYFS 提纲
vfs 原理

?
    Virtual File
    System 是一种
    软件机制,将
    不同类型的文
    件系统统一为
    一套接口


                   http://space.itpub.net/?uid-26110315-action-viewspace-itemid-719438
vfs 原理

?
    VFS 在内存中要为(一部分)真实的物理文件建立一套内存视图




     此图来自《 Understanding Linux Kernel ( 3rd
      version )》,被无数的网站引用,但它确实很能说明问题
vfs 原理

?
    普遍的疑惑: inode 和 dentry 有什么区别,为
    什么会有这两个内核对象?
?
    “ 文件“这个词包含了两层意思:
     –   这个”文件“所在的位置,即与兄弟姐妹父母亲
         的关系
     –   这个”文件“自身的属性,即大小、访问权限等
         信息
vfs 原理

?
    inode 主要描述了文件的自身属性
      –   创建时间、被修改时间
      –   操作权限
      –   该怎么操作( inode_operations )
      –   拿到 inode 对象并不能直接告诉你文件在哪个目录下
?
    dentry 主要描述了文件(相对于其它文件和目录)的位置
      –   父目录是谁
      –   如果自己是目录,那下面有哪些文件
      –   该怎么处理位置关系( dentry_operations )
vfs 原理
struct inode {

    ……

    unsigned long         i_ino;

    atomic_t            i_count;

    unsigned int         i_nlink;

    uid_t             i_uid;

    gid_t             i_gid;

   ……

    struct timespec        i_atime;

    struct timespec        i_mtime;

    struct timespec        i_ctime;
vfs 原理
struct inode_operations {

      int (*create) (struct inode *,struct dentry *,int, struct nameidata *);

      struct dentry * (*lookup) (struct inode *,struct dentry *, struct nameidata *);

      int (*link) (struct dentry *,struct inode *,struct dentry *);

      int (*unlink) (struct inode *,struct dentry *);

      int (*symlink) (struct inode *,struct dentry *,const char *);

     ……

      void (*truncate) (struct inode *);

     ......

};
vfs 原理
struct dentry {

    ……

     struct dentry *d_parent;        /* parent directory */

    struct qstr d_name;

    struct list_head d_lru;       /* LRU list */

    union {

         struct list_head d_child;      /* child of parent list */

         struct rcu_head d_rcu;

    } d_u;

    struct list_head d_subdirs;      /* our children */

    struct list_head d_alias;     /* inode alias list */
vfs 原理
struct dentry_operations {

     int (*d_revalidate)(struct dentry *, struct nameidata *);

     int (*d_hash) (struct dentry *, struct qstr *);

     int (*d_compare) (struct dentry *, struct qstr *, struct qstr *);

     int (*d_delete)(struct dentry *);

     void (*d_release)(struct dentry *);

     void (*d_iput)(struct dentry *, struct inode *);

     char *(*d_dname)(struct dentry *, char *, int);

         ……

};
vfs 原理

?
    问:文件的删除、创建等都是 inode_operations
    接口提供,那文件的 read/write/mmap 呢?
?
    答: struct inode 里有一个“ struct
    file_operations i_fop”, 这个 file_operations 就是负
    责文件自身操作的接口
vfs 原理
struct file_operations {

    struct module *owner;

    loff_t (*llseek) (struct file *, loff_t, int);

    ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);

    ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);

    ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);

    ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);

    int (*readdir) (struct file *, void *, filldir_t);

    unsigned int (*poll) (struct file *, struct poll_table_struct *);

    long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);

    long (*compat_ioctl) (struct file *, unsigned int, unsigned long);

    int (*mmap) (struct file *, struct vm_area_struct *);

            ……};
vfs 原理
?
    问:当我们读一个文件时(先 open ,后 read ),
    发生了什么?(为了避免牵扯太多,我假设文件对
    象已经都在内存中,也就是说近期已经被访问过了
    )
?
    先查找文件,沿着路径在每一级目录里找对应
    name 的 dentry
?
    找到 dentry 后再调用 __dentry_open
vfs 原理总结

?
    vfs 提供了高度的灵活性:对文件属性的操作
    、对文件位置的操作、对文件数据的操作都是
    可以由开发者自己实现的
1. linux 文件系统的一些基础知识

2. 怎么发现 overlayfs (源起)

3. Linux 上 vfs 的原理


4. overlayfs 的原理
OVERLAYFS 提纲
Overlayfs 的原理

?
    VFS 的高度灵活性已经给我们很多启发
    了
?
    overlayfs 的根本:把对 overlayfs 文件系
    统里一个文件的操作,转为对 lowerdir
    里对应文件的操作
Overlayfs 的原理
static struct file *ovl_open(struct dentry *dentry, struct file *file, const struct cred
    *cred)

{

            ……

    type = ovl_path_real(dentry, &realpath);

    /* overlayfs 在 dentry 的 d_fsdata 成员里放了文件对应的 lowerdir 和


                           upperdir 的信息,此处便可以找到该文件对应的
    lowerdir 的文件了 */

     …...

    return vfs_open(&realpath, file, cred);
Overlayfs 的原理
static int ovl_readdir(struct file *file, void *buf, filldir_t filler)

{

     …...

     if (!od->is_cached) {

            struct ovl_readdir_data rdd = { .list = &od->cache };

            res = ovl_dir_read_merged(&upperpath, &lowerpath, &rdd);

                  /* 把上下两层目录的内容都读出来,合并,放入 rdd 这个数
    据结构 */

                …...

            }
Overlayfs 的原理
 while (od->cursor.next != &od->cache) {
             /* rdd 数据结构里的 list 成员,实际是指向 od-
>cache 的,
                所以移动 od->cursor 就是在沿着 rdd->list 找到
所有 dentry */
      p = list_entry(od->cursor.next, struct ovl_cache_entry,
l_node);
      off = file->f_pos;
      if (!p->is_whiteout) {
            over = filler(buf, p->name, p->len, off, p->ino,
                ……
      }
    }
Overlayfs 的原理

?
    问:如果上下两层目录里有相同名
    字的文件,怎么处理?


?
    问:下层目录是 readonly 的,那如
    果它对应的 overlayfs 里的文件能被
    修改吗?
Overlayfs 原理
?
    overlayfs 的特性:将上下两层目录合并为一个文件系统,“
    下层”目录是只读的,所有修改都是对”上层“的修改
      –   新创建的文件实际是创建在“上层”目录的
      –   删除文件时:
           ?   如果文件来自“下层”目录,则隐藏它
           ?   如果文件来自“上层”目录,则直接删除即可
      –   写一个文件时:
           ?   如果文件来自“下层”,则拷贝其到上层目录,
               然后写这个”上层“的新文件
           ?   如果文件来自”上层“,直接写即可
Overlayfs 的原理
static struct file *ovl_open(struct dentry *dentry, struct file *file, const struct cred *cred)

{

      ……

    if (ovl_open_need_copy_up(file->f_flags, type, realpath.dentry)) {

         if (file->f_flags & O_TRUNC)

                err = ovl_copy_up_truncate(dentry, 0);

         else

                err = ovl_copy_up(dentry);

      ……

      return vfs_open(&realpath, file, cred);
向 Overlayfs 写入
Overlayfs 的原理总结

?
    有 VFS 的高度灵活性,才有 overlayfs
    的简洁实现
     –   上下合并
     –   同名遮盖
     –   写时拷贝
Overlayfs 现状
?
    2011 年 6 月, Miklos 曾询问社区
    overlayfs 是否可以并入 upstream
?
    层叠型文件系统会进 kernel ,但,是
    overlayfs 还是 uni-mount 进内核,抑或都
    进,目前还不明朗
?
    目前 overlayfs 在开发上更活跃
推荐学习资料
?
    《深入理解 linux 内核》(第三版)
?
    解析 Linux 中的 VFS 文件系统机制
    http://www.ibm.com/developerworks/cn/linux/l-vfs/
?
    Overlayfs 源代码

http://git.kernel.org/?
    p=linux/kernel/git/mszeredi/vfs.git;a=tree;h=refs/heads/overlayfs.v13;h
    b=refs/heads/overlayfs.v13
Q&A
Thanks!


          40

More Related Content

Overlayfs and VFS

  • 1. 叠合式文件系统 — — overlayfs 核心系统部 - 内核组 Robin Dong <hao.bigrat@gmail.com>
  • 2. 讲师介绍 ? 核心系统部 - 内核组 - 董昊(花名:三百) ? 2006 年加入阿里巴巴 - 雅虎中国 从事 c/c++ 服务端程序开发 ? 2008 年转入淘宝,继续从事 c/c++ 服务端程序及公用库开发 ( tlock/tdbm/ 夸父) ? 2011 年转入核心系统部内核组,目前从事文件系统相关的内核 开发和调优 ? 内核组 wiki : http://kernel.taobao.org/
  • 3. 1. linux 文件系统的一些基础知识 2. 怎么发现 overlayfs (源起) 3. Linux 上 vfs 的原理 4. overlayfs 的原理 课程大纲页
  • 4. 基础知识 ? Linux 的 page cache – read/write – mmap ? 常见疑问:好多内存都被 cache 占了,我想手工释放它 – 答:不需要, linux 系统在需要内存时,自己会释放 cache ? 常见疑问:我想让 cache 一直保留不被收回,怎么做? – 答: mmap 后 mlock
  • 5. 基础知识 ? 文件系统的“快照”( snapshot ) – 多个 inode 指向相同的物理磁盘块 – 需要引用计数以记录一个磁盘块被几个 inode 使 用了 Image from http://sannasanalyst.blogspot.com/2010/06/netapp-fractional- reserve.html
  • 6. 1. linux 文件系统的一些基础知识 2. 怎么发现 overlayfs (源起) 3. Linux 上 vfs 的原理 4. overlayfs 的原理 OVERLAYFS 提纲
  • 7. 源起 ? 需求:在一个 linux 系统上,跑多个不同应用,这 些应用由不同的运维人员来操作,为了避免互相干 扰,希望运维只能看见自己的文件,而看不见别的 应用的文件信息 ? 常见解决方案: linux 系统上装多个虚拟机 ? 缺陷:多个应用公用的一些动态链接库(比如 libc.so )和配置文件(比如 hosts.conf )就复制了 多份。
  • 8. 源起 ? 我们的最初方案:把 linux 系统装到 ext4 上, 然后做 4 个 snapshot (“快照“),这 4 个 snapshot 分别 mount 到 4 个目录, 4 个运维人 员 chroot 到这 4 个目录里(我们最初以为一 个文件和它的快照是共享 cache 的) ? 疑问:直接把系统常用的动态链接库做 4 个 软链接出来,给 4 个运维用不就行了?
  • 9. 源起 ? ext4 snapshot 方案的纰漏:一个文件和它的 snapshot 各自有自己的 page cache ,并非共享! ? 我们还考虑过 link-ref (多个文件共享一样的磁盘 块),但问题一样:不同的 inode 无法共享一套 page cache ? mount –bind 的问题: clone 出来的新文件系统是 只读的,运维人员无法单独改动系统文件
  • 10. 源起 ? 最终方案: overlayfs ? overlayfs 能将两个目录“合并”,比如两个目录: – dir1/ 目录里有 – ./fire – ./water – dir2/ 目录里有 – ./apple – ./banana
  • 11. 源起 mount -t overlayfs overlayfs -olowerdir=/dir1,upperdir=/dir2 /test1/ (我们不修改 dir1 目录里的文件)以后 – test1/ 目录里将会有 – ./fire – ./water – ./apple – ./banana 其中 /test1/fire 和 /dir1/fire 其实是“同一个文件”,用的是一 套 page cache
  • 12. 生产系统的做法 ? 1. 做一个 base 目录,比如 /base ,里面存放了所有 系统文件,类似 /etc 、 /bin/ 、 /lib/ 等 ? 2. 准备 4 个目录来存储文件,比 如 /store1,/store2,/store3,/store4 ? 3. 准备 4 个空目录(仅仅作为名字)比如 /system1 、 /system2 、 /system3 、 /system4
  • 13. 生产系统的做法 ? 4. mount – mount -t overlayfs overlayfs -olowerdir=/base,upperdir=/store1 /system1/ – mount -t overlayfs overlayfs -olowerdir=/base,upperdir=/store2 /system2/ – mount -t overlayfs overlayfs -olowerdir=/base,upperdir=/store3 /system3/ – mount -t overlayfs overlayfs -olowerdir=/base,upperdir=/store4 /system4/ 运维人员执行: cd /system2/; chroot .
  • 14. Overlayfs 概览 ? 由 SUSE 的 Miklos Szeredi 开发,实现非常简洁 ? 设计用途 – 各个 linux 发行版的 livecd (以前的方案是 union mount ) – 很多嵌入式设备的“恢复原厂设置”功能 – “virtualized systems built on a common base filesystem”
  • 15. 1. linux 文件系统的一些基础知识 2. 怎么发现 overlayfs (源起) 3. Linux 上 vfs 的原理 4. overlayfs 的原理 OVERLAYFS 提纲
  • 16. vfs 原理 ? Virtual File System 是一种 软件机制,将 不同类型的文 件系统统一为 一套接口 http://space.itpub.net/?uid-26110315-action-viewspace-itemid-719438
  • 17. vfs 原理 ? VFS 在内存中要为(一部分)真实的物理文件建立一套内存视图 此图来自《 Understanding Linux Kernel ( 3rd version )》,被无数的网站引用,但它确实很能说明问题
  • 18. vfs 原理 ? 普遍的疑惑: inode 和 dentry 有什么区别,为 什么会有这两个内核对象? ? “ 文件“这个词包含了两层意思: – 这个”文件“所在的位置,即与兄弟姐妹父母亲 的关系 – 这个”文件“自身的属性,即大小、访问权限等 信息
  • 19. vfs 原理 ? inode 主要描述了文件的自身属性 – 创建时间、被修改时间 – 操作权限 – 该怎么操作( inode_operations ) – 拿到 inode 对象并不能直接告诉你文件在哪个目录下 ? dentry 主要描述了文件(相对于其它文件和目录)的位置 – 父目录是谁 – 如果自己是目录,那下面有哪些文件 – 该怎么处理位置关系( dentry_operations )
  • 20. vfs 原理 struct inode { …… unsigned long i_ino; atomic_t i_count; unsigned int i_nlink; uid_t i_uid; gid_t i_gid; …… struct timespec i_atime; struct timespec i_mtime; struct timespec i_ctime;
  • 21. vfs 原理 struct inode_operations { int (*create) (struct inode *,struct dentry *,int, struct nameidata *); struct dentry * (*lookup) (struct inode *,struct dentry *, struct nameidata *); int (*link) (struct dentry *,struct inode *,struct dentry *); int (*unlink) (struct inode *,struct dentry *); int (*symlink) (struct inode *,struct dentry *,const char *); …… void (*truncate) (struct inode *); ...... };
  • 22. vfs 原理 struct dentry { …… struct dentry *d_parent; /* parent directory */ struct qstr d_name; struct list_head d_lru; /* LRU list */ union { struct list_head d_child; /* child of parent list */ struct rcu_head d_rcu; } d_u; struct list_head d_subdirs; /* our children */ struct list_head d_alias; /* inode alias list */
  • 23. vfs 原理 struct dentry_operations { int (*d_revalidate)(struct dentry *, struct nameidata *); int (*d_hash) (struct dentry *, struct qstr *); int (*d_compare) (struct dentry *, struct qstr *, struct qstr *); int (*d_delete)(struct dentry *); void (*d_release)(struct dentry *); void (*d_iput)(struct dentry *, struct inode *); char *(*d_dname)(struct dentry *, char *, int); …… };
  • 24. vfs 原理 ? 问:文件的删除、创建等都是 inode_operations 接口提供,那文件的 read/write/mmap 呢? ? 答: struct inode 里有一个“ struct file_operations i_fop”, 这个 file_operations 就是负 责文件自身操作的接口
  • 25. vfs 原理 struct file_operations { struct module *owner; loff_t (*llseek) (struct file *, loff_t, int); ssize_t (*read) (struct file *, char __user *, size_t, loff_t *); ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *); ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t); ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t); int (*readdir) (struct file *, void *, filldir_t); unsigned int (*poll) (struct file *, struct poll_table_struct *); long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); long (*compat_ioctl) (struct file *, unsigned int, unsigned long); int (*mmap) (struct file *, struct vm_area_struct *); ……};
  • 26. vfs 原理 ? 问:当我们读一个文件时(先 open ,后 read ), 发生了什么?(为了避免牵扯太多,我假设文件对 象已经都在内存中,也就是说近期已经被访问过了 ) ? 先查找文件,沿着路径在每一级目录里找对应 name 的 dentry ? 找到 dentry 后再调用 __dentry_open
  • 27. vfs 原理总结 ? vfs 提供了高度的灵活性:对文件属性的操作 、对文件位置的操作、对文件数据的操作都是 可以由开发者自己实现的
  • 28. 1. linux 文件系统的一些基础知识 2. 怎么发现 overlayfs (源起) 3. Linux 上 vfs 的原理 4. overlayfs 的原理 OVERLAYFS 提纲
  • 29. Overlayfs 的原理 ? VFS 的高度灵活性已经给我们很多启发 了 ? overlayfs 的根本:把对 overlayfs 文件系 统里一个文件的操作,转为对 lowerdir 里对应文件的操作
  • 30. Overlayfs 的原理 static struct file *ovl_open(struct dentry *dentry, struct file *file, const struct cred *cred) { …… type = ovl_path_real(dentry, &realpath); /* overlayfs 在 dentry 的 d_fsdata 成员里放了文件对应的 lowerdir 和 upperdir 的信息,此处便可以找到该文件对应的 lowerdir 的文件了 */ …... return vfs_open(&realpath, file, cred);
  • 31. Overlayfs 的原理 static int ovl_readdir(struct file *file, void *buf, filldir_t filler) { …... if (!od->is_cached) { struct ovl_readdir_data rdd = { .list = &od->cache }; res = ovl_dir_read_merged(&upperpath, &lowerpath, &rdd); /* 把上下两层目录的内容都读出来,合并,放入 rdd 这个数 据结构 */ …... }
  • 32. Overlayfs 的原理 while (od->cursor.next != &od->cache) { /* rdd 数据结构里的 list 成员,实际是指向 od- >cache 的, 所以移动 od->cursor 就是在沿着 rdd->list 找到 所有 dentry */ p = list_entry(od->cursor.next, struct ovl_cache_entry, l_node); off = file->f_pos; if (!p->is_whiteout) { over = filler(buf, p->name, p->len, off, p->ino, …… } }
  • 33. Overlayfs 的原理 ? 问:如果上下两层目录里有相同名 字的文件,怎么处理? ? 问:下层目录是 readonly 的,那如 果它对应的 overlayfs 里的文件能被 修改吗?
  • 34. Overlayfs 原理 ? overlayfs 的特性:将上下两层目录合并为一个文件系统,“ 下层”目录是只读的,所有修改都是对”上层“的修改 – 新创建的文件实际是创建在“上层”目录的 – 删除文件时: ? 如果文件来自“下层”目录,则隐藏它 ? 如果文件来自“上层”目录,则直接删除即可 – 写一个文件时: ? 如果文件来自“下层”,则拷贝其到上层目录, 然后写这个”上层“的新文件 ? 如果文件来自”上层“,直接写即可
  • 35. Overlayfs 的原理 static struct file *ovl_open(struct dentry *dentry, struct file *file, const struct cred *cred) { …… if (ovl_open_need_copy_up(file->f_flags, type, realpath.dentry)) { if (file->f_flags & O_TRUNC) err = ovl_copy_up_truncate(dentry, 0); else err = ovl_copy_up(dentry); …… return vfs_open(&realpath, file, cred);
  • 37. Overlayfs 的原理总结 ? 有 VFS 的高度灵活性,才有 overlayfs 的简洁实现 – 上下合并 – 同名遮盖 – 写时拷贝
  • 38. Overlayfs 现状 ? 2011 年 6 月, Miklos 曾询问社区 overlayfs 是否可以并入 upstream ? 层叠型文件系统会进 kernel ,但,是 overlayfs 还是 uni-mount 进内核,抑或都 进,目前还不明朗 ? 目前 overlayfs 在开发上更活跃
  • 39. 推荐学习资料 ? 《深入理解 linux 内核》(第三版) ? 解析 Linux 中的 VFS 文件系统机制 http://www.ibm.com/developerworks/cn/linux/l-vfs/ ? Overlayfs 源代码 http://git.kernel.org/? p=linux/kernel/git/mszeredi/vfs.git;a=tree;h=refs/heads/overlayfs.v13;h b=refs/heads/overlayfs.v13

Editor's Notes

  • #8: 例如:原先一个系统在运行时系统文件占了 500M 的 cache ,那么现在装了 4 台虚拟机,就一共要占 2G 的 cache 。 平台的层次越深,这种浪费就越大, c/c++ 程序只是用一些系统的 .so , java 程序依靠 jvm ,需要的公用库就更多了。
  • #9: 第一,动态链接库以及各种系统文件很多,不可能一一做软链接;第二,也是关键的一点,如果其中一个运维人员错误操作 —— 例如覆盖写了某个系统文件,那么其他的运维将会受影响,因为软链接实际指向的是同一个实际文件。
  • #10: 现有 linux 的支持快照的文件系统( ext2/ext3/ext4 、 btrfs 、 ocfs2 ),它们的快照在 mount 以后,就是个“新的”文件系统、“新的” inode ,新的 inode 就有自己“新的” page cache
  • #14: 此后,运维人员就拥有自己“独立”的可写的系统了。系统文件的 page cache 是共享的。
  • #19: inode 和 dentry 都是内存里的对象,其中, inode 对应一个在磁盘里的真实文件(仅限磁盘文件系统),而 dentry 没有对应的磁盘对象
  • #21: 主要描述文件自有属性 对于磁盘文件系统,其中的 i_atime 、 i_mtime 、 i_blocks 等都是从磁盘里读出来的
  • #22: 提供文件属性的修改接口:如何创建、如何添加链接、如何截断、如何删除等 对于磁盘文件系统,这些接口的具体实现都变为对磁盘内容的操作
  • #23: 主要描述文件的位置关系 父目录是谁、有哪些子文件 (如果自己是目录)
  • #24: 提供了文件位置关系处理的接口: 怎么计算 hash 、怎样比较文件名
  • #27: 调用 d_hash 根据 name 等计算 hash 值( d_hash 是可以文件系统开发者自己实现的接口) 根据 hash 值在 hash 表里找到对应的桶( linux 有一张 hash 表“ dentry_hashtable” ,整个系统的 dentry 都放在里面) 这个桶后面有一串 dentry (都是相同 hash 值的),再用 d_compare 去一个个对比是不是要找的那个 name dentry 里有指针指向对应的 inode f-&gt;f_op = fops_get(inode-&gt;i_fop); 把 inode 里的 i_fop 赋值给 struct file 对象 从此,对这个文件的 read/write/mmap 都由 file_operations 接口负责了
  • #28: 不同的文件系统通过不同的 inode_operations 和 file_operations 实现(当然,还有别的 operations )来完成自己的特性。即使是 windows 的 fat 、 ntfs 和 plan9 的文件系统都已经移植到了 linux
  • #30: 既然对一个文件的操作是可以任意实现的,那就完全可以把对文件 A 的 read 直接转为对另一个文件 B 的 read
  • #31: vfs_open() /* 把这个 lowerdir 对应的文件的 path 传给 vfs_open ,这样,被真正 open 的就是 lowerdir 对应的“下层文件”了,之后的 read/mmap 都是调用的该文件的 file_operation */
  • #33: filler 是在填写用户态传下来的 buffer ,两层目录的文件名都要填写进去 /* 于是乎,两层目录下的文件名都读出来放到一起了 * /
  • #34: 1 答:上面的“盖住”下面的,显示的是上层目录的文件 2 答:一旦被修改, overlayfs 实际是把它拷贝到上层目录,然后修改之
  • #36: /* 如果需要,是要拷贝下层的文件的 * /
  • #38: (如果是一个很大的文件,则写时拷贝是比较费时的,但毕竟只需要一次拷贝,下次就不需要了 )
  • #39: Andrew Morton 表示怀疑,觉得这种需求最好由 fuse 来实现:如果因为 overlayfs 简单就把它合进内核的话,那么“ Not merging it would be even smaller and simpler” Linus :“ So Andrew, I think that arguing that something _can_ be done with fuse, and thus _should_ be done with fuse is just ridiculous.” (参考 http://lwn.net/Articles/447650/ )
  • #40: 获取方法 git clone git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs.git 现在的 branch 是 overlayfs.v13