在《设备驱动模型之:kobject,kset,ktype(四)》这篇博文里面已经详细介绍了kset的操作以及kset与kobject的关系,下面则是对于这篇博文的一些实际操作:
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kobject.h>
#include <linux/slab.h>
static struct kset * first_kset = NULL;
static struct kset * second_kset = NULL;
static struct kset third_kset;
#define FIRST_KSET_NAME "first"
#define SECOND_KSET_NAME "second"
#define THIRD_KSET "third"
static int filter(struct kset *kset, struct kobject *kobj)
{
printk("this is %s , and kset is : %s , and kobj is %s\n", __func__, kset->kobj.name, kobj->name);
return 1;
}
static const char *name(struct kset *kset, struct kobject *kobj)
{
printk("this is %s , and kset is : %s , and kobj is %s\n", __func__, kset->kobj.name, kobj->name);
return kset->kobj.name;
}
static int uevent(struct kset *kset, struct kobject *kobj,
struct kobj_uevent_env *env)
{
printk("this is %s , and kset is : %s , and kobj is %s\n", __func__, kset->kobj.name, kobj->name);
return 0;
}
static struct kset_uevent_ops uevent_ops = {
.filter = filter,
.name = name,
.uevent = uevent
};
static ssize_t kshow(struct kobject *kobj, struct attribute * attr,char *buff)
{
printk("this is %s, and kboj : %s and attr: %s\n", __func__, kobj->name, attr->name);
return 0;
}
static ssize_t kstore(struct kobject *kobj,struct attribute *attr,const char * buff, size_t count)
{
printk("this is %s, and kboj : %s and attr: %s\n", __func__, kobj->name, attr->name);
printk("store buff: %s\n", buff);
return 0;
}
static struct sysfs_ops sysfs_ops= {
.show = kshow,
.store = kstore
};
static struct attribute attr1 = {.name = "alex1", .mode=S_IRWXUGO};
static struct attribute attr2 = {.name = "alex2", .mode=S_IRWXUGO};
static struct attribute *default_attrs[] = {
&attr1,
&attr2,
NULL
};
static struct kobj_type third_ktype = {
.sysfs_ops = &sysfs_ops,
.default_attrs = default_attrs
};
static inline int __init
kset_test_init(void)
{
int ret = 0;
first_kset = kset_create_and_add(FIRST_KSET_NAME, & uevent_ops,NULL);
if (NULL == first_kset){
ret = -ENOMEM;
goto out;
}
second_kset = kset_create_and_add(SECOND_KSET_NAME, &uevent_ops, &(first_kset->kobj));
if (NULL == second_kset){
ret = -ENOMEM;
goto create_second_kset_failed;
}
kobject_set_name(&(third_kset.kobj), THIRD_KSET);
third_kset.kobj.parent = &(second_kset->kobj);
third_kset.kobj.ktype = &third_ktype;
third_kset.uevent_ops = &uevent_ops;
third_kset.kobj.kset = second_kset;
ret = kset_register(&third_kset);
if (ret){
goto third_kset_register_failed;
}
return ret;
third_kset_register_failed:
kset_unregister(second_kset);
create_second_kset_failed:
kset_unregister(first_kset);
out:
return ret;
}
static inline void __exit
kset_test_exit(void)
{
kset_unregister(&third_kset);
kset_unregister(second_kset);
kset_unregister(first_kset);
}
module_init(kset_test_init);
module_exit(kset_test_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Alexander");
下一篇博客则是介绍kset与kobject和kset的的关系的,可能介绍的不好有遗漏的地方请大家谅解。