通知信息由定义于kernel/sys.c中的notifier_call_chain产生,而此函数只是按照优先级次序调用对此链注册的所有回调函数。注意,回调函数是在调用notifier_call_chain 的进程上下文 ontext 中执行的。然而,回调函数也可以实现成把通知信息排进某处的队列,然后唤醒查看此通知信息的进程。
int notifier_call_chain(struct notifier_block **n, unsigned longval, void *v)
{
int ret = NOTIFY_DONE;
struct notifier_block *nb = *n;
while (nb)
{
ret = nb->notifier_call(nb,val, v);
if (ret & NOTIFY_STOP_MASK) {
return ret;
}
nb = nb->next;
}
return ret;
}
以下是三个输入参数的意义
n 通知链
val 事件类型,链本身标识的一组事件,val明确标识一种事件类型。
v 此输入参数可由各种各样的注册的处理函数使用,在不同情况下可以有不同的用途,
例如,当一个新的网络设备在内核注册时,相关的通知信息会使用v以标识net_device数据结构。
notifier_call_chain所调用的回调函数可以返回定义在include/linux/notifier.h中的任何NOTIFY_XXX的值
NOTIFY_OK 通知信息被正确的处理了。
NOTIFY_DONE 通知对信息不感兴趣
NOTIFY_BAD 有事情出错,停止调用此事件的回调函数
NOTIFY_STOP 函数正被调用,然而,不需要进一步调用其他毁掉函数。
NOTIFY_STOP_MASK
次标识由notifier_call_chain检查,以了解是否停止调用回调函数,或者继续调用下去,NOTIFY_BAD和NOTIFY_STOP在其定义中都包括了此标识。
notifier_call_chain 捕获并返回由最后一个调用的回调函数所接受的返回值。无论是否所有回调函数都已经被调用,或者其中之一由于NOTIFY_BAD或者NOTIFY_STOP的返回值中断了循环,都是如此。
在同一时间不同CPU上的相同的通知链有可能同时调用notifier_call_chain 回调函数的责任是在必要的地方处理互斥和串行化。