Essential linux device driver:
Notifier chains are used to send status change messges to code regions that request them.
There are Die notification, Net device notification, CPU frequency notification, and Internet address notification.
To attach your code to a notifier chain, you have to register an event handler with the associated chain.
Example:
//notifier.c #include <linux/notifier.h> //#include <asm/kdebug.h> #include <linux/kdebug.h> #include <linux/netdevice.h> #include <linux/inetdevice.h> MODULE_LICENSE("Dual BSD/GPL"); int my_die_event_handler(struct notifier_block *self, unsigned long val, void* data); int my_dev_event_handler(struct notifier_block *self, unsigned long val, void* data); int my_event_handler(struct notifier_block *self, unsigned long val, void *data); // Die notifier Definition static struct notifier_block my_die_notifier = { .notifier_call = my_die_event_handler, }; //Die notification envent handler int my_die_event_handler(struct notifier_block *self, unsigned long val, void* data) { struct die_args *args = (struct die_args*)data; args = args; if (val == 1) { printk("%s: OOPs! EIP = %lx, ESP= %lx/n", __func__, (long)(args->regs->eip),(long) ( args->regs->esp)); } return 0; } // Net device notifier definition static struct notifier_block my_dev_notifier = { .notifier_call = my_dev_event_handler, }; // Net Device notification event handler int my_dev_event_handler(struct notifier_block *self, unsigned long val, void* data) { printk(KERN_EMERG "%s: Val=%ld, Interface = %s/n", __func__, val, ((struct net_device *)data)->name); return 0; } // User defined notifier chain implementation static BLOCKING_NOTIFIER_HEAD(my_noti_chain);// what's this used for static struct notifier_block my_notifier = { .notifier_call = my_event_handler, }; // User defined notification event handler int my_event_handler(struct notifier_block *self, unsigned long val, void *data) { printk("%s: Val=%ld /n", __func__, val); return 0; } static int mydrv_init(void) { printk("Hello, beatiful new world!/n"); // Register die notifer register_die_notifier(&my_die_notifier); // Register Net device notifer register_netdevice_notifier(&my_dev_notifier); // Register a user-defined notifier blocking_notifier_chain_register(&my_noti_chain, &my_notifier); return 0; } static void mydrv_exit(void) { printk("Bye, my dear!/n Cruel world/n"); unregister_die_notifier(&my_die_notifier); unregister_netdevice_notifier(&my_dev_notifier); blocking_notifier_chain_unregister(&my_noti_chain, &my_notifier); } module_init(mydrv_init); module_exit(mydrv_exit);