Linux ns 3. Mnt Namespace 详解
1. 文件系统层次化
对 Linux 系统来说一切皆文件,Linux 使用树形的层次化结构来管理所有的文件对象。
完整的Linux文件系统,是由多种设备、多种文件系统组成的一个混合的树形结构。我们首先从一个单独的块设备来分析其树形结构的构造。
1.1 块设备的层次化(superblock/inode/dentry)
对一个块设备来说要想构造文件系统树形结构,最重要的两个全局因素是:块设备(block_device)和文件系统(file_system_type)。内核使用了一个数据结构 struct super_block
把这两者结合起来,用来标识一个块设备。
确定了 super_block 以后,就可以使用文件系统提供的方法来解析块设备的内容,形成一个块设备内部的树形结构,也就是我们熟悉的文件夹、文件的层次结构。
系统使用 struct inode
结构来标识块设备内部的一个文件夹或者文件,struct inode
结构中最重要的成员是 ->i_ino
这个记录了 inode 在块设备中的偏移。
系统为了辅助 struct inode
的使用还设计了一个 struct dentry
结构,通常情况下一个 struct dentry
对应一个 struct inode
,也有少数情况下多个 struct dentry
对应一个 struct inode
(如硬链接)。struct dentry
中 cache 了更多的文件信息,类如文件名、层次结构,成员 ->d_parent
指向同一块设备内的父节点 struct dentry
,成员 ->d_subdirs
链接了所有的子节点 struct dentry
。
1.2 多设备的层次化(mount/vfsmount)
上一节描述了单个块设备构建树形文件系统的方式,如果是多个设备怎么样组成一颗更复杂的树呢?
Linux使用父子树的形式来构造,父设备树中的一个文件夹 struct dentry
可以充当子设备树的挂载点 mountpoint
。
- mount/vfsmount
为了组成复杂的父子树,系统定义了一个 struct mount
结构来负责对一个设备内子树的引用。
- mount tree
可以看到通过一个 struct mount
结构负责引用一颗子设备树,把这颗子设备树挂载到父设备树的其中一个 dentry
节点上。
如果 dentry
成为了挂载点 mountpoint
,会给其标识成 DCACHE_MOUNTED
。我们在查找路径的时候同样会判断 dentry
的 DCACHE_MOUNTED
标志,一旦置位就变成了 mountpoint
,挂载点文件夹下原有的内容就不能访问了,转而访问子设备树根节点下的内容。
struct mount
结构之间也构成了树形结构。
我们通常使用 mount -t fstpye devname pathname
命令来进行挂载子设备的操作。Linux 拥有非常灵活的挂载规则:
规则1、一个设备可以被挂载多次:
可以看到同一个子设备树,同时被两个 struct mount
结构所引用,被挂载到父设备树的两处不同的 dentry
处。
特别说明:虽然子设备树被挂载两次并且通过两处路径都能访问,但子设备的
dentry
和inode
只保持一份。
规则2、一个挂载点可以挂载多个设备:
还可以对父设备树的同一个文件夹 dentry
进行多次挂载,最后路径查找时生效的是最后一次挂载的子设备树。
- path
因为linux提供的灵活的挂载规则,所以我们如果要标识一个路径 struct path
的话需要两个元素:vfsmount
和 dentry
。
可以看到两个路径 struct path
最后引用到了同一 inode
,但是路径 path
是不一样的,因为 path
指向的 vfsmount
是不一样的。
- chroot
Linux 还支持每个进程拥有不同的根目录,使用 chroot()
系统调用可以把当前进程的根目录设置为整棵文件系统树中的任何 path
。
1.3 多名空间的层次化(mnt_namespace)
之前的系统中只有一棵mount
树,为了支持mnt_namespace
,系统把mount
树叶扩展成了多棵。每个mnt_namespace
拥有一棵独立的mount
树:
2. 关键代码
2.1 mount()
mount() 系统调用是理解文件系统层次化的核心,它主要包含3个关键步骤:
1、解析 mount() 系统调用中的参数挂载点路径 pathname
,返回对应的 struct path
结构:
SYSCALL_DEFINE5(mount) → do_mount() → user_path() → user_path_at_empty() → filename_lookup() → path_lookupat() → link_path_walk() → walk_component() → follow_managed()
2、解析 mount() 系统调用中的参数文件系统类型 -t type
和设备路径 devname
,建立起子设备的树形结构(如果之前已经创建过引用即可),建立起新的 struct mount
结构对其引用:
SYSCALL_DEFINE5(mount) → do_mount() → do_new_mount() → vfs_kern_mount() → mount_fs() → type->mount()
3、将新建立的 struct mount
结构挂载到查找到的 struct path
结构上:
SYSCALL_DEFINE5(mount) → do_mount() → do_new_mount() → do_add_mount() → graft_tree() → attach_recursive_mnt() → commit_tree()
2.2 chroot()
更改当前进程的根目录:
SYSCALL_DEFINE1(chroot, const char __user *, filename)
{struct path path;int error;unsigned int lookup_flags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
retry:/* (1) 解析指定的路径,返回对应的`struct path`结构 */error = user_path_at(AT_FDCWD, filename, lookup_flags, &path);if (error)goto out;error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_CHDIR);if (error)goto dput_and_out;error = -EPERM;if (!ns_capable(current_user_ns(), CAP_SYS_CHROOT))goto dput_and_out;error = security_path_chroot(&path);if (error)goto dput_and_out;/* (2) 把`struct path`结构设置为当前进程的根目录 */set_fs_root(current->fs, &path);error = 0;
dput_and_out:path_put(&path);if (retry_estale(error, lookup_flags)) {lookup_flags |= LOOKUP_REVAL;goto retry;}
out:return error;
}↓void set_fs_root(struct fs_struct *fs, const struct path *path)
{struct path old_root;path_get(path);spin_lock(&fs->lock);write_seqcount_begin(&fs->seq);old_root = fs->root;/* (2.1) 替换新的根目录 */fs->root = *path;write_seqcount_end(&fs->seq);spin_unlock(&fs->lock);if (old_root.dentry)path_put(&old_root);
}
2.3 copy_mnt_ns()
在进程创建或者 unshare()/setns() 系统调用时,如果设置了 CLONE_NEWNS
标志会调用 copy_mnt_ns() 创建一个新的 mnt namespace。其中的核心是创建一颗新的 struct mount
树,首先把旧的 struct mount
树复制过来:
SYSCALL_DEFINE1(unshare) → unshare_nsproxy_namespaces() → create_new_namespaces() → copy_mnt_ns() → copy_tree() → clone_mnt()
随后如果有新的 mount()
动作,两棵树的内容就会不同。
参考文档:
1.Linux Namespace
2.Linux文件系统
3.在CentOS7上使用LXC管理容器
4.docker基础:从chroot理解namespace的隔离
5.Docker基础: Linux内核命名空间之(1)mnt namespace
6.Docker基础:文件系统之AUFS
7.docker image是什么,存储在什么位置
8.Docker镜像存储-overlayfs
9.linux文件系统之mount流程分析
10.dentry和inode的关系
Linux ns 3. Mnt Namespace 详解相关推荐
- Linux ns 5. IPC Namespace 详解
文章目录 1. 简介 2. 源码分析 2.1 copy_ipcs() 2.2 ipcget() 2.3 ipc_check_perms() 2.4 相关系统调用 参考文档: 1. 简介 进程间通讯的机 ...
- linux服务器怎么查看cpu配置信息,linux服务器cpu信息查看详解
在linux系统中,提供了/proc目录下文件,显示系统的软硬件信息.如果想了解系统中CPU的提供商和相关配置信息,则可以查/proc/cpuinfo.但是此文件输出项较多,不易理解.例如我们想获取, ...
- Linux文件系统的目录结构详解(转)
Linux文件系统的目录结构详解(转) 原文链接https://www.cnblogs.com/cyjaysun/p/4462325.html 一.前 言 文章对Linux下所有目录一一说明,对比较重 ...
- LINUX经常使用的命令详解
LINUX经常使用的命令详解 源地址:http://blog.itpub.net/29065182/viewspace-1189162/ 1.man 对你熟悉或不熟悉的命令提供帮助解释 eg:man ...
- Linux初始化内存盘黑屏,详解linux内存磁盘初始化技术.doc
详解linux内存磁盘初始化技术 详解linux内存磁盘初始化技术 /5502266.html 关键词: HYPERLINK "/tag/initrd" \n _blankinit ...
- Ubuntu (Linux) 系统 find 命令详解
Ubuntu (Linux) 系统 find 命令详解 在Ubuntu (Linux)系统的终端上,虽然没有像 windows 上那样简介易用的图形界面 搜索工具,但只要你使用足够熟练, 有一个强大命 ...
- linux内核管道pipe实现详解
linux内核管道pipe实现详解 (文件系统暂时不是很了解,文件系统部分暂时不做解释,此文仅解释关键流程,系统调用部分请参考前面已经发布的文章,这里不做展开) 1.管道系统调用(SyS_pipe) ...
- linux find 命令通配符,linux find命令查找文件详解
首页 > Linux教程 > 常用命令 > find 查找文件 linux find命令查找文件详解 linux中find命令用来在指定目录下查找文件,如果使用该命令时,不设置任何参 ...
- 【linux】Valgrind工具集详解(八):Memcheck命令行参数详解
[linux]Valgrind工具集详解(五):命令行详解中不够全,在此专门针对Memcheck工具中的命令行参数做一次详细的解释. Memcheck命令行选项 –leak-check=<no| ...
最新文章
- Hadoop数据收集与入库系统Flume与Sqoop
- Scala学习笔记-5
- BCH实用场景增加,Bitwage推出BCH工资单
- 点云的无序性_PU-Net:解决3D点云数据的上采样问题
- anki怎么设置学习计划_打篮球怎么训练弹跳力?NBA经典训练计划值得学习
- 大话中文文本分类之Transformers
- 网络编程相关概念学习笔记
- C# DirectX 开发2 - 定义一个矩阵和赋值
- hdu_1861_游船出租_201402282130
- php 对象赋值后改变成员变量影响赋值对象
- 线性条件随机场代码解读
- 【API进阶之路6】一个技术盲点,差点让整个项目翻车
- linux中存放着内核和引导程序的是,Linux操作系统 考试题库
- 停掉暴风影音stormliv.exe进程
- apk 反编译 - 最新版图文教程
- keil5代码可以下载但无法进行串口通信
- mac过热_如何阻止Mac过热
- 关于数据埋点的认识以及在流量分析系统中的实际使用
- python图片中文汉字标注乱码,变成方框
- 解决org.apache.zookeeper.KeeperException$UnimplementedException:KeeperErrorCode = Unimplemented for /S
热门文章
- u盘数据乱码怎么恢复?恢复U盘,图文教程在这里
- 企业邮箱邮件如何备份?公司邮件如何转发?
- 自助建站有什么优势?什么是自助建站
- Leetcode 第121,122,136,141,144,145,155,160,167,168题(Java解法)
- JAVA PDF文件下载
- android 国密签名,关于国密 (sm2,sm3,sm4)在Linux、python、Android、java、ios中的...
- 离职后,想去原来的公司上班怎么办?
- typeorm-统计数据,格式化时间
- 特斯拉向更多车主开放FSD测试,并推出安全评分系统,马斯克终于兑现承诺了吗?
- matlab范德瓦尔斯,范德瓦尔斯等温线的计算机描绘