关于内核notifier随笔

来源:互联网 发布:计算机编程有什么种类 编辑:程序博客网 时间:2024/06/03 10:52
/*************************************************************************> File Name: notifierA.c> Author: XXDK> Email: v.manstein@qq.com > Created Time: Tue 11 Jul 2017 12:39:44 PM CST ************************************************************************//*  * notifierA.c:  * 0. 申明一个通知链 * 1. 向内核注册通知链 * 2. 定义事件  * 3. 导出符号,因而必需最后退出 * **/#include <linux/notifier.h>#include <linux/module.h>#include <linux/init.h>#include <linux/kernel.h> /* printk() */#include <linux/fs.h>     /* everything() */#define TESTCHAIN_INIT 0x52U#define TESTCHAIN_EXIT 0x25Ustatic RAW_NOTIFIER_HEAD(test_chain);/* define our own notifier_call_chain *//*  * 回调通知链test_chain为头节点的链表的每个 notifier_block 节点的 方法 * **/static int call_test_notifiers(unsigned long val, void *v){    return raw_notifier_call_chain(&test_chain, val, v);}EXPORT_SYMBOL(call_test_notifiers);/* define our own notifier_chain_register func *//* 注册一个 notifier block 到 test_chain 通知链 */ static int register_test_notifier(struct notifier_block *nb){    int err;    err = raw_notifier_chain_register(&test_chain, nb);    if(err)        goto out;out:    return err;}EXPORT_SYMBOL(register_test_notifier);static int __init notifierA_init(void){    printk(KERN_DEBUG "I'm in notifierA\n");    return 0;}static void __exit notifierA_exit(void){    printk(KERN_DEBUG "Goodbye to notifierA\n");}MODULE_LICENSE("GPL v2");module_init(notifierA_init);module_exit(notifierA_exit);

 

/*************************************************************************> File Name: notifierB.c> Author: XXDK> Email: v.manstein@qq.com > Created Time: Tue 11 Jul 2017 12:41:21 PM CST ************************************************************************//*  * notifierB.c  *     我这里向 notifierA.c 中定义test_chain * 注册了一个notifter_block 节点和对应的事件 * 回调方法 *     当别人调用, raw_notifier_call_chain 遍历 * test_chain 链表就会回调我的 test_init_event 方法 * 从而达到: 别人通过(遍历)通知链上我注册的通知块节点 * 回调通知块节点中的, 对应的方法,达到通知我的目的 * 本质是一种间接回调机制 **/  #include <linux/notifier.h>  #include <linux/module.h>  #include <linux/init.h>    #include <linux/kernel.h> /* printk() */  #include <linux/fs.h> /* everything() */    extern int register_test_notifier(struct notifier_block *nb);  #define TESTCHAIN_INIT 0x52U  #define TESTCHAIN_EXIT 0x25U    /* realize the notifier_call func */  int test_init_event(struct notifier_block *nb, unsigned long event,      void *v)  {      switch(event){      case TESTCHAIN_INIT:          printk(KERN_DEBUG "notifierB.c, I got the chain event: notifierC is on the way of init\n");          break;        default:          break;      }        return NOTIFY_DONE;  }  /* realize the notifier_call func */  int test_exit_event(struct notifier_block *nb, unsigned long event,      void *v)  {      switch(event){      case TESTCHAIN_EXIT:          printk(KERN_DEBUG "notifierB.c, I got the chain event: notifierC is off the way of exit\n");          break;        default:          break;      }        return NOTIFY_DONE;  }  /* define a notifier_block */  static struct notifier_block test_init_notifier = {      .notifier_call = test_init_event,  // 事件回调方法};  static struct notifier_block test_exit_notifier = {      .notifier_call = test_exit_event,  // 事件回调方法};  static int __init notifierB_init(void)  {      printk(KERN_DEBUG "I'm in notifierB\n");  /* 注册一个 notifier block 到 test_chain 通知链 */    register_test_notifier(&test_init_notifier); // 由 notifierA 提供的设施      register_test_notifier(&test_exit_notifier); // 由 notifierA 提供的设施      return 0;  }    static void __exit notifierB_exit(void)  {      printk(KERN_DEBUG "Goodbye to notifierB\n");  }    MODULE_LICENSE("GPL");    module_init(notifierB_init);  module_exit(notifierB_exit);  


/*************************************************************************> File Name: notifierC.c> Author: XXDK> Email: v.manstein@qq.com > Created Time: Tue 11 Jul 2017 12:41:52 PM CST ************************************************************************//* notifierC.c:发出通知链事件*/    #include <linux/notifier.h>  #include <linux/module.h>  #include <linux/init.h>  #include <linux/kernel.h> /* printk() */  #include <linux/fs.h> /* everything() */    extern int call_test_notifiers(unsigned long val, void *v);  #define TESTCHAIN_INIT 0x52U  #define TESTCHAIN_EXIT 0x25U    static int __init notifierC_init(void)  {      printk(KERN_DEBUG "I'm in notifierC\n");  // 回调通知链上对应的通知块的回调函数, 达到通知的目的    call_test_notifiers(TESTCHAIN_INIT, "no_use");            return 0;  }    static void __exit notifierC_exit(void)  {      printk(KERN_DEBUG "Goodbye to notifierC\n");  // 回调通知链上对应的通知块的回调函数, 达到通知的目的    call_test_notifiers(TESTCHAIN_EXIT, "no_use");  }    MODULE_LICENSE("GPL v2");    module_init(notifierC_init);  module_exit(notifierC_exit);