mnt_namespace学习笔记


基础知识(重点理解设备树)

块设备:

块设备(Block Device)是指在操作系统中以固定大小的块为单位进行数据读写的设备。 每个块的大小通常为512字节或更大,用于存储和传输数据。 块设备可以是硬盘、固态硬盘(SSD)、光盘、闪存等存储设备。

树形结构:

目录/文件这种结构,用树形结构去访问一个块设备的关键是块设备和文件系统

Linux用super_block来将两者联系在一起;

inode和dentry

系统使用 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

对于一个super_block,通过s_root找到自己的根节点,然后dentry之间构成了一个树形结构,由孩子指向父亲;

同时还有两个链表结构用于父子间的指向;

多设备的层次化(重点理解mount树)

Linux 使用父子树的形式来构造,父设备树中的一个文件夹 struct dentry 可以充当子设备树的挂载点 mountpoint

比之前多了一个struct mount结构;

如果是多个块设备的挂载,相互之间形成了树形结构:

如果 dentry 成为了挂载点 mountpoint,会给其标识成 DCACHE_MOUNTED。我们在查找路径的时候同样会判断 dentryDCACHE_MOUNTED 标志,一旦置位就变成了 mountpoint,挂载点文件夹下原有的内容就不能访问了,转而访问子设备树根节点下的内容。

规则1、一个设备可以被挂载多次:

规则2、一个挂载点可以挂载多个设备:

解释:这里第一次挂载成功之后,挂载点(蓝色)的dentry会被标记为DCACHE_MOUNTED,那么第二次挂载再次输入这个目录的路径之后,这里就不能被访问了,转而访问第一次挂载的块设备的根节点的dentry,所以我们看到的第二次的挂载点就是途中黄色的dentry了。

path

因为 Linux 提供的灵活的挂载规则,所以我们如果要标识一个路径 struct path 的话需要两个元素:vfsmountdentry

path的定义路径:https://elixir.bootlin.com/linux/v6.13.6/source/include/linux/path.h

判断两个路径相等用的是path_equal,要同时比较mnt和dentry:

1741524467268

chroot

多名空间的层次化(mnt_namespace)

mount

创建文件会创建对应的path;

删除文件会删除对应的path;

所以mount的时候回去找这个目录的path,mount成功后会将struct mount 挂载到struct path上;

chroot

task_struct中有一个fs成员:https://elixir.bootlin.com/linux/v6.13.5/source/include/linux/sched.h#L785

然后查看fs_struct定义:

关注chroot中的set_fs_root:

https://elixir.bootlin.com/linux/v6.13.5/source/fs/fs_struct.c#L15

就是设置fs->root为path;

copy_mnt_ns

参考

https://tinylab.org/mnt-namespace/


文章作者: q1ming
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 q1ming !
  目录