41 sysfs 文件系统

前言

在 linux 中常见的文件系统 有很多, 如下 

基于磁盘的文件系统, ext2, ext3, ext4, xfs, btrfs, jfs, ntfs 
内存文件系统, procfs, sysfs, tmpfs, squashfs, debugfs 
闪存文件系统, ubifs, jffs2, yaffs  

文件系统这一套体系在 linux 有一层 vfs 抽象, 用户程序不用关心 底层文件系统的具体实现, 用户只用操作 open/read/write/ioctl/close 的相关 系统调用, 这一层系统调用 会操作 vfs 来处理响应的业务 

vfs 会有上面各种文件系统对应的 读写 相关服务, 进而 将操作下沉到 具体的文件系统 

我们这里 来看一下 sysfs 文件系统, 这是一个 基于 内核内存的文件系统, 读写的都是 kobject 的相关信息项, 由内核代码来组织的树形结构 
 

如何分配 inode ?

我们这里的操作是 “cat /sys/module/i8042/parameters/debug”, 访问之前 对应的 inode 还不存在 

sysfs 的 inode 也是懒加载创建的, 当你访问它的时候,才会创建对应的 inode, 这时候 才会在 vfs 中有对应的角色 

sysfs 对应的 iop->lookup 为 kernfs_iop_lookup, 实现如下, 在父级 kernfs_node 下面查询当前文件的 kernfs_node, 然后根据 当前 kernfs_node 去创建, 初始化当前文件对应的 inode

另外就是 kernfs_node 本身会有一套树形结构, 来维护 sysfs 下面各个文件的关系, 以便于这里的 lookup inode 的实现 

kernfs_get_inode 中新建并初始化 inode, ino 取自 kernfs_node 中早就暂存了一个 i_no

iget_locked 中从 super_block 中分配 inode, 并初始化 ino, 将当前 inode 放到了 inode_hashtable 中, 下一次根据 获取直接拿到的是 已有的 inode

kernfs_init_inode 是初始化 inode 的各个函数 

kenfs_init_node 中初始化了 inode->private/i_ops/i_fops 等等, f_ops 用于后面读写 当前文件的操作 

/sys/xx 是在哪里创建的 ? 

从上面可以看到, 系统首先维护的是 kernfs_node 的树形结构

然后 真正的文件的获取是在访问给定的文件的时候创建的, 比如 cat “/sys/module/i8042/parameters/debug”, “ls /sys/module/i8042/”

上面的例子是一个 “cat /sys/module/i8042/parameters/debug” 访问到具体的文件的例子, 这里我们来测试一个 访问目录, 然后 懒加载创建目录下面的所有的 文件的 inode 的过程 

在新建 inode 的地方打上断点, 可以看到的是 外层在迭代 “/sys/devices/breakpoint” 目录下面的所有文件[基于 kernfs_node], 然后通过 lstat 来访问给定的文件, 进而实现主动触发了 文件夹下面所有的文件的访问

然后具体的根据 kernfs_node 迭代文件夹下面所有目录的地方是在这里, dir_emit 会访问给定的文件, 访问上面的 lstat 函数 

接下来问题 便是 kernfs_node 的这棵树的初始化的流程了, 内核是先构造了这棵树, 然后用户/内核 访问 的时候, 再根据 kernfs_node 创建了对应的 inode

kernfs_node树 的初始化是在 内核初始化的阶段, 创建了相关的 kobject, 就会注册 kernfs_node, 挂在 kernfs_node 树上面 

如下是注册 sysfs_root, 也就是 “/sys”

如下是注册 “/sys” 下面的 “fs”, 创建 kobject 的时候, 传入 parent 为 NULL, 默认 parent 是 sysfs_root

又比如我们这里的 i8042驱动 下面的 debug 参数 

此参数是属于 i8042驱动 下面的 参数组 下面的 debug 参数

因此这里在 i8042节点 下面创建了 parameters 节点, 然后作为 debug 参数节点的父节点

然后是循环 i8042 的参数列表, 注册对应的参数在 i8042节点 下面的 parameters节点 上面

创建 kernfs_node 的时候, 传入的 ops 为 sysfs_file_kfops_rw

kn->attr->ops 为 sysfs_file_kfops_rw, kn->priv 为当前 attr 

如何分配 存储的空间?

大多数的 sysfs 的 ”文件” 是不单独占用存储空间的 

是通过相应的读写函数 去操作对应的 kobject

如何 读写数据?

读取的链路如下 

file->f_ops 为 inode 的 f_ops, 为kernfs_file_ops[初始化是在 kernfs_init_inode], 其中 read 为 kernfs_fop_read

下一层 seq_read 的 m->op 来自于封装 file 对象的时候, 初始化的 seq_file, 默认的 ops 为 kernfs_seq_ops

再下一层 of->kn 为 kernfs_node, kernfs_node->attr.ops 为上面构造 kernfs_node 的时候传入的 ops 为 sysfs_file_kfops_rw, 其中 seq_show 为 sysfs_kf_seq_show

接下来就是根据 kernfs_node 中存放的 attribute 的信息, 定位到 module_attribute, param_attribute, kernel_attribute, 然后通过 kernel_attribute 的 ops 来读写 kernel_attribute

如何根据 path 获取到上下文的数据?

