当前位置: 首页 > news >正文

驱动_ConfigFS多级目录操作

ConfigFS 系统实现多级组目录

文章目录

  • 前言
  • 参考资料
  • 一、ConfigFS实现多级目录知识点
    • 源码实例
      • 源码分析
      • 结果分析
  • 二、结构体 configfs_group_operations-config_group 再分析
  • 三、ConfigFS 多级目录Group和Item 区别和联系
    • 定义与角色
    • 关键区别
    • 联系与协作
    • 示例场景
    • 内核开发视角
    • group和Item 区别小结
  • 总结


前言

前面的知识点从ConfigFS 概念 -> ConfigFS基础必备 ->ConfigFS注册子系统->ConfigFS注册group组->ConfigFS 注册Item-> ConfigFS 释放资源->再到这里ConfigFS 属性读取->ConfigFS 实现多级目录创建。其实都是从一个简单例子,一步一步到各个知识点,对同一个实例不断添加知识点的功能。 这里就开始理解属性相关知识了。

其实就是要在子group 中继续创建group 实现这样的一个功能或者需求。

参考资料

重温一下前面的知识点,方便后续查看资料时候对知识点进行再一次的脉络梳理:

Linux驱动-设备树插件语法
设备树插件基础必备
设备树插件注册子系统
驱动-设备树插件-注册group
RK3568驱动指南|第八篇 设备树插件-第78章 用户空间创建item实验
驱动-设备数插件-创建Item
设备树插件-第79章 完善drop和release函数实验
驱动-ConfigFS-释放资源篇
设备树插件 注册attribute实验
Linux驱动-ConfigFS-读写属性操作
设备树插件-第81章 实现多级目录实验
迅为设备树插件模块知识点

一、ConfigFS实现多级目录知识点

源码实例

#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/configfs.h>// 定义一个名为"mygroup"的config_group结构体
static struct config_group mygroup;// 自定义的配置项结构体
struct myitem
{struct config_item item;int size;void *addr;
};
// 自定义的配置组结构体
struct mygroup
{struct config_group group;
};// 配置项释放函数
void myitem_release(struct config_item *item)
{struct myitem *myitem = container_of(item, struct myitem, item);kfree(myitem);printk("%s\n", __func__);
};// 读取配置项内容的回调函数
ssize_t myread_show(struct config_item *item, char *page)
{struct myitem *myitem = container_of(item, struct myitem, item);memcpy(page, myitem->addr, myitem->size);printk("%s\n", __func__);return myitem->size;
};// 写入配置项内容的回调函数
ssize_t mywrite_store(struct config_item *item, const char *page, size_t size)
{struct myitem *myitem = container_of(item, struct myitem, item);myitem->addr = kmemdup(page, size, GFP_KERNEL);myitem->size = size;printk("%s\n", __func__);return myitem->size;
};// 创建只读配置项
CONFIGFS_ATTR_RO(my, read);
// 创建只写配置项
CONFIGFS_ATTR_WO(my, write);// 配置项属性数组
struct configfs_attribute *my_attrs[] = {&myattr_read,&myattr_write,NULL,
};// 配置项操作结构体
struct configfs_item_operations myitem_ops = {.release = myitem_release,
};// 配置项类型结构体
static struct config_item_type mygroup_item_type = {.ct_owner = THIS_MODULE,.ct_item_ops = &myitem_ops,.ct_attrs = my_attrs,
};// 配置组类型结构体
static struct config_item_type mygroup_type = {.ct_owner = THIS_MODULE,};// 创建配置项函数
struct config_item *mygroup_make_item(struct config_group *group, const char *name)
{struct myitem *myconfig_item;printk("%s\n", __func__);myconfig_item = kzalloc(sizeof(*myconfig_item), GFP_KERNEL);config_item_init_type_name(&myconfig_item->item, name, &mygroup_item_type);return &myconfig_item->item;
}// 删除配置项函数
void mygroup_delete_item(struct config_group *group, struct config_item *item)
{struct myitem *myitem = container_of(item, struct myitem, item);config_item_put(&myitem->item);printk("%s\n", __func__);
}
// 创建配置组函数
struct config_group *mygroup_make_group(struct config_group *group, const char *name)
{struct mygroup *mygroup;printk("%s\n", __func__);mygroup = kzalloc(sizeof(*mygroup), GFP_KERNEL);config_group_init_type_name(&mygroup->group, name, &mygroup_type);return &mygroup->group;
};// 配置组操作结构体
struct configfs_group_operations mygroup_ops = {.make_item = mygroup_make_item,.drop_item = mygroup_delete_item,.make_group = mygroup_make_group,
};// 配置项类型结构体
static const struct config_item_type mygroup_config_item_type = {.ct_owner = THIS_MODULE,.ct_group_ops = &mygroup_ops,
};// 配置项类型结构体
static const struct config_item_type myconfig_item_type = {.ct_owner = THIS_MODULE,.ct_group_ops = NULL,
};// 定义一个configfs_subsystem结构体实例"myconfigfs_subsystem"
static struct configfs_subsystem myconfigfs_subsystem = {.su_group = {.cg_item = {.ci_namebuf = "myconfigfs",.ci_type = &myconfig_item_type,},},
};// 模块的初始化函数
static int myconfig_group_init(void)
{// 初始化配置组config_group_init(&myconfigfs_subsystem.su_group);// 注册子系统configfs_register_subsystem(&myconfigfs_subsystem);// 初始化配置组"mygroup"config_group_init_type_name(&mygroup, "mygroup", &mygroup_config_item_type);// 在子系统中注册配置组"mygroup"configfs_register_group(&myconfigfs_subsystem.su_group, &mygroup);return 0;
}// 模块退出函数
static void myconfig_group_exit(void)
{// 注销子系统configfs_unregister_subsystem(&myconfigfs_subsystem);
}module_init(myconfig_group_init); // 指定模块的初始化函数
module_exit(myconfig_group_exit); // 指定模块的退出函数MODULE_LICENSE("GPL");     // 模块使用的许可证
MODULE_AUTHOR("fangchen"); // 模块的作者

