模块API之register_module_notifier

int register_module_notifier(struct notifier_block *nb)
函数用于注册需要知道当前模块的状态,然后触发一个回调函数
使用的例子如下:
static __init int jump_label_init_module(void)
{
return register_module_notifier(&jump_label_module_nb);
}
注册的回调函数如下:
static struct notifier_block jump_label_module_nb = {
.notifier_call = jump_label_module_notify,
.priority = 1, /* higher than tracepoints */
};
其源码分享如下:
int register_module_notifier(struct notifier_block *nb)
{
return blocking_notifier_chain_register(&module_notify_list, nb);
}
可见就是注册了一个通用的通知链,那在什么时候触发这个通知链呢?
这个通知链定义如下:
static BLOCKING_NOTIFIER_HEAD(module_notify_list);
会出删除模块的时候调用,通知链的参数是MODULE_STATE_GOING


SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
unsigned int, flags)
{


blocking_notifier_call_chain(&module_notify_list,
     MODULE_STATE_GOING, mod);
}
会在模块初始化的时候调用通知链,参数是MODULE_STATE_LIVE
static noinline int do_init_module(struct module *mod)
{
/* Now it's a first class citizen! */
mod->state = MODULE_STATE_LIVE;
blocking_notifier_call_chain(&module_notify_list,
     MODULE_STATE_LIVE, mod);
}
总而言之,针对模块的每个状态
enum module_state {
MODULE_STATE_LIVE, /* Normal state. */
MODULE_STATE_COMING, /* Full formed, running module_init. */
MODULE_STATE_GOING, /* Going away. */
MODULE_STATE_UNFORMED, /* Still setting it up. */
};
都会发出一次通知链
srcu_notifier_chain_register函数用于向系统注册一个SRCU notifier链。它的原型如下: ```c int srcu_notifier_chain_register(struct srcu_notifier_head *nh, struct notifier_block *n) ``` 其中,nh是一个指向srcu_notifier_head结构体的指针,表示需要注册的SRCU notifier链;n是一个指向notifier_block结构体的指针,表示需要注册的notifier。 以下是一个使用srcu_notifier_chain_register函数的例子: ```c #include <linux/kernel.h> #include <linux/module.h> #include <linux/notifier.h> #include <linux/srcu.h> static struct srcu_notifier_head my_chain; static int my_notifier_func(struct notifier_block *nb, unsigned long val, void *data) { printk(KERN_INFO "my_notifier_func called with val=%lu\n", val); return NOTIFY_OK; } static struct notifier_block my_notifier = { .notifier_call = my_notifier_func, }; static int __init my_module_init(void) { int ret; ret = srcu_notifier_chain_register(&my_chain, &my_notifier); if (ret) { printk(KERN_ERR "Failed to register srcu notifier chain: %d\n", ret); return ret; } return 0; } static void __exit my_module_exit(void) { srcu_notifier_chain_unregister(&my_chain, &my_notifier); } module_init(my_module_init); module_exit(my_module_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Example SRCU notifier chain module"); ``` 在这个例子中,我们首先定义了一个srcu_notifier_head结构体my_chain和一个notifier_block结构体my_notifier。然后,在模块初始化函数my_module_init中,我们调用了srcu_notifier_chain_register函数将my_notifier注册到my_chain中。在模块退出函数my_module_exit中,我们调用了srcu_notifier_chain_unregister函数将my_notifier从my_chain中注销。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值