“tcp丢包分析”实验解析(一)--proc文件系统

栏目: IT技术 · 发布时间: 4年前

内容简介:“tcp丢包分析”系列文章代码来自谢宝友老师,由西邮陈莉君教授研一学生进行解析,本文由戴君毅整理,梁金荣编辑,贺东升校对。最初开发

“tcp丢包分析”系列文章代码来自谢宝友老师,由西邮陈莉君教授研一学生进行解析,本文由戴君毅整理,梁金荣编辑,贺东升校对。

最初开发 /proc 文件系统是为了提供有关系统中进程的信息。但是这个文件系统非常有用, /proc 文件系统包含了一些目录(用作组织信息的方式)和虚拟文件。虚拟文件可以向用户呈现内核中的一些信息,也可以用作一种从用户空间向内核发送信息的手段。

/proc 文件系统可以为用户提供很多信息, 在左边是一系列数字编号,每个实际上都是一个目录,表示系统中的一个进程。由于在 Linux 中创建的第一个进程是 init 进程,因此它的 process-id 为 1。

“tcp丢包分析”实验解析(一)--proc文件系统

右边的目录包含特定信息,比如 cpuinfo 包含了CPU的信息, modules 包含了内核模块的信息。

“tcp丢包分析”实验解析(一)--proc文件系统

为了解决一些实际问题,我们需要在 /proc 下创建条目捕获信息,使用文件系统通用方法肯定是不行的,需要使用相关API编写内核模块来实现。

在做谢宝友老师写的“TCP丢包分析”实验里,首先就会在 /proc 下创建条目,较为简单,先来看 initexit

框架还是比较清晰的,需要深入源码来感受一下,第一部分代码:

struct proc dir entry *pe;

结构 proc_dir_entry 定义在 <fs/proc/internal.h> 下,可以称为一个 pde ,在创建一个文件或目录时就会创建一个 pde 来管理它们。而在打开它们的时候,则会创建一个 proc_inode 结构:

可以使用 PROC_I 宏,也就是我们熟悉的 container_of ,从虚拟文件系统的 inode 得到 proc_inode ,进而得到 pde

回到 proc_dir_entry 结构,很多信息从字段名字就可以看出, pde 需要指向创建自己的父 pde 结构, subdir 的组织方式是红黑树,还需要我们实现操作集以及一些引用计数和命名规则等等。

有意思的是,除了操作集之外还有一个 proc_write_t ,对于一些功能比较简单的 proc 文件,我们只要实现这个函数即可,而不用设置 inode_operations 结构,在注册 proc 文件的时候,会自动为 proc_fops 设置一个缺省的 file_operations 结构。

此时,我们可以想象以下模型:

“tcp丢包分析”实验解析(一)--proc文件系统

第二部分代码是:

proc_mkdir("mooc", NULL);

proc_mkdir("mooc/net", NULL);

remove proc entry("mooc/net", NULL);

remove proc entry("mooc", NULL);

易知其功能是在 /proc 下创建和删除条目 mooc/net ,以创建操作为例,看下内核代码如何实现的:

这里逻辑很简单, proc_mkdir 实际上是 proc_mkdir_data 默认了权限为 S_IRUGO|S_IXUGO ,再调用 __proc_create 初始化一个局部 pde ,如果成功则初始化操作集,并调用 proc_register 注册这个 pde 到父 pde 下并返回。

__proc_create 调用 kmem_cache_zalloccache 中获取空间给 pde ,并且对条目名称进行检查。如果成功,则对名称、模式等属性赋值,设置引用计数并初始化锁。

__proc_register 接收两个参数,一个父亲 pde ,一个当前 pde ,目的是把当前 pde 挂到父亲名下,前面提到 subdir 的组织形式是红黑树,那么肯定涉及相关代码,来看:

首先判断当前 pdeid 是否越界,如果没有打开子目录锁,把当前 pdeparent 字段指向父亲 pde ,并尝试在红黑树中插入子目录,成功后重新上锁并返回当前 pde

红黑树的插入操作篇幅所限不再叙述。

下面看第三部分代码:

proc_create 内部也是调用 proc_create_data ,但还需自行指定权限以及操作集回调,用于创建一个 proc 文件,在3.10内核中取代 create_proc_entry 这个旧的接口。

回到实验代码,我们为加入的条目编写操作集接口。

一般地,内核通过在 procfs 文件系统下建立文件来向用户空间提供输出信息,用户空间可以通过任何文本阅读应用查看该文件信息,但是 procfs 有一个缺陷,如果输出内容大于1个内存页,需要多次读,因此处理起来很难,另外,如果输出太大,速度比较慢,有时会出现一些意想不到的情况, AlexanderViro 实现了一套新的功能,使得内核输出大文件信息更容易,它们叫做 seq_file ,所以在使用它们的操作集时需要包含 seq_file.h 头文件。

Drop_packet_open 实际上是调用了 single_open

为什么这么做?内核文档给出了相关描述:

“tcp丢包分析”实验解析(一)--proc文件系统

https://www.kernel.org/doc/Documentation/filesystems/seq_file.txt

你可能发现,内核文档里显示的是 seq_open ,而实验里是 single_open ,它们有什么区别呢?实际上内核文档的最后给出了答案:

“tcp丢包分析”实验解析(一)--proc文件系统

谢宝友老师的实验中运用 seq_file 的极简版本(extra-simple version),只需定义一个 show() 函数。完整的情况我们还需要实现 start() , next() 等迭代器来对 seq_file 进行操作。极简版本中, open 方法需要调用 single_open ,对应的, release 方法调用 single_release

推荐阅读https://www.ibm.com/developerworks/cn/linux/l-proc.html


以上所述就是小编给大家介绍的《“tcp丢包分析”实验解析(一)--proc文件系统》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

C++数据结构与算法

C++数据结构与算法

[美]乔兹德克(Adam Drozdek) / 徐丹、吴伟敏 / 清华大学出版社 / 2014-10-1 / 63.00元

本书全面系统地介绍了数据结构,并以C++语言实现相关的算法。书中主要强调了数据结构和算法之间的联系,使用面向对象的方法介绍数据结构,其内容包括算法的复杂度分析、链表、栈、队列、递归、二叉树、图、排序和散列。书中还清晰地阐述了同类教材中较少提到的内存管理、数据压缩和字符串匹配等主题。书中包含大量的示例分析和图形,便于读者进一步理解和巩固所学的知识。一起来看看 《C++数据结构与算法》 这本书的介绍吧!

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试