源码分析

为什么对比,每个新知识点都是前面知识点一步一步累加起来的功能、逻辑。 对比看看 方便理解新的知识点。

这里拿ConfigFS读写属性操作 和 ConfigFS 实现多级目录 案例对比,如下:

在这里插入图片描述
我们之前整理过 驱动-设备数插件-创建Item 篇章中 configfs_group_operations 相关知识点
在这里插入图片描述

意思就是说:一个配置组也就是(group) 可以包含多个配置项(item)和子配置组。 配置项和配置组都是作为配置组的成员存在的。 配置项和配置组之间通过指针进行关联, 以形成一个层次结构。

结果分析

在这里插入图片描述

[root@topeet:/sys/kernel/config/myconfigfs/mygroup]# cd  test2
[root@topeet:/sys/kernel/config/myconfigfs/mygroup/test2]# ls -l
total 0
-r--r--r-- 1 root root 4096 Oct 17 18:00 read
--w------- 1 root root 4096 Oct 17 18:00 write
[root@topeet:/sys/kernel/config/myconfigfs/mygroup/test2]# mkdir hhh
mkdir: cannot create directory 'hhh': Operation not permitted
[root@topeet:/sys/kernel/config/myconfigfs/mygroup/test2]#

这里在 mygroup 组中创建了Item: test和test2, 并且在test/test2 中看到创建的属性 read/write , 那么如何验证可以在Item 创建组group呢? 那不就是命令 mkdir 内核名 来验证创建组。

上面执行 mkdir hh 就是创建 group,只是没有权限而已。为什么没有权限,因为我们没有写创建group 的回调方法。

二、结构体 configfs_group_operations-config_group 再分析

在这里插入图片描述

对于创建group 前面详解过 驱动-设备树插件-注册group 这里不做详细阐述。
在这里插入图片描述

三、ConfigFS 多级目录Group和Item 区别和联系

在 Linux 的 ConfigFS 文件系统中,Group 和 Item 是两种核心对象类型,用于构建动态的、层次化的配置结构。它们的区别和联系如下:

定义与角色

Group(组)
是一个容器对象,用于组织和管理其他 Group 或 Item。
类似于目录,可以包含子目录或文件。
通常表示一个逻辑分组或功能模块(如存储设备的后端、网络服务的配置组等)。

Item(项)

  • 是一个叶子对象,代表具体的配置实体。
  • 类似于文件,存储实际的配置属性(如参数、状态等)。
  • 不能包含其他对象,是配置树中的终端节点。

