前言
最近再看一些涉及内核模块的常用API,学习的过程记录下来。
函数find_module( )用来获得一个指向模块的指针。它是根据给定的模块名字查找模块链表,如果找到一个与给定的模块名字相匹配的模块,则返回该模块的指针。由于一个模块的名字是唯一的且不允许有重名的模块,因此基于模块名查找模块是可行的。
一、find_module源码解析
enum module_state {
MODULE_STATE_LIVE,
MODULE_STATE_COMING,
MODULE_STATE_GOING,
MODULE_STATE_UNFORMED,
};
MODULE_STATE_LIVE表示模块在正常运行中,已经完成初始化任务之后。 MODULE_STATE_COMING表示在加载模块期间。 MODULE_STATE_GOING表示模块在卸载期间。
static struct module *find_module_all(const char *name,
bool even_unformed)
{
struct module *mod;
list_for_each_entry(mod, &modules, list) {
if (!even_unformed && mod->state == MODULE_STATE_UNFORMED)
continue;
if (strcmp(mod->name, name) == 0)
return mod;
}
return NULL;
}
struct module *find_module(const char *name)
{
return find_module_all(name, false);
}
EXPORT_SYMBOL_GPL(find_module);
#define list_for_each_entry(pos, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member); \
&pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))
find_module实现逻辑很简单,遍历内核全局双向链表modules,比较链表上模块的名字与传入的参数名字是否相等,相等则表示找到。
注意调用该函数时要加锁访问:
DEFINE_MUTEX(module_mutex);
EXPORT_SYMBOL_GPL(module_mutex);
static LIST_HEAD(modules);
mutex_lock(&module_mutex);
find_module(mod_name);
mutex_unlock(&module_mutex);
二、API使用
# include <linux/init.h>
# include <linux/kernel.h>
# include <linux/module.h>
#define MODULE_NAME "nf_conntrack"
static int __init lkm_init(void)
{
struct module *mod;
mutex_lock(&module_mutex);
mod = find_module(MODULE_NAME);
mutex_unlock(&module_mutex);
if(mod){
printk("module name = %s\n", mod->name);
printk("module core_size = %d\n", mod->core_size);
printk("module refcount = %ld\n", module_refcount(mod));
}
return -1;
}
module_init(lkm_init);
MODULE_LICENSE("GPL");
通过字符串"nf_conntrack"找到nf_conntrack模块:
参考资料
Linux 3.10.0
|