内核中的很多子系统都是联系很紧密的,因此有可能某个子系统的某些事件,其他多个子系统都很感兴趣,此时就需要用到notification chain.

举个具体的例子,比如说一台主机由于某个网卡的损坏或其他原因不能使用,从而导致连接此网卡的网络不能使用,这个时侯就是notification chain.来通知路由表去除这个网络的路由表项。

notification chain就是一个链表,包括了所有当某个事件发生时当前子系统所需要执行的函数,而这些函数是被其他的子系统注册到nc(下面notification chain就简称nc了)里。

下面来看源码.

首先来看nc的数据结构(include/linux/notifier.h):

notifier_call也就是将会执行的回调函数,next指向下一个nc节点,priority是优先级,优先级高的节点会先执行。

Java代码  
  1. struct notifier_block {
  2. int (*notifier_call)(struct notifier_block *, unsigned long, void *);
  3. struct notifier_block *next;
  4. int priority;
  5. };

注册到一个nc上: 
这里我们使用notifier_chain_register来实现注册。

这里遍历nc然后按照优先级来插入相应的位置(也就是插入到优先级比自己小的之前)

Java代码  
  1. static int notifier_chain_register(struct notifier_block **nl,
  2. struct notifier_block *n)
  3. {
  4. ///开始遍历
  5. while ((*nl) != NULL) {
  6. ///比较优先级
  7. if (n->priority > (*nl)->priority)
  8. break;
  9. nl = &((*nl)->next);
  10. }
  11. ///链表插入的操作
  12. n->next = *nl;
  13. rcu_assign_pointer(*nl, n);
  14. return 0;
  15. }

在nc上唤醒一个事件,也就是执行相对应的函数:

notifier_call_chain方法.

第一个参数为nc,第二个参数为事件类型,第三个参数为传给回调函数的参数,第三个和第四个参数分别为nc已经遍历的数目。

事件类型值可以看notifier.h中定义的。 
流程很简单就是遍历此nc,然后调用相应的回调函数。

Java代码  
  1. static int __kprobes notifier_call_chain(struct notifier_block **nl,
  2. unsigned long val, void *v,
  3. int nr_to_call, int *nr_calls)
  4. {
  5. int ret = NOTIFY_DONE;
  6. struct notifier_block *nb, *next_nb;
  7. nb = rcu_dereference(*nl);
  8. while (nb && nr_to_call) {
  9. next_nb = rcu_dereference(nb->next);
  10. ///基本上所有的回调函数里面都会使用switch语句,通过判断不同的event值来执行不同的操作。
  11. ret = nb->notifier_call(nb, val, v);
  12. if (nr_calls)
  13. (*nr_calls)++;
  14. if ((ret & NOTIFY_STOP_MASK) == NOTIFY_STOP_MASK)
  15. break;
  16. nb = next_nb;
  17. nr_to_call--;
  18. }
  19. ///返回值为最后一个回调函数执行的返回值
  20. return ret;
  21. }

这里还要注意下,一般上来说内核都会对上面的注册和执行函数进行包装。

内核中至少有10种不同的nc,比如inetaddr_chain就是本地网络地址的改变等等事件所触发。

