linux之configfs简介和编程入门
2013-09-29 10:39
423 查看
转载请注原出处:http://blog.csdn.net/liumangxiong
一、什么是configfs
是一种基于ram的文件系统
二、configfs有什么用处
在用户空间配置内核对象
三、configfs VS ioctl
configfs可直接察看,通过用户态目录文件访问接口,适用于内核对象有众多复杂的配置。
四、configs VS sysfs
configfs可以在用户态创建和删除内核对象。
五、什么时候用configfs
当内核需要很多参数需要配置时;当需要动态创建内核对象并且内核对象需要修改配置时;
不想写用户态程序和ioctl时,写shell脚本就可以直接配置configfs。
六、怎么知道系统上是否已经安装了configfs,安装在哪个目录
执行如下命令,可以看到安装目录为/sys/kernel/config
cat /proc/mounts | grep configfs
configfs /sys/kernel/config configfs rw,relatime 0 0
七、configfs组织结构是怎么样的
顶层结构是struct configfs_subsystem,为configfs子系统结构,接着是struct config_group,是configfs目录和属性的容器,struct config_item是configfs目录,代表可配置的内核对象,struct configfs_attribute是目录下面的属性。
八、代码示例(来自内核目录Documentation\filesystems\configfs)
介绍代码之前,先过一下基本的数据结构:
configfs子系统,config_group是抽象容器,之所以叫容器,是因为容器中可以包括config_item,还可以递归包含config_group。struct mutex是用于子系统访问控制的。
config_group作为幕后主使,是不轻易出现在台前的。所以有了94行的struct config_item来表现为一个目录。
58行为目录名称。
63行为目录下属性和属性操作,属性表现为目录下的文本文件。
84行为属性操作方法,操作对象是86行属性。
85行为目录操作方法,可以在当前目录下创建item或group。
86行为当前目录属性数组。
属性非常简单,有属性名称、所属模块和访问权限。
示例1:创建一个最简单的configfs目录和可读写的属性
创建目录01-childless,下面有三个属性,其中属性storeme为可写。
# ll /sys/kernel/config/01-childless/
-r--r--r--. 1 root root 4096 Sep 27 05:16 description
-r--r--r--. 1 root root 4096 Sep 27 05:16 showme
-rw-r--r--. 1 root root 4096 Sep 27 05:16 storeme
创建一个结构体包含了configfs子系统,两个属性showme, storeme放在了这里。
虽然注释里说明了为什么把这两个属性放这里,但还是没太理解,既然属性description可以放子系统下,为什么其他两个属性不行呢?有谁知道的告知一下。
子系统定义如下:
142行,定义目录名称。
143行,定义属性和操作。
接着看属性和操作的定义:
133行,属性操作定义在128行和129行,这两个函数又是由126行宏定义的。126行宏依赖一个函数to_##_item,其中_item是宏的传入参数,这个函数的作用是从struct config_item转换到第49行的结构,然后作为函数show_attribute和store_attribute的传入参数。
134行,关联了属性数组,属性数组在119行定义,第120-122行属性又分别在114-117行定义。
一切准备就绪之后,在模块初始化地方调用子系统注册函数之后,就可以在/sys/kernel/config/下看到创建了子系统了。
416-417行,初始化子系统。
418行,注册子系统。
这里做个小结:
1、创建子系统struct configfs_subsystem
2、创建子系统下config_item_type,对应位置configfs_subsystem->config_group->config_item->config_item_type
3、创建config_item_type对应的属性数组和操作,操作主要是show_attribute和store_attribute
4、注册子系统configfs_register_subsystem
示例2:创建一个configfs目录,用户空间可创建目录(新的内核对象)
首先是定义configfs子系统,
接着定义config_item_type,
298行,定义了子系统根目录属性操作,跟示例1类似
300行,定义了子系统根目录属性,跟示例1类似
299行,这里新增加了configfs_group_operations,具体定义在293行,继续跟进294行函数simple_children_make_item
241行,定义了configfs_group_operations->make_item操作,返回值是新创建的struct config_item,传入参数是struct config_group,即是指定config_group下创建config_item项,这就意味着在该子系统(i.e /sys/kernel/config/02-simple-children)下执行命令mkdir,最终会执行到这个函数。
那执行mkdir 之后,会生成一个怎样的新目录呢?
249行,当调用mkdir时,这时就调用config_item_init_type_name初始化这个config_item,接着看250行的simple_child_type到底定义了怎么一个item类型?
225行,定义了config_item_type。
227行,先看属性,simple_child_attrs定义在177行,只有一个属性,这个属性定义在171行,仔细看一下这个属性,有可读写的。
所以经过mkdir之后,该目录下就自动生成一个名字为storeme的属性,其对应的操作定义在219行。具体如下:
# cd /sys/kernel/config/02-simple-children/
# ls
description
# mkdir test
# ll
-r--r--r--. 1 root root 4096 Sep 28 21:24 description
drwxr-xr-x. 2 root root 0 Sep 28 21:24 test
# tree
.
|-- description
`-- test
`-- storeme
1 directory, 2 files
# cat test/storeme
0
# echo 1 > test/storeme
# cat test/storeme
1
示例3:创建group
之前我们讲过,config_group是可以嵌套的,那么现在就来看一下嵌套之后是什么样的:
# cd /sys/kernel/config/03-group-children/
# ls
description
# mkdir test
# mkdir test/test1
# mkdir test/test2
# mkdir test/test3
# tree
.
|-- description
`-- test
|-- description
|-- test1
| `-- storeme
|-- test2
| `-- storeme
`-- test3
`-- storeme
看出与示例2的区别了吗?
首先看子系统定义
386行,config_item_type与之前的不一样,跟过去看看
375行,定义新的config_item_type,其根本区别在377行configfs_group_operations
371行,定义了configfs_group_operations,这里定义了make_group函数,在子系统下mkdir就会调用这个函数。
这份代码非常眼熟,跟示例2中创建config_item太像了,只不过把所有对象由config_item改为config_group类型的。
336行,simple_children_type正是示例2中对应的config_item_type。
所以这里的创建步骤首先是创建一个为config_group的目录,再在这个目录下创建config_item的目录。
到这里为止,简单地了解了一下configfs的实现原理,在某些应用中不失为一种很好的手段。
转载请注原出处:http://blog.csdn.net/liumangxiong
一、什么是configfs
是一种基于ram的文件系统
二、configfs有什么用处
在用户空间配置内核对象
三、configfs VS ioctl
configfs可直接察看,通过用户态目录文件访问接口,适用于内核对象有众多复杂的配置。
四、configs VS sysfs
configfs可以在用户态创建和删除内核对象。
五、什么时候用configfs
当内核需要很多参数需要配置时;当需要动态创建内核对象并且内核对象需要修改配置时;
不想写用户态程序和ioctl时,写shell脚本就可以直接配置configfs。
六、怎么知道系统上是否已经安装了configfs,安装在哪个目录
执行如下命令,可以看到安装目录为/sys/kernel/config
cat /proc/mounts | grep configfs
configfs /sys/kernel/config configfs rw,relatime 0 0
七、configfs组织结构是怎么样的
顶层结构是struct configfs_subsystem,为configfs子系统结构,接着是struct config_group,是configfs目录和属性的容器,struct config_item是configfs目录,代表可配置的内核对象,struct configfs_attribute是目录下面的属性。
八、代码示例(来自内核目录Documentation\filesystems\configfs)
介绍代码之前,先过一下基本的数据结构:
240struct configfs_subsystem { 241 struct config_group su_group; 242 struct mutex su_mutex; 243};
configfs子系统,config_group是抽象容器,之所以叫容器,是因为容器中可以包括config_item,还可以递归包含config_group。struct mutex是用于子系统访问控制的。
89/** 90 * group - a group of config_items of a specific type, belonging 91 * to a specific subsystem. 92 */ 93struct config_group { 94 struct config_item cg_item; 95 struct list_head cg_children; 96 struct configfs_subsystem *cg_subsys; 97 struct config_group **default_groups; 98};
config_group作为幕后主使,是不轻易出现在台前的。所以有了94行的struct config_item来表现为一个目录。
56struct config_item { 57 char *ci_name; 58 char ci_namebuf[CONFIGFS_ITEM_NAME_LEN]; 59 struct kref ci_kref; 60 struct list_head ci_entry; 61 struct config_item *ci_parent; 62 struct config_group *ci_group; 63 struct config_item_type *ci_type; 64 struct dentry *ci_dentry; 65};
58行为目录名称。
63行为目录下属性和属性操作,属性表现为目录下的文本文件。
82struct config_item_type { 83 struct module *ct_owner; 84 struct configfs_item_operations *ct_item_ops; 85 struct configfs_group_operations *ct_group_ops; 86 struct configfs_attribute **ct_attrs; 87};
84行为属性操作方法,操作对象是86行属性。
85行为目录操作方法,可以在当前目录下创建item或group。
86行为当前目录属性数组。
124struct configfs_attribute { 125 const char *ca_name; 126 struct module *ca_owner; 127 umode_t ca_mode; 128};
属性非常简单,有属性名称、所属模块和访问权限。
示例1:创建一个最简单的configfs目录和可读写的属性
创建目录01-childless,下面有三个属性,其中属性storeme为可写。
# ll /sys/kernel/config/01-childless/
-r--r--r--. 1 root root 4096 Sep 27 05:16 description
-r--r--r--. 1 root root 4096 Sep 27 05:16 showme
-rw-r--r--. 1 root root 4096 Sep 27 05:16 storeme
37/* 38 * 01-childless 39 * 40 * This first example is a childless subsystem. It cannot create 41 * any config_items. It just has attributes. 42 * 43 * Note that we are enclosing the configfs_subsystem inside a container. 44 * This is not necessary if a subsystem has no attributes directly 45 * on the subsystem. See the next example, 02-simple-children, for 46 * such a subsystem. 47 */ 48 49struct childless { 50 struct configfs_subsystem subsys; 51 int showme; 52 int storeme; 53};
创建一个结构体包含了configfs子系统,两个属性showme, storeme放在了这里。
虽然注释里说明了为什么把这两个属性放这里,但还是没太理解,既然属性description可以放子系统下,为什么其他两个属性不行呢?有谁知道的告知一下。
子系统定义如下:
138static struct childless childless_subsys = { 139 .subsys = { 140 .su_group = { 141 .cg_item = { 142 .ci_namebuf = "01-childless", 143 .ci_type = &childless_type, 144 }, 145 }, 146 }, 147};
142行,定义目录名称。
143行,定义属性和操作。
接着看属性和操作的定义:
114CHILDLESS_ATTR_RO(showme, childless_showme_read); 115CHILDLESS_ATTR(storeme, S_IRUGO | S_IWUSR, childless_storeme_read, 116 childless_storeme_write); 117CHILDLESS_ATTR_RO(description, childless_description_read); 118 119static struct configfs_attribute *childless_attrs[] = { 120 &childless_attr_showme.attr, 121 &childless_attr_storeme.attr, 122 &childless_attr_description.attr, 123 NULL, 124}; 125 126CONFIGFS_ATTR_OPS(childless); 127static struct configfs_item_operations childless_item_ops = { 128 .show_attribute = childless_attr_show, 129 .store_attribute = childless_attr_store, 130}; 131 132static struct config_item_type childless_type = { 133 .ct_item_ops = &childless_item_ops, 134 .ct_attrs = childless_attrs, 135 .ct_owner = THIS_MODULE, 136};
133行,属性操作定义在128行和129行,这两个函数又是由126行宏定义的。126行宏依赖一个函数to_##_item,其中_item是宏的传入参数,这个函数的作用是从struct config_item转换到第49行的结构,然后作为函数show_attribute和store_attribute的传入参数。
134行,关联了属性数组,属性数组在119行定义,第120-122行属性又分别在114-117行定义。
一切准备就绪之后,在模块初始化地方调用子系统注册函数之后,就可以在/sys/kernel/config/下看到创建了子系统了。
407static int __init configfs_example_init(void) 408{ 409 int ret; 410 int i; 411 struct configfs_subsystem *subsys; 412 413 for (i = 0; example_subsys[i]; i++) { 414 subsys = example_subsys[i]; 415 416 config_group_init(&subsys->su_group); 417 mutex_init(&subsys->su_mutex); 418 ret = configfs_register_subsystem(subsys); 419 if (ret) { 420 printk(KERN_ERR "Error %d while registering subsystem %s\n", 421 ret, 422 subsys->su_group.cg_item.ci_namebuf); 423 goto out_unregister; 424 } 425 } 426 427 return 0;
416-417行,初始化子系统。
418行,注册子系统。
这里做个小结:
1、创建子系统struct configfs_subsystem
2、创建子系统下config_item_type,对应位置configfs_subsystem->config_group->config_item->config_item_type
3、创建config_item_type对应的属性数组和操作,操作主要是show_attribute和store_attribute
4、注册子系统configfs_register_subsystem
示例2:创建一个configfs目录,用户空间可创建目录(新的内核对象)
首先是定义configfs子系统,
304static struct configfs_subsystem simple_children_subsys = { 305 .su_group = { 306 .cg_item = { 307 .ci_namebuf = "02-simple-children", 308 .ci_type = &simple_children_type, 309 }, 310 }, 311};
接着定义config_item_type,
289/* 290 * Note that, since no extra work is required on ->drop_item(), 291 * no ->drop_item() is provided. 292 */ 293static struct configfs_group_operations simple_children_group_ops = { 294 .make_item = simple_children_make_item, 295}; 296 297static struct config_item_type simple_children_type = { 298 .ct_item_ops = &simple_children_item_ops, 299 .ct_group_ops = &simple_children_group_ops, 300 .ct_attrs = simple_children_attrs, 301 .ct_owner = THIS_MODULE, 302};
298行,定义了子系统根目录属性操作,跟示例1类似
300行,定义了子系统根目录属性,跟示例1类似
299行,这里新增加了configfs_group_operations,具体定义在293行,继续跟进294行函数simple_children_make_item
232struct simple_children { 233 struct config_group group; 234}; 235 236static inline struct simple_children *to_simple_children(struct config_item *item) 237{ 238 return item ? container_of(to_config_group(item), struct simple_children, group) : NULL; 239} 240 241static struct config_item *simple_children_make_item(struct config_group *group, const char *name) 242{ 243 struct simple_child *simple_child; 244 245 simple_child = kzalloc(sizeof(struct simple_child), GFP_KERNEL); 246 if (!simple_child) 247 return ERR_PTR(-ENOMEM); 248 249 config_item_init_type_name(&simple_child->item, name, 250 &simple_child_type); 251 252 simple_child->storeme = 0; 253 254 return &simple_child->item; 255}
241行,定义了configfs_group_operations->make_item操作,返回值是新创建的struct config_item,传入参数是struct config_group,即是指定config_group下创建config_item项,这就意味着在该子系统(i.e /sys/kernel/config/02-simple-children)下执行命令mkdir,最终会执行到这个函数。
那执行mkdir 之后,会生成一个怎样的新目录呢?
249行,当调用mkdir时,这时就调用config_item_init_type_name初始化这个config_item,接着看250行的simple_child_type到底定义了怎么一个item类型?
171static struct configfs_attribute simple_child_attr_storeme = { 172 .ca_owner = THIS_MODULE, 173 .ca_name = "storeme", 174 .ca_mode = S_IRUGO | S_IWUSR, 175}; 176 177static struct configfs_attribute *simple_child_attrs[] = { 178 &simple_child_attr_storeme, 179 NULL, 180}; 219static struct configfs_item_operations simple_child_item_ops = { 220 .release = simple_child_release, 221 .show_attribute = simple_child_attr_show, 222 .store_attribute = simple_child_attr_store, 223}; 224 225static struct config_item_type simple_child_type = { 226 .ct_item_ops = &simple_child_item_ops, 227 .ct_attrs = simple_child_attrs, 228 .ct_owner = THIS_MODULE, 229};
225行,定义了config_item_type。
227行,先看属性,simple_child_attrs定义在177行,只有一个属性,这个属性定义在171行,仔细看一下这个属性,有可读写的。
所以经过mkdir之后,该目录下就自动生成一个名字为storeme的属性,其对应的操作定义在219行。具体如下:
# cd /sys/kernel/config/02-simple-children/
# ls
description
# mkdir test
# ll
-r--r--r--. 1 root root 4096 Sep 28 21:24 description
drwxr-xr-x. 2 root root 0 Sep 28 21:24 test
# tree
.
|-- description
`-- test
`-- storeme
1 directory, 2 files
# cat test/storeme
0
# echo 1 > test/storeme
# cat test/storeme
1
示例3:创建group
之前我们讲过,config_group是可以嵌套的,那么现在就来看一下嵌套之后是什么样的:
# cd /sys/kernel/config/03-group-children/
# ls
description
# mkdir test
# mkdir test/test1
# mkdir test/test2
# mkdir test/test3
# tree
.
|-- description
`-- test
|-- description
|-- test1
| `-- storeme
|-- test2
| `-- storeme
`-- test3
`-- storeme
看出与示例2的区别了吗?
首先看子系统定义
382static struct configfs_subsystem group_children_subsys = { 383 .su_group = { 384 .cg_item = { 385 .ci_namebuf = "03-group-children", 386 .ci_type = &group_children_type, 387 }, 388 }, 389};
386行,config_item_type与之前的不一样,跟过去看看
371static struct configfs_group_operations group_children_group_ops = { 372 .make_group = group_children_make_group, 373}; 374 375static struct config_item_type group_children_type = { 376 .ct_item_ops = &group_children_item_ops, 377 .ct_group_ops = &group_children_group_ops, 378 .ct_attrs = group_children_attrs, 379 .ct_owner = THIS_MODULE, 380};
375行,定义新的config_item_type,其根本区别在377行configfs_group_operations
371行,定义了configfs_group_operations,这里定义了make_group函数,在子系统下mkdir就会调用这个函数。
326static struct config_group *group_children_make_group(struct config_group *group, const char *name) 327{ 328 struct simple_children *simple_children; 329 330 simple_children = kzalloc(sizeof(struct simple_children), 331 GFP_KERNEL); 332 if (!simple_children) 333 return ERR_PTR(-ENOMEM); 334 335 config_group_init_type_name(&simple_children->group, name, 336 &simple_children_type); 337 338 return &simple_children->group; 339}
这份代码非常眼熟,跟示例2中创建config_item太像了,只不过把所有对象由config_item改为config_group类型的。
336行,simple_children_type正是示例2中对应的config_item_type。
所以这里的创建步骤首先是创建一个为config_group的目录,再在这个目录下创建config_item的目录。
到这里为止,简单地了解了一下configfs的实现原理,在某些应用中不失为一种很好的手段。
转载请注原出处:http://blog.csdn.net/liumangxiong
相关文章推荐
- linux之configfs简介和编程入门
- linux之configfs简介和编程入门
- Linux简介及常用命令使用5--linux shell编程入门
- Linux下C语言编程入门-9信号简介
- Linux编程入门-gcc、make和gdb简介
- Linux下串口编程入门
- Linux网络编程入门必备函数说明
- linux Socket编程入门
- Linux学习笔记一 ---- Linux基础知识认知以及初识Linux下C编程入门
- linux操作系统下c语言编程入门
- Linux下C语言编程入门-10关于信号处理操作
- Linux网络编程入门
- 第1章 Linux下C语言编程简介
- Linux 下串口编程入门教程
- linux下c语言编程 vi 简介
- Linux下多线程编程简介(二)
- Linux学习笔记(8)之Shell编程入门--输入输出、引号
- linux下C语言编程8-SDL图形入门
- Linux学习笔记——轻松学Linux shell编程 第一部分:Linux初学者编程入门