Notification不像信号一样,他必须注册了以后才可以使用。
也不像信号一样有默认的信号处理方法。
要使用Notifier我们需要在notifier_chain里边注册notifier_block结构。
Notifier系统是有文件kernel/sys.c实现的。
该系统导出了三个API:
notifier_chain_register
notifier_chain_unregister
notifier_call_chain
目前系统中已经出现的notifier chain有
cup_chain
module_notify_list
panic_notifier_list
exit_task_notifier exit_mmap_notifier exec_unmap_notifier profier_listeners
reboot_notifier_list
一个使用notifier的例子。
#ifndef __KERNEL__
# define __KERNEL__
#endif
#define __NO_VERSION__ /* don't define kernel_verion in module.h */
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/module.h>
#include <linux/notifier.h>
// #include <linux/kthread.h>
// #include <linux/net.h>
// #include <net/sock.h>
// #include <linux/socket.h>
// #include <linux/netlink.h>
// #include <linux/skbuff.h>
char kernel_version [] = UTS_RELEASE;
static struct notifier_block mod_watch_nb;
/** module watch callback
*/
int mod_watch_cb( struct notifier_block * nb, unsigned long code, void * arg)
{
struct module * mod = (struct module *)arg;
if ( code != MODULE_STATE_COMING ) {
printk("mod_watch_cb: wrong code %ld\n", code );
return EINVAL;
}
/* get the module name and print it */
printk("mod_watch_cb: module %s is coming\n", mod->name);
return 0;
}
/** module init
* @return 0 on success
*/
int mod_watch_init( void )
{
/* initialize the notifier_block */
mod_watch_nb.notifier_call = mod_watch_cb;
mod_watch_nb.next = 0;
mod_watch_nb.priority = 0;
if ( register_module_notifier( & mod_watch_nb ) == 0 ) {
printk("mod_watch_init: ok \n");
return 0;
} else {
printk("mod_watch_init: failed to register notifier \n");
return 1;
}
}
/** module exit
*
* In the thread model it stops the thread,
* then it releases the knetlink sock.
*/
void mod_watch_exit( void )
{
if ( unregister_module_notifier( & mod_watch_nb ) == 0 ) {
printk("mod_watch_exit: ok \n");
} else {
printk("mod_watch_exit: fail \n");
}
}
module_init( mod_watch_init );
module_exit( mod_watch_exit );
MODULE_LICENSE("GPL");
MODULE_AUTHOR("marco corvi");
MODULE_DESCRIPTION("notify example");
Makefile:
KSRC := /lib/modules/$(shell uname -r)/build
SRC_DIR=$(shell pwd)
all: prereq_check kernel-module
# test user programs
UEXE :=
test: $(UEXE)
user-program: user-program.c
gcc -g -O2 -o $@ $^
SRCS := mod_watch.c
OBJS := mod_watch.o
prereq_check:
@ if [ ! -f $(KSRC)/include/linux/version.h ]; then \
echo "Kernel sources not been found. Aborting."; \
exit 1;\
fi
MODULE := mod_watch.ko
obj-m := mod_watch.o
mod_watch-objs :=
kernel-module:
$(MAKE) -C $(KSRC) SUBDIRS=$(SRC_DIR) modules
clean:
rm -f *.o *.ko .*.ko.cmd .*.o.cmd *.mod.[oc] *~
rm -rf .tmp_versions
rm -f $(UEXE)
posted on 2007-04-22 17:33
yongqing 阅读(683)
评论(0) 编辑 收藏 引用 所属分类:
linux