操作系统实践 第19章 Linux虚拟文件系统 山东科技大学操作系统教研组
本章目标 理解虚拟文件系统在Linux系统中的作用和地位 理解虚拟文件系统的基本结构和操作 熟悉proc文件系统的结构与管理方式
第19章 Linux虚拟文件系统 实验1:访问Linux内核虚拟文件系统 实验2:加载newproc文件系统
实验1 访问Linux内核虚拟文件系统 实验目的 实验内容 熟悉VFS的基本结构 请读者验证上述程序查询该程序所在文件系统的类型 和块大小信息
实验1 访问Linux内核虚拟文件系统 原理/背景 Linux虚拟文件系统是用户进程与文件系统之间的一个软件抽 象层,是一种软件机制 英文表达的全称是Virtual Filesystem Switch,简称为VFS, 负责Linux文件系统的管理 一方面,作为所有实体文件系统的管理者,它必须兼容各种具 体的文件系统 另一方面,它用来为内核其他子系统提供文件处理的通用接口
实验1 访问Linux内核虚拟文件系统 原理/背景 VFS在Linux内核中的逻辑关系
实验1 访问Linux内核虚拟文件系统 原理/背景 VFS在Linux中的作用
实验1 访问Linux内核虚拟文件系统 原理/背景 VFS的基本数据结构 该模型只存在于物理内存中,必须使用各种对象和函数指针与每 种文件系统适配 所有文件系统的实现都必须提供与VFS定义的结构配合的例程, 以弥合两种视图之间的差异
实验1 访问Linux内核虚拟文件系统 原理/背景 VFS的基本数据结构 从结构上来说,它们可以分为文件和文件系统两类 超级块对象 索引节点对象 目录项对象 文件对象 从结构上来说,它们可以分为文件和文件系统两类
实验1 访问Linux内核虚拟文件系统 原理/背景 VFS对象的操作 注册文件系统 extern int register_filesystem(struct file_system_type *); 在Linux中,所有文件系统都保存在一个链表file_systems中,该链 表被以全局变量的形式定义在<fs/filesystems.c>文件中 这里各个文件系统的名称存储为字符串
实验1 访问Linux内核虚拟文件系统 原理/背景 VFS对象的操作 注册文件系统 新的文件系统注册到内核时,将逐元素扫描该链表,直至到达链表尾 部或找到所需的文件系统。如果在链表中找到所需文件系统,会返回 一个适当的错误信息,这是因为一个文件系统不能注册两次;否则将 描述新文件系统的对象置于链表末尾,这样就完成了文件系统的注册 Linux文件系统中,文件系统都会以struct file_system_type数据结 构来表示,即文件系统注册函数register_filesystem的形参和链表 file_systems的数据类型
实验1 访问Linux内核虚拟文件系统 原理/背景 注册文件系统 VFS对象的操作 file_system_type结构被定义在<include/linux/fs.h>文件中 struct file_system_type { const char *name; int fs_flags; struct dentry *(*mount) (struct file_system_type *, int,const char *, void *); void (*kill_sb) (struct super_block *); struct module *owner; struct file_system_type * next; struct hlist_head fs_supers; …… };
实验1 访问Linux内核虚拟文件系统 原理/背景 VFS对象的操作 注册文件系统 相应地,Linux内核也提供了注销文件系统的系统调用接口 extern int unregister_filesystem(struct file_system_type *); 注销文件系统时,首先在链表中file_systems中找到要注销的文件系 统名称,然后将其从链表中删除
实验1 访问Linux内核虚拟文件系统 原理/背景 VFS对象的操作 文件系统装载 当将一个设备装载到文件空间的一个目录时,VFS将调用相应文件系统 所实现的mount()方法 接着,被装载点的目录结构将指向新文件系统的根inode节点 在file_system_type结构体中,函数指针mount指向的函数用于从底层 存储介质读取超级块,该函数依赖具体的文件系统 超级块对象和指向超级块的指针都是在调用mount()之后创建的
实验1 访问Linux内核虚拟文件系统 原理/背景 VFS对象的操作 函数指针mount的原型定义 struct dentry *(*mount) (struct file_system_type *, int,const char *, void *); 第一个参数是以file_system_type结构体描述的文件系统 第二参数表示了使用标志 第三个参数表示装载的设备名称 第四个参数为装载属性选项,通常为ASCII码字符串
实验1 访问Linux内核虚拟文件系统 原理/背景 VFS对象的操作 文件系统装载 当某个文件系统被装载时,将有一个文件系统能够装载点数据结构 vfsmount被创建。它记录该文件系统的根目录、超级块等信息 对于每个已经装载的文件系统,在内存中都创建了一个超级块结构。 该结构保存了文件系统本身和装载点的有关信息
实验1 访问Linux内核虚拟文件系统 原理/背景 与进程相关的文件系统数据结构 Linux系统中每一个进程都有一组与其相关的打开文件 files_struct结构 用于描述进程打开文件对象 进程描述表task_struct中的files指针指向该结构,将进程与其相关 的打开文件关联 该结构被定义在<include/linux/fdtable.h>文件中
实验1 访问Linux内核虚拟文件系统 原理/背景 与进程相关的文件系统数据结构 fs_struct结构 用于描述进程文件系统信息 进程描述表task_struct中的fs指针指向该结构 该结构被定义在<include/linux/fs_struct.h>文件中
实验1 访问Linux内核虚拟文件系统 原理/背景 与进程相关的文件系统数据结构 mnt_namespace结构 主要为了进程可以共享同样的命名空间 进程描述表task_struct中的namespace指针指向该结构 该结构被定义在<fs/mount.h>文件中
实验1 访问Linux内核虚拟文件系统 原理/背景 从当前进程访问Linux内核VFS文件系统 通过以上对VFS文件系统的分析可以发现,可以从当前进程探测和 操纵VFS文件系统
实验2 加载newproc文件系统 实验目的 实验内容 掌握文件系统的加载过程 Linux系统在启动时会默认加载一个proc文件系统,用 于查看运行中的内核信息,第13章中通过proc获取的进 程信息就是在该proc文件系统基础上完成的。下面请读 者在系统启动后,利用模块新加载一个newproc文件系统
实验2 加载newproc文件系统 原理/背景 proc文件系统 proc文件系统是Linux系统的进程文件系统,是一种仅 存在于内存中的伪文件系统,通过它可以查看运行中的 内核,访问进程信息,为用户空间与内核交换数据提供 修改系统行为的接口
实验2 加载newproc文件系统 原理/背景 主要数据结构 超级块 proc文件系统中没有自身独立的超级块表示,这是由于proc使用VFS的 超级块就可以表示其信息了 proc的超级块是在proc文件系统装载时动态分配得到的 可以查阅Linux内核源码<fs/proc/root.c>文件中proc_mount函数及相 关的sget函数
实验2 加载newproc文件系统 原理/背景 主要数据结构 inode节点 proc文件系统中的proc_inode结构体内嵌了inode节点的数据结构 proc_dir_entry proc_inode结构体和proc_dir_entry结构体都被定义在 <fs/proc/internal.h>文件中 proc_dir_entry表示每一个inode节点(即proc_inode)的实例, proc_dir_entry包含了proc文件所需要的信息 每一个proc文件都有一个inode节点
实验2 加载newproc文件系统 原理/背景 主要数据结构 目录项和文件对象 但是从proc_dir_entry结构体的定义发现,proc文件系统包含有文件 对象的相关操作,即proc_fops
实验2 加载newproc文件系统 原理/背景 proc文件系统的操作 proc文件系统使用全局变量proc_fs_type表示其数据类型 在proc文件系统的初始化函数proc_root_init中,通过调用 register_filesystem(&proc_fs_type)向内核注册proc文件系统 类型
实验2 加载newproc文件系统 原理/背景 proc文件系统的操作 proc文件系统在命名空间结构体pid_namespace中定义了指向 vfsmount实例的指针proc_mnt 通过调用kern_mount_data(&proc_fs_type, ns)进行初始化,这 里的ns为命名空间的实例,并且proc_mnt有一个成员包含了proc 文件系统超级块的信息(proc_mnt.mnt_sb) proc_mnt也包含了一个dentry实例proc_mnt.mnt_root proc文件系统通过实例化vfsmount方便了VFS对proc文件的管理
实验2 加载newproc文件系统 原理/背景 proc文件系统的操作 相对于其他逻辑文件系统的具体文件组织形式(比如ext4文件系 统的inode),proc文件系统也有自己的组织结构,那就是 proc_dir_entry结构 所有属于proc文件系统的文件,都对应一个proc_dir_entry结构, 并且在VFS需要读取proc文件的时候,把这个结构和VFS的inode建 立链接(即由inode->u.generic_ip指向该prc_dir_entry结构) proc文件系统实现了一套对proc_dir_entry结构的管理
第19章 Linux虚拟文件系统 课后练习 编写一个名为get_fat_boot的内核函数,通过系统调 用或动态模块调用它可以提取和显示出FAT文件系统盘 的引导扇区信息。这些信息的格式定义在内核文件 <include/uapi/linux/msdos_fs.h>的 fat_boot_sector结构体中
第19章 Linux虚拟文件系统 课后练习 在验证实验exp1程序的基础上,获取程序所在文件系 统的装载点 请在新加载的proc文件系统基础上,挑选第13章中部 分proc相关实验重新实现