好记性不如铅笔头

kernel, linux, 操作系统

Linux内核kset的简单笔记

LDD3的第14章《Linux设备模型》一章节把Linux内核中的很多结构体串讲了一遍,满满的干货,非常值得一看,这里简单的笔记下代码注释吧。作者的语文实在太差,很多阅读心得不知道怎么笔记出来,还请各位高手勿喷~

kset基于kobject,因此kset包含kobject的所有功能,比如组成树形结构,或者属于另一个kset。

CONTENTS

\linux-2.6.11\include\linux\kobject.h

/**
 *	kset - a set of kobjects of a specific type, belonging
 *	to a specific subsystem.
 *
 *	All kobjects of a kset should be embedded in an identical 
 *	type. This type may have a descriptor, which the kset points
 *	to. This allows there to exist sets of objects of the same
 *	type in different subsystems.
 *
 *	A subsystem does not have to be a list of only one type 
 *	of object; multiple ksets can belong to one subsystem. All 
 *	ksets of a subsystem share the subsystem's lock.
 *
 *      Each kset can support hotplugging; if it does, it will be given
 *      the opportunity to filter out specific kobjects from being
 *      reported, as well as to add its own "data" elements to the
 *      environment being passed to the hotplug helper.
 */
struct kset_hotplug_ops {
	int (*filter)(struct kset *kset, struct kobject *kobj);
	char *(*name)(struct kset *kset, struct kobject *kobj);
	int (*hotplug)(struct kset *kset, struct kobject *kobj, char **envp,
			int num_envp, char *buffer, int buffer_size);
};

struct kset {
	struct subsystem	* subsys;/* kset一般都属于一个特定的subsystem */
	struct kobj_type	* ktype; /* kset对应的kobj_type,这个优先于kobject里面的kobj_type */
	struct list_head	list; /* kset内部维护一个链表,连接着内部管理的kobject */
	struct kobject		kobj;  /* kset也是一个kobject,由于无法继承,这里包含一个kobject */
	struct kset_hotplug_ops	* hotplug_ops;
};


extern void kset_init(struct kset * k);
extern int kset_add(struct kset * k);
extern int kset_register(struct kset * k);
extern void kset_unregister(struct kset * k);

/* 根据kobject获取外部包含的kset */
static inline struct kset * to_kset(struct kobject * kobj)
{
	return kobj ? container_of(kobj,struct kset,kobj) : NULL;
}

/* 增加一个kset的引用计数,可以发现,是调用的内部的kobject来进行引用计数  */
static inline struct kset * kset_get(struct kset * k)
{
	return k ? to_kset(kobject_get(&k->kobj)) : NULL;
}

/* 减少一个kset的引用计数 */
static inline void kset_put(struct kset * k)
{
	kobject_put(&k->kobj);
}

/* 返回一个kobject对应的kobj_type,注意这里的k不一定是kset,外部包裹的
不一定是kset。
这里可以看到对于一个kobject,它的kobj_type的获取不是直接获取它自己的,
而是先查询下它有没有在一个kset中,如果在一个kset中,就用kset的kobj_type来
作为自己的kobj_type。这点非常重要,否则属性的读写调用就会出现问题
*/
static inline struct kobj_type * get_ktype(struct kobject * k)
{
	if (k->kset && k->kset->ktype)
		return k->kset->ktype;
	else 
		return k->ktype;
}

extern struct kobject * kset_find_obj(struct kset *, const char *);


/**
 * Use this when initializing an embedded kset with no other 
 * fields to initialize.
 */
 /* 设置一个kset的名字,其实就是设置kset内部包含的kobject的名字 */
#define set_kset_name(str)	.kset = { .kobj = { .name = str } }

\linux-2.6.11\lib\kobject.c

/**
 *	kset_init - initialize a kset for use
 *	@k:	kset 
 */
 /* 初始化kset  */
void kset_init(struct kset * k)
{
	kobject_init(&k->kobj);
	INIT_LIST_HEAD(&k->list);
}


/**
 *	kset_add - add a kset object to the hierarchy.
 *	@k:	kset.
 *
 *	Simply, this adds the kset's embedded kobject to the 
 *	hierarchy. 
 *	We also try to make sure that the kset's embedded kobject
 *	has a parent before it is added. We only care if the embedded
 *	kobject is not part of a kset itself, since kobject_add()
 *	assigns a parent in that case. 
 *	If that is the case, and the kset has a controlling subsystem,
 *	then we set the kset's parent to be said subsystem. 
 */
 
/* 讲kset加入到某个树形中,注意这里的关系在调用函数之前已经设置了。
*/
int kset_add(struct kset * k)
{
/* 如果kset附属于某个subsystem,那么就把kset的parent设置为该subsystem  */
	if (!k->kobj.parent && !k->kobj.kset && k->subsys)
		k->kobj.parent = &k->subsys->kset.kobj;

	return kobject_add(&k->kobj);/* 内部调用kobject */
}


/**
 *	kset_register - initialize and add a kset.
 *	@k:	kset.
 */

int kset_register(struct kset * k)
{
	kset_init(k);
	return kset_add(k);
}


/**
 *	kset_unregister - remove a kset.
 *	@k:	kset.
 */

void kset_unregister(struct kset * k)
{
	kobject_unregister(&k->kobj);
}


/**
 *	kset_find_obj - search for object in kset.
 *	@kset:	kset we're looking in.
 *	@name:	object's name.
 *
 *	Lock kset via @kset->subsys, and iterate over @kset->list,
 *	looking for a matching kobject. If matching object is found
 *	take a reference and return the object.
 */
/* 在kset管理的链表中查找指定名称的kobject */
struct kobject * kset_find_obj(struct kset * kset, const char * name)
{
	struct list_head * entry;
	struct kobject * ret = NULL;

	down_read(&kset->subsys->rwsem);
	list_for_each(entry,&kset->list) {
		struct kobject * k = to_kobj(entry);
		if (kobject_name(k) && !strcmp(kobject_name(k),name)) {
			ret = kobject_get(k);
			break;
		}
	}
	up_read(&kset->subsys->rwsem);
	return ret;
}

 

发表评论

20 − 14 =

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据