Mnt_namespace分析

1      简介

1.1      背景

Linux容器场景下实现对进程和其相关的资源的隔离,这些资源同样也包括了进程的文件系统环境。这就要求容器中有一个独立的文件环境,而容器中的进程共享这个文件系统环境,即容器自己的根文件系统环境。

所以内核引入了mnt命名空间的概念,来实现文件系统环境的隔离。

1.2      概述

内核中通过mnt_namespace实现对根文件系统的环境的隔离,不同的mnt_namespace对应不同的根文件系统,组织不同的文件系统挂载树,形成不同的文件系统目录结构。

创建一个新的进程时,会拷贝父进程的命名空间,如果指定一个clone_flag(CLONE_NEWNS)则会创建一个新的命名空间。

对命名空间的修改,属于同一个mnt命名空间的进程可见,其他命名空间的进程不可见。

2      实现机制

2.1      几个相关的技术点

2.1.1      文件系统挂载树

Linux中使用树来组织文件系统,整个文件系统构成一棵树。整个全局系统中只有这样一棵文件树(在没有容器的情况下),这棵树描述文件系统的拓扑结构。

既然是树,所以根就是其赖以生存的基础,这棵树以“/”为根。由于linux的树形文件系统是完全抽象的,因此它不和任何介质进行绑定,仅存在于内核当中,内核只要起来,这个虚拟的树就存在了,只是此时只有树根,然而linux此时却可以挂载任意类型的文件系统到这个树根,这样就可以实现很方便的定制,linux可以在initrd中挂载任意文件系统到树根,这是因为内核和文件系统是分离的概念,内核启动并不依赖任何文件系统。

这棵挂载树的建立包括建立根节点“/”和挂载rootfs文件系统到根目录的过程。

这一部分的操作是在kernel的初始化中完成的,构造根目录的代码是在init_mount_tree()函数(fs/namespace.c)中。

init_mount_tree函数会调用get_fs_type获取文件系统类型,即“rootfs”,这看起来似乎有点奇怪,因为根据前面的说法,似乎是应该先有挂载目录,然后再在其上挂载相应的文件系统,然而此时 VFS 似乎并没有建立其根目录。没关系,这是因为这里调用的是vfs_kern_mount(),这个函数内部自然会创建我们最关心也是最关键的根目录(在 Linux中,目录对应的数据结构是structdentry)。

vfs_kern_mount()主要做的工作是:

1、 调用alloc_vfsmnt()函数在内存里申请了一块该类型的内存空间(struct mount*mnt),并初始化其部分成员变量;

2、 接着会通过rootfs注册的挂载函数rootfs_mount完成rootfs的挂载;

3、 通过rootfs文件系统中挂载的的fill_super函数指针调用ramfs_fill_super()函数;

4、 ramfs_fill_super()函数调用ramfs_get_inode()在内存中分配了一个inode结构(struct *inode)inode,并初始化其部分成员变量,其中比较重要的有i_op、i_fop 和i_sb;

5、 ramfs_fill_super()函数在分配和初始化了inode结构之后,会调用d_make_root()函数来为VFS的目录树建立起关键的根目录“/”的(struct *dentry)dentry,并将 dentry中的d_sb指针指向sb,d_inode指针指向inode;

6、 完成以上的创建后࿰

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值