一,Notification Chains的作用,什么时候用到它?
大部分内核子系统之间都是相互依赖的,所以一个子系统的某个事件被检测或者发生很可能会有其他子系统对其感兴趣,这需要这些内核子系统之间具有相互通知的能力,linux内核使用Notification Chains来实现这一功能.注意,Notification Chains只是用于内核子系统之间的通知,而内核空间与用户之间的交互有另外一套机制.
二,Notification Chains是什么?
一个Notification Chains本质上就是一系列函数,这些函数在某个事件发生时被调用.通常情况下,每个函数都和其它子系统有对应关系,即当某个特定事件发生时,对其感兴趣的子系统会调用其在这个事件所注册的函数.
三,实现的大概描述.
定义:
一个Notification Chains由一个notifier_block表示,如下:
struct notifier_block
{
int (*notifier_call)(struct notifier_block *self,unsigned long,void *);
struct notifier_block *next;
int priority;
};
注册:
定义好了以后,可以用notifier_chain_register对其感兴趣的事件注册.
函数原型:
int notifier_chain_register(struct notifier_block **list,struct notifier_block *n)
int notifier_chain_unregister(struct notifier_block **nl,struct notifier_block *n)
注册到list中,按优先级排列,如优先级相同,则按时间排列,先注册的优先级高.
上面两步,是在感兴趣的子系统中发生的.即the notified的一方.
当某个事件发生后,则由notifier_call_chain通知对其感兴趣的子系统.即根据优先级依次调用各个子系统在这个Chain上注册的函数.notifier_call_chain在kernel/sys.c中定义.
函数原型:
int notifier_call_chain(struct notifier_block **n,unsigned long val,void *v)
其中
n:为一函数链表,其链表成员为各子系统注册的notifier_block.
val:唯一定义了某个事件类型.如NETDEV_REGISTER.
这一步发生在事件发生的子系统,即the notifier.
四,在网络子系统中主要的Notification chains:
inetaddr_chain:在本地接口上插入,移除或改变ipv4地址时,发出通知,ipv6对应的为inet6addr_chain.
netdev_chain:把注册的device的status通知给感兴趣的子系统.
五,例子
比如,路由子系统对网络子系统中的ipv4/ipv6地址和device的状态信息感兴趣,则实现大体如下.
static struct notifier_block fib_inetaddr_notifier = {
.notifier_call = fib_inetaddr_event,
};
static struct notifier_block fib_netdev_notifier = {
.notifier_call = fib_netdev_event,
};
这两步分别定义了两个Notification Chains.接下来把它们进行注册.
void __init ip_fib_init(void)
{
...
...
...
register_inetaddr_notifier(&fib_inetaddr_notifier);
register_netdev_notifier(&fib_netdev_notifier);
}
上面的两个为注册函数notifier_chain_register的包裹函数.
ip_fib_init为路由子系统初始化时的部分代码.
希望看到错误的朋友们及时给予指出,不胜感激.