如何在已创建的sysfs目录moo下创建attribute_group boo?
在sysfs的moo目录下添加boo子目录的实现方案
核心思路是借助Linux内核sysfs的kobject机制,在moo目录对应的kobject下创建boo的kobject,并注册boo的属性组,同时将boo的逻辑与moo解耦到独立文件中。
1. 暴露moo目录的kobject指针
moo目录是通过attribute_group创建的,首先需要在moo.c中保存moo对应的kobject指针,供boo.c调用:
- 在
moo.c中定义全局kobject指针:// moo.c struct kobject *moo_kobj; - 修改moo目录的创建逻辑,保存返回的kobject(以
kobject_create_and_add结合sysfs_create_group为例):// moo.c 中创建moo目录的核心代码 moo_kobj = kobject_create_and_add("moo", foo_kobj); // foo_kobj为父目录foo的kobject if (!moo_kobj) { return -ENOMEM; } if (sysfs_create_group(moo_kobj, &moo_attr_group)) { kobject_put(moo_kobj); return -ENOMEM; } - 在
moo.h中声明该指针,让boo.c可以访问:// moo.h extern struct kobject *moo_kobj;
2. 在boo.c中实现boo目录的创建与属性逻辑
在boo.c中实现boo目录的kobject创建、属性定义及属性组注册:
2.1 定义boo的属性与属性组
// boo.c #include <linux/kobject.h> #include <linux/sysfs.h> #include "moo.h" // 属性读取函数 static ssize_t boo_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { // 自定义读取逻辑,示例返回固定字符串 return sprintf(buf, "boo_example\n"); } // 属性写入函数 static ssize_t boo_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) { // 自定义写入逻辑,示例直接返回写入长度 return count; } // 定义单个属性 static struct kobj_attribute boo_attr = __ATTR(boo, 0644, boo_show, boo_store); // 组装属性数组 static struct attribute *boo_attrs[] = { &boo_attr.attr, NULL, // 数组必须以NULL结尾 }; // 定义属性组 static const struct attribute_group boo_attr_group = { .attrs = boo_attrs, }; static struct kobject *boo_kobj;
2.2 实现boo目录的初始化与清理函数
// boo.c int boo_init(void) { int ret; // 检查moo的kobject是否已有效创建 if (!moo_kobj) { return -EINVAL; } // 创建boo目录,父目录为moo_kobj boo_kobj = kobject_create_and_add("boo", moo_kobj); if (!boo_kobj) { return -ENOMEM; } // 在boo目录下注册属性组 ret = sysfs_create_group(boo_kobj, &boo_attr_group); if (ret) { kobject_put(boo_kobj); // 创建失败,释放资源 return ret; } return 0; } // 清理boo目录及资源 void boo_exit(void) { if (boo_kobj) { sysfs_remove_group(boo_kobj, &boo_attr_group); kobject_put(boo_kobj); } }
同时在boo.h中声明这两个函数,供moo.c调用:
// boo.h int boo_init(void); void boo_exit(void);
3. 在moo的初始化流程中调用boo的初始化
修改moo.c的初始化函数,在moo目录创建成功后启动boo的初始化,同时完善错误回滚逻辑:
// moo.c #include "boo.h" int moo_init(void) { int ret; // 创建moo目录的代码(同步骤1) moo_kobj = kobject_create_and_add("moo", foo_kobj); if (!moo_kobj) { return -ENOMEM; } ret = sysfs_create_group(moo_kobj, &moo_attr_group); if (ret) { kobject_put(moo_kobj); return ret; } // 初始化boo目录 ret = boo_init(); if (ret) { // 回滚moo的创建,避免资源泄漏 sysfs_remove_group(moo_kobj, &moo_attr_group); kobject_put(moo_kobj); return ret; } return 0; } void moo_exit(void) { // 先清理boo目录,再清理moo目录 boo_exit(); sysfs_remove_group(moo_kobj, &moo_attr_group); kobject_put(moo_kobj); }
4. 关键注意事项
- 编译时需将
moo.c与boo.c链接到同一内核模块或内核源码部分,确保符号可见。 - 错误处理必须完整,任何环节创建失败都要回滚已分配的资源,防止内存泄漏。
- 如果moo目录是基于
device对象创建的(比如用device_add_group),可通过device_find_child获取moo的kobject,或直接将device指针暴露给boo.c,再用device_add_group在指定路径下创建boo目录。 - 属性权限(如示例中的
0644)需根据实际需求设置,兼顾功能与安全性。
内容的提问来源于stack exchange,提问作者Suja S
相关产品推荐
相关产品推荐

