山庄来客的专栏

Android, Linux Kernel Research Notes

内核中的通知链

 

通知链(Notifier Chains):

通知链用于向请求通知的代码区发送状态变化消息。

有几个内核中预定义的通知器:

l  Die Notification: 当一个内核函数触发了一个由“opps”引起的陷阱或错误时。

l  Net device notification:当一个网卡禁用或启用时,

l  CPU frequency notification:当处理器频率发生变化时

l  Internet address notification:当一个网卡IP地址发生变化时

 

自定义通知链:

使用BLOCKING_NOTIFIER_HEAD()初始化,通过blocking_notifier_chain_register()来注册通知链。在中断上下文中,使用ATOMIC_NOTIFIER_HEAD()初始化,通过atomic_notifier_chain_register()来注册通知链。

 

代码示例:

#include <linux/notifier.h>
#include <linux/kdebug.h>
#include <linux/netdevice.h>
#include <linux/inetdevice.h>

extern int register_die_notifier(struct notifier_block *nb);
extern int unregister_die_notifier(struct notifier_block *nb);

/* Die notification event handler */
int my_die_event_handler(struct notifier_block *self, unsigned long val, void *data)
{
  struct die_args *args = (struct die_args *)data;

  if (val == 1) { /* '1' corresponds to an "oops" */
    printk("my_die_event: OOPs! at EIP=%lx\n", args->regs->eip);
  } /* else ignore */
  return 0;
}

/* Die Notifier Definition */
static struct notifier_block my_die_notifier = {
  .notifier_call = my_die_event_handler,
};



/* Net Device notification event handler */
int my_dev_event_handler(struct notifier_block *self,
                              unsigned long val, void *data)
{
  printk("my_dev_event: Val=%ld, Interface=%s\n", val,
           ((struct net_device *) data)->name);
  return 0;
}

/* Net Device notifier definition */
static struct notifier_block my_dev_notifier = {
  .notifier_call = my_dev_event_handler,
};


/* User-defined notification event handler */
int my_event_handler(struct notifier_block *self,
                          unsigned long val, void *data)
{
  printk("my_event: Val=%ld\n", val);
  return 0;
}

/* User-defined notifier chain implementation */
static BLOCKING_NOTIFIER_HEAD(my_noti_chain);

static struct notifier_block my_notifier = {
  .notifier_call = my_event_handler,
};

/* Driver Initialization */
static int __init
my_init(void)
{
  /* ... */

  /* Register Die Notifier */
  register_die_notifier(&my_die_notifier);

  /* Register Net Device Notifier */
  register_netdevice_notifier(&my_dev_notifier);

  /* Register a user-defined Notifier */
  blocking_notifier_chain_register(&my_noti_chain, &my_notifier);

  /* ... */
  return 0;
}

//驱动模块初始化函数
static int __init hello3_init(void)
{
 	   my_init();
	   blocking_notifier_call_chain(&my_noti_chain, 100, NULL);
       return 0;
}

module_init(hello3_init);
//驱动模块注册函数
static void __exit hello3_exit(void)
{
	unregister_die_notifier(&my_die_notifier);
	unregister_netdevice_notifier(&my_dev_notifier);
	blocking_notifier_chain_unregister(&my_noti_chain, &my_notifier);
}

module_exit(hello3_exit);


 

阅读更多
个人分类: Linux内核研究
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