关键区别

特性GroupItem
用途组织层次结构(容器)存储具体配置(叶子节点)
能否包含子对象可以包含子 Group 或 Item不能包含子对象
生命周期通常由内核模块预先定义动态创建/删除(用户可操作)
操作接口提供 mkdir/rmdir 操作提供属性文件(读写配置值)

联系与协作

层次关系
ConfigFS 通过 Group 和 Item 构建树形结构:

/config/├── group1/          # Group│   ├── item1        # Item│   └── subgroup/    # Group│       └── item2    # Item└── group2/          # Group└── item3        # Item

Group 是分支节点,Item 是叶子节点。

动态性

Group 通常由内核模块在初始化时注册(如 configfs_register_subsystem)。
Item 由用户通过 mkdir 在 Group 下动态创建(触发内核回调函数分配资源)。

属性交互

Group 可能包含默认属性(如描述信息)。
Item 的属性文件(如 param1、status)允许用户读写具体配置。

示例场景

假设实现一个虚拟存储设备的配置:

/config/target/├── core/                 # Group(核心配置)│   └── enable            # Item(开关属性)└── storage/             # Group(存储后端)├── fileio/           # Group(文件后端)│   ├── create        # Item(创建存储)│   └── path         # Item(路径配置)└── block/            # Group(块设备后端)└── dev           # Item(设备名)
  • target/、storage/ 是 Group,用于分类。
  • enable、path、dev 是 Item,存储具体值。

内核开发视角

Group
需实现 struct config_group_type,定义其子对象类型(通过 ct_group_ops 和 ct_item_ops)。

Item
需实现 struct config_item_type,定义属性操作(如 show/store 方法)。

group和Item 区别小结

  • Group 是目录结构的骨架,Item 是配置数据的载体。
  • 用户通过操作 Group 创建层次,通过 Item 读写配置。
  • 两者协同实现动态、可扩展的配置管理,常见于虚拟化、存储(如 LIO Target)、网络等子系统。

总结

  • 理解组group 创建子组 group 方案,通过结构体configfs_group_operations 配置实现
  • 前面从设备数插件基本知识到子系统创建、组 Item创建、创建属性、子组创建,知识点都是一环套一环,每个知识点不难,但是得形成体系才行。
http://www.lryc.cn/news/617885.html

相关文章:

  • 光功率dBm为何是负数?一文详解
  • Google OAuth 配置步骤指南,实现Google Drive文件同步功能。
  • UVM验证—UVM 简述
  • 快速了解TF-IDF算法
  • 逐际动力开源运控 tron1-rl-isaacgym 解读与改进
  • 自由学习记录(81)
  • 5B 参数,消费级显卡可部署:Wan2.2-TI2V-5B 本地部署教程,9分钟跑出电影级大片!
  • 【运维进阶】WEB 服务器
  • GB17761-2024标准与电动自行车防火安全的技术革新
  • Redis 数据结构及特点
  • 【工作笔记】Wrappers.lambdaQuery()用法
  • ROS2学习(1)—基础概念及环境搭建
  • JavaEE 初阶第十七期:文件 IO 的 “管道艺术”(下)
  • vscode新建esp32工程,没有sample_project怎么办?
  • 计算机网络:ovn数据通信都是用了哪些协议?
  • 应用层模拟面试题
  • C语言(06)——二、八、十、十六进制的相互转换
  • Effective C++ 条款35:考虑 virtual函数以外的其他选择
  • 【已解决】报错:WARNING: pip is configured with locations that require TLS/SSL
  • HarmonyOS 开发入门 第一章
  • 一文读懂 C# 中的 Lazy<T>
  • Python 在自动化办公汇总和脚本示例
  • 本地文件夹与 GitHub 远程仓库绑定并进行日常操作的完整命令流程
  • 【基本有序数组中找到有且仅有的一个无序元素并进行排序之顺序法】2022-10-12
  • Linux线程——线程控制及理解
  • Transformer前传:Seq2Seq与注意力机制Attention
  • Haystack:面向大模型应用的模块化检索增强生成(RAG)框架
  • 什么情况下会导致日本服务器变慢?解决办法
  • Linux kernel network stack, some good article
  • Flink + Hologres构建实时数仓