第四章:通知链
内核很多子系统之间具有很强的依赖性,其中一个子系统侦测到的或者产生的事件,其他子系统可能都感兴趣,为了实现这种需求,Linux使用了通知链。通知链只在内核子系统之间使用。
通知链就是一个函数列表,当给定的事件发生时予以执行。对于每条通知链,都有被通知者和通知者,即发布订阅模型。被通知者提供回调函数,通知者监听到某监事后会调用回调函数。任何子系统都可以对该通知链注册一个回调函数来接收通知信息。
通知链列表元素:
struct notifier_block{
int (*notifier_call)(struct notifier_block *self, unsigned long , void *); //要执行的函数
struct notifier_block *next;
int priority; //函数的优先级,但是实际中几乎设置这个值。
};
链注册:
当一个内核组件对给定通知链的事件感兴趣时,可以用通用函数notifier_chain_register来注册。
对通知链的访问受到notifier_lock锁的保护。所有通知链只用一个锁也不会影响性能,因为子系统通常在引导或模块加载时注册其notifier_call函数,之后对列表的访问都是只读的。
链上的通知事件:
通知信息由notifier_call_chain产生(定义于kernel/sys.c),此函数只是按优先级调用通知链上注册的回调函数。回调函数的返回值定义在include/linux/notifier.h中。例如:NOTIFY_OK(通知信息被正确处理了),NOTIFY_DONE(对通知信息不感兴趣),NOTIFY_BAD(出错了,停止调用此事件的回调函数),NOTIFY_STOP(函数被正确调用,但是不再需要进一步调用其他回调函数),NOTIFY_STOO_MASK(此标识由notifier_call_chain检查,以决定是否了停止调用回调函数)。
注意,在同一时间不同cpu上的相同通知链可能同时调用notifier_call_chain,回调函数需要负责在必要的地方处理互斥和串行化。
网络子系统的通知链:
和网络有关的通知链:
inetaddr_chain:发送有关本地接口上的ipv4地址的插入,删除和变更通知信息。第二十三章会数描述这类信息何时产生。
netdev_chain:发送有关网络设备注册状态的通知信息。第八章会描述合适产生这类信息。