Chinaunix首页 | 论坛 | 博客
  • 博客访问: 173547
  • 博文数量: 47
  • 博客积分: 992
  • 博客等级: 准尉
  • 技术积分: 565
  • 用 户 组: 普通用户
  • 注册时间: 2010-07-08 21:57
文章分类

全部博文(47)

文章存档

2019年(1)

2018年(1)

2017年(1)

2014年(6)

2013年(1)

2012年(2)

2011年(35)

我的朋友

分类: LINUX

2011-11-23 17:02:31


Email:    zcatt@163.com
Blog    http://zcatt.blog.chinaunix.net
 
声明
仅限学习交流,禁止商业用途。转载需注明出处。

版本记录
Date        Ver        Note
2011-11-22    0.1        Draft.  zcatt, Beijing

1. bind and namespace
=================================
引[2].
在 2000 年,Al Viro 为 Linux 引入了绑定挂载和文件系统名称空间:

    a.绑定挂载(bind mount)允许从任何其他位置访问任何文件或目录。
    b.文件系统名称空间(filesystem namespace)是与不同进程相关联的完全独立的文件系统树。
在执行 clone(2) 时,进程请求它当前的文件系统树的拷贝(更多信息见 参考资料);在此之后,新进程就拥有与原进程的文件系统树相同的拷贝。在建立拷贝之后,在这两个树中的任何挂载操作都不会影响另一个拷贝。

尽管每个进程使用单独的文件系统名称空间在理论上非常有意义,但是在实践中,完全隔离它们会造成较大的限制性。进程克隆了系统的文件系统名称空间之后,已经运行的系统守护进程无法为这个用户自动挂载 CD-ROM,因为在原文件系统名称空间中执行的挂载无法影响用户的拷贝。

2006 年引入的挂载传播(mount propagation)解决了这个问题,挂载传播定义了挂载对象之间的关系。系统用这些关系决定任何挂载对象中的挂载事件如何传播到其他挂载对象:

    a.如果两个挂载对象具有共享关系,那么一个挂载对象中的挂载事件会传播到另一个挂载对象,反之亦然。
    b.如果两个挂载对象形成从属(slave)关系,那么一个挂载对象中的挂载事件会传播到另一个挂载对象,但是反过来不行;在这种关系中,从属对象是事件的接收者。

传播事件的挂载对象称为共享挂载(shared mount);接收挂载事件的挂载对象称为从属挂载(slave mount)。既不传播也不接收挂载事件的挂载对象称为私有挂载(private mount)。另一种特殊的挂载对象称为不可绑定的挂载(unbindable mount),它们与私有挂载相似,但是不允许执行绑定挂载。不可绑定的挂载对于快速增长挂载对象尤其有意义

2. propagation_next
=================================
fs/pnode.c:
/*
 * get the next mount in the propagation tree.
 * @m: the mount seen last
 * @origin: the original mount from where the tree walk initiated
 */
static struct vfsmount *propagation_next(struct vfsmount *m,
                     struct vfsmount *origin)
{
    /* are there any slaves of this mount? */
    if (!IS_MNT_NEW(m) && !list_empty(&m->mnt_slave_list))
        return first_slave(m);

    while (1) {
        struct vfsmount *next;
        struct vfsmount *master = m->mnt_master;

        if (master == origin->mnt_master) {
            next = next_peer(m);
            return ((next == origin) ? NULL : next);
        } else if (m->mnt_slave.next != &master->mnt_slave_list)
            return next_slave(m);

        /* back at master */
        m = master;
    }
}
    
propagation_next将会深度优先的遍历根是origin的propagation tree(传播树). 所谓传播数是指主从mnt_slave_list链表和共享mnt_share链表构建的mnt数.

一般的使用方法,

    struct vfsmount *m;
    for (m = propagation_next(dest_mnt, dest_mnt); m;
            m = propagation_next(m, dest_mnt)) {
        ... ...
    }


例如下面的树,

n0*
    n1
        n3
        n4
    n2

n10*
    n11
    n12

其中n0和n10是share mnt.
那么, propagation_next()遍历的顺序是: n1,n3,n4,n2,(因为是share mnt)n10,n11,n12


REF
=================================
1. linuxKernelSrc/fs/pnode.c

2. 应用挂载名称空间, http://www.ibm.com/developerworks/cn/linux/l-mount-namespaces.html

阅读(931) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~