通知鏈
數據結構:
14 struct notifier_block
15 {
16 int (*notifier_call)(struct notifier_block *self, unsigned long, void *);
17 struct notifier_block *next;
18 int priority;
19 };
模型:
通知鏈就是一份簡單的函數列表,當給定的事件發生時予以執行。每個函數都讓另一個子系統知道,調用此函數的子系統內所發生的一個事件或者子系統所偵測到的一個事件。
因此,通知鏈是所謂的發佈-訂閱模型:
1.被通知者就是要求接收某事件的子系統,而且會提供回調函數予以調用。
2.通知者就是感受到一個事件並調用回調函數的子系統。
通知鏈的註冊接口實現:
83 int notifier_chain_register(struct notifier_block **list, struct notifier_block *n)
84 {
85 write_lock(¬ifier_lock);
86 while(*list)
87 {
88 if(n->priority > (*list)->priority)
89 break;
90 list= &((*list)->next);
91 }
92 n->next = *list;
93 *list=n;
94 write_unlock(¬ifier_lock);
95 return 0;
96 }
其中的語句(用的是>而不是>=):
if(n->priority > (*list)->priority)
決定了對於每條鏈條而言,那些notifier_block實體被插入到一個按優先級排序的列表中。相同的優先級的元素則按插入時間排序:新的元素排在尾端。
實現通知:
141 int notifier_call_chain(struct notifier_block **n, unsigned long val, void *v)
142 {
143 int ret=NOTIFY_DONE;
144 struct notifier_block *nb = *n;
145
146 while(nb)
147 {
148 ret=nb->notifier_call(nb,val,v);
149 if(ret&NOTIFY_STOP_MASK)
150 {
151 return ret;
152 }
153 nb=nb->next;
154 }
155 return ret;
156 }
網絡子系統幾條重要的通知鏈:
inetaddr_chain:
發送有關本地接口上的IPv4地址的插入,刪除以及變更的通知信息。
netdev_chain:
發送有關網絡設備註冊狀態的通知信息。
其它:
網絡代碼也可以註冊其他內核組件產生的通知信息。例如,某些NIC設備驅動程序可以用reboot_notifier_list鏈註冊,當系統重新引導時,此鏈會發出警告。