内核中的notification chain浅析相关推荐

  1. linux内核定时器死机,浅析linux内核中timer定时器的生成和sofirq软中断调用流程

    浅析linux内核中timer定时器的生成和sofirq软中断调用流程 mod_timer添加的定时器timer在内核的软中断中发生调用,__run_timers会spin_lock_irq(& ...

  2. Linux内核通知链(notifier chain)

    1.概述 Linux内核中各个子系统相互依赖,当其中某个子系统状态发生改变时,就必须使用一定的机制告知使用其服务的其他子系统,以便其他子系统采取相应的措施.为满足这样的需求,内核实现了事件通知链机制( ...

  3. Linux内核中流量控制(16)

    本文档的Copyleft归yfydz所有,使用GPL发布,可以自由拷贝,转载,转载时请保持文档的完整性,严禁用于任何商业用途. msn: yfydz_no1@hotmail.com 来源:http:/ ...

  4. 互联网络层的内核实现[内核中的路由机制]

    内核中网络层3条线: A 主机到网络->互联网络层-->传输层: ip_rcv()   -->NF_INET_PRE_ROUTING   -->ip_rcv_finish    ...

  5. Linux内核中的同步原语:自旋锁,信号量,互斥锁,读写信号量,顺序锁

    Linux内核中的同步原语 自旋锁,信号量,互斥锁,读写信号量,顺序锁 rtoax 2021年3月 在英文原文基础上,针对中文译文增加5.10.13内核源码相关内容. 1. Linux 内核中的同步原 ...

  6. Linux内核中的IPSEC实现(1)

    本文档的Copyleft归yfydz所有,使用GPL发布,可以自由拷贝,转载,转载时请保持文档的完整性,严禁用于任何商业用途. msn: yfydz_no1@hotmail.com 来源:http:/ ...

  7. linux内核中的文件描述符(三)--fd的回收

    linux内核中的文件描述符(三)--fd的回收 Kernel version:2.6.14 CPU architecture:ARM920T Author:ce123(http://blog.csd ...

  8. linux cache控制 内核,Linux内核中cache的实现

    本文档的Copyleft归yfydz所有,使用GPL发布,可以自由拷贝,转载,转载时请保持文档的完整性, 1. 前言 kmem_cache是Linux内核提供的快速内存缓冲接口,这些内存块要求是大小相 ...

  9. Spring Security入门到实践(一)HTTP Basic在Spring Security中的应用原理浅析

    一.Spring Security简介 打开Spring Security的官网,从其首页的预览上就可以看见如下文字: Spring Security is a powerful and highly ...

最新文章

  1. AI、ML论文网站、如何阅读论文?
  2. 同时获取同一等级下多个class值的节点的方法
  3. Photoshop的基本操作
  4. CSS之容器按比例缩放
  5. Nginx 简介和使用
  6. 读书笔记: 博弈论导论 - 05 - 完整信息的静态博弈 纳什均衡
  7. PMP资料,考过的学员整理分享
  8. 宿命论與自由意志 ---霍金
  9. specular图使用方法_CSharpGL(54)用基于图像的光照(IBL)来计算PBR的Specular部分
  10. 大数据本科毕业论文应该怎么写?
  11. 周超臣:支付宝的套路是我走过最长的路
  12. 获取SYSTEM Shell:Citrix Workspace软件命名管道校验客户端漏洞分析
  13. Java开源工具库使用之Apache commons-lang3
  14. 利用智能算法优化参数的自适应变分模态分解,VMD实现混合储能系统的分频
  15. python获取网页图片_python抓取网页中的图片示例
  16. 每节课都是一个项目 手把手用STM32打造联网气象站-4-STM32基础三件套-TIM定时器和SYSTICK初始化
  17. gc方法写法_云风的 BLOG
  18. beatbox最终版本
  19. 里约奥运|高科技助力 本届奥运会有待打破更多记录
  20. 电影院场次管理java_电影放映时间选择_09-JAVASE项目实战-电影管理系统_Java视频-51CTO学院...

热门文章

  1. 合肥师范学院计算机与技术,合肥师范学院计算机科学与技术系JAVA复习提纲
  2. html中单选框重置,HTML表单和组件
  3. python 使用tsfresh进行时间序列特征提取
  4. 解决新安装的Ubuntu18.04没有网络连接的问题
  5. django表单提交案例
  6. C#巧妙实现服务器端应用程序和asp网页交互
  7. Python基础1(2017-07-16)
  8. MySQL筛选重复数据
  9. 小程序--计算正负数个数
  10. 《神经网络和深度学习》系列文章五:用简单的网络结构解决手写数字识别