在 kernfs_fop_open 的时候, 根据 inode, kernfs_node 以及上下文 构造 file 

kernfs_fop_open 中的 seq_open 中构造了 seq_file, ops 初始化为上下文传入的 kernfs_seq_ops, 构造之后的 file->private_data 为 新建的 seq_file

在外层的 kernfs_fop_open 封装 file, 新建 kernfs_open_file 并初始化, 作为了 ((seq_file)file->private_data)->private_data

seq_open 中新建了 seq_file, 作为 file->private_data

kernfs_fop_open 中 kernfs_node 是来自于 file->f_path.dentry->d_fsdata, 那么这个 d_fsdata 是在哪里填充进去的呢? 

来自于根据 path 向下遍历的时候, i_op->lookup 中在 dentry 中封装了 d_fsdata 为 kernfs_node

完 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/297084.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

用CSDN训练的InsCode AI创作博文:数据治理体系建设

想不想用AI帮我们写方案? 想尝试用CSDN提供的InsCode AI创作助手协助我们进行技术方案的创作,看看效果如何,能不能辅助我们日常的方案编写与创作?以前用ChatGPT也尝试过,但对于专业性更强的内容,还有表现的…

mmyolo导出模型

报错:python mmyolo/projects/easydeploy/tools/export_onnx.py configs/yolov7/tfj_yolov7_tiny_syncbn_fast_8x16b-300e_coco.py work_dirs/tfj_yolov7_tiny_syncbn_fast_8x16b-300e_coco/best_coco_bbox_mAP_epoch_10.pth --model-only --simplify 运行报错 No m…

Nginx优化(重点)与防盗链(新版)

Nginx优化(重点)与防盗链 Nginx优化(重点)与防盗链一、隐藏Nginx版本号1、修改配置文件2、修改源代码 二、修改Nginx用户与组1、编译安装时指定用户与组2、修改配置文件指定用户与组 三、配置Nginx网页的缓存时间四、实现Nginx的日志切割1、data的用法2、编写脚本进行日志切割的…

在linux操作系统Centos上安装服务器相关软件

如果您的服务器没有图形界面(GUI),您可以通过命令行(终端)来安装和配置Tomcat、JDK和MySQL等软件。以下是在没有图形界面GHome的 Linux 系统上安装这些软件的基本步骤: 对于CentOS Stream 9,您可以按照以下步骤在命令行上安装Tomcat、JDK 和 MySQL 数据库: 1. 安装JD…

AI项目十九:YOLOV8实现目标追踪

若该文为原创文章,转载请注明原文出处。 主要是学习一下实现目标追踪的原理,并测试一下效果。 目的是通过YOLOV8实现人员检测,并实现人员追踪,没个人员给分配一个ID,实现追踪的效果。 也可以统计人数。在小区办公楼…

Linux环境下MySQL安装

MySQL是一个关系型数据库管理系统,有瑞典MySQL AB公司于1995年开发,现属于Oracle旗下产品。MySQL是最流行的关系型数据库管理系统之一,在WEB应用方面,MySQL是最好的RDBMS应用软件之一,因为它具有快速、轻量级和易用的特…

《图解HTTP》第1章 了解Web及网络基础

《图解HTTP》第1章 了解Web及网络基础 1. 使用 HTTP 协议访问 Web1.1 网络基础 TCP/IP1.2 TCP/IP 协议族1.2.1 TCP/IP 的分层管理 1. 使用 HTTP 协议访问 Web Web 使用一种名为 HTTP(HyperText Transfer Protocol,超文本传输协议) 的协议作为…

cpp_06_缺省构造_拷贝构造_拷贝赋值_初始化表

1 构造函数 1.1 构造函数可重载&#xff1a; 构造函数可以通过形参表的差别化形成重载关系 重载关系的构造函数&#xff0c;通过构造函数的实参类型进行匹配 使用缺省参数可以减少构造函数重载的数量 // consover.cpp 构造函数的重载 #include <iostream> using name…

系列一、MQ简介

一、MQ简介 1.1、概述 MQ&#xff08;Message Queue&#xff09;&#xff0c;是一种提供消息队列服务的中间件&#xff0c;也称为消息中间件&#xff0c;是一套提供了消息&#xff08;消息即数据&#xff0c;一般消息的体量不会很大&#xff09;生产、存储、消费全过程的API软…

Plantuml之组件图语法介绍(二十二)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

【论文解读】3D视觉标定的显式文本解耦和密集对齐(CVPR 2023)

来源&#xff1a;投稿 作者&#xff1a;橡皮 编辑&#xff1a;学姐 论文链接&#xff1a;https://arxiv.org/abs/2209.14941 开源代码&#xff1a;https://github.com/yanmin-wu/EDA 图1所示。文本解耦&#xff0c;密集对齐的3D视觉标定。文本中的不同颜色对应不同的解耦分量。…

LLaMA开源大模型源码分析!

Datawhale干货 作者&#xff1a;宋志学&#xff0c;Datawhale成员 花了一晚上照着transformers仓库的LLaMA源码&#xff0c;把张量并行和梯度保存的代码删掉&#xff0c;只留下模型基础结构&#xff0c;梳理了一遍LLaMA的模型结构。 今年四月份的时候&#xff0c;我第一次接触…