Linux Notification chain学习

深入理解Linux网络技术内幕——Notification内核通知表链 为什么要有内核通知表链:     Linux由多个相互依赖的子系统组成。其中一些子系统可能需要对其他子系统的一些事件感兴趣。这样子系统之间需要一些通信机制来实现这一功能。     在接触Notification Chain之前,我们可能想到通过轮询来实现,事件发生时,子系统轮询所有其他的子系统,看看有没有对这一事件感兴趣的,有没有需要执行的子函数。 If (subsystem_X 阅读详情
概 述
    内核许多子系统之间关联紧密,因此在一个子系统发生或者检测到的事件信息很可能对其他子系统来说也是有价值的。为了满足其他子系统对这些事件信息的需求,即在某个子系统内发生或检测到事件时,其他对此感兴趣的子系统也能知道事件的发生,内核提供了notification chain机制。

注意:notification chain适用于内核子系统之间的信息传递,不涉及用户态。

Notification chain使用发布-订阅模型(publish-and-subscribe model):
    在事件发生时,检测或产生事件的子系统作为主动一方通过通知函数来告知作为被动一方的订阅者(对此事件感兴趣的子系统)。这里有个额外要求,订阅一方要提供callback函数以供发布方调用,当然,提供什么样的callback函数完全由订阅方决定。订阅者必须知道其他子系统提供了哪些事件通知支持,以选择可以订阅的事件通知;当然,订
阅者本身也是一个子系统,因此也具有信息发布功能,因此它也要清楚本系统内哪些事件对其他子系统是有价值的,即有哪些本系统内的事件发生时需要通知订阅者,但是子系统对谁订阅了事件通知以及为什么要订阅一无所知。
从某种意义上来说,notification chain实现了事件信息的共享

struct notifier_block结构

Notification chain由notifier block组成,其结构类型如下(include/linux/notifier.h):
struct notifier_block
{
       int (*notifier_call)(struct notifier_block *self, unsigned long, void *);
       struct notifier_block *next;
       int priority;
};
notifier_call回调函数:self参数通常为notifier_block本身;unsigned long型参数表示发生的事件类型,因为一个chain可能支持多个事件,此参数用来对事件进行区分,在include/linux/notifier.h文件中预订了一些事件常量,例如与netdevice相关的就有多个事件;void *用来存放私有信息,其具体信息取决于特定的事件next指针:用于同一个chain中的notifier_block的链接priority:表示notifier_call函数的优先级,在事件发生时先调用高优先级的回调函数。实际
上在chain中notifier block是根据优先级来进行排队的,高优先级的在前面,这样就可以容易地实现根据优先级来调用回调函数。同优先级的根据加入chain的顺序来排队,最新加入的排在同优先级的最后。通常该字段取缺省值0,这样回调函数就根据加入chain的顺序来调用。该字段的用法可参考函数notifier_chain_register的实现。

实际上notification chain就是一组函数列表。通常notification chain的名字的格式为xxx_chain、xxx_notifier_chain、 xxx_notifier_list,例如reboot_notifier_list。

回调函数notifier_call
int (*notifier_call)(struct notifier_block *self, unsigned long, void *);
前面已经讲过函数参数的含义,注意到该函数的返回值为int类型,这里就来看一下可能的返回
值(include/linux/notifier.h文件中定义了这些常值):
NOTIFY_DONE              0x0000                                                       对该事件不感兴趣(根据unsigned long参数)
NOTIFY_OK                    0x0001                                                       成功响应该事件
NOTIFY_STOP_MASK  0x8000                                                        该回调函数返回后停止处理后续notifier block
NOTIFY_BAD                 (NOTIFY_STOP_MASK|0x0002)             出错,回调函数返回后停止处理后续notifier block
NOTIFY_STOP              (NOTIFY_OK|NOTIFY_STOP_MASK)     成功响应事件,回调函数返回后停止处理后续notifier block

注意,NOTIFY_STOP和NOTIFY_BAD的定义都包含了NOTIFY_STOP_MASK。

并发访问控制在kernel/sys.c文件中定义了对notification chain进行并发访问控制的读写锁notifier_lock。系统中对所有notification chain的并发访问都是由该锁来控制。子系统通常只在boot或者加载module时注册notifier block,即修改notification chain,而大多数时间仅以只读方式来访问,因此一个锁基本不会影响系统性能。

 基 本 API

下面的基本例程位于kernel/sys.c文件中要接收某些事件的通知需要先注册到支持这些事件的notification chain中:
int notifier_chain_register(struct notifier_block **list, struct notifier_block *n)

list为notification chain
n为当前子系统提供的notifier_block,其中指明了回调函数该函数会根据notifier_block的优先级priority将n插入到list中合适位置如果不想接受已订阅事件的通知,则需要取消订阅注册:
int notifier_chain_unregister(struct notifier_block **nl, struct notifier_block *n)
nl为notification chain
n为当前子系统提供的notifier_block当事件发生时,要通知订阅该事件的子系统:
int notifier_call_chain(struct notifier_block **n, unsigned long val, void *v)
n为notification chain
val为事件类型,前面提到过一个chain可能支持多个事件,该参数用来对事件进行区分
v存放特定于事件的信息该函数会遍历chain,对chain中每个notifier block,以参数val和v调用其notifier_call函数,若notifier_call函数返回值中标志了NOTIFY_STOP_MASK(如NOTIFY_BAD、NOTIFY_STOP),则函数停止处理,返回当前notifier block的返回值;否则返回chain中最后一个notifier block的返回值。

注意:多数子系统都定义了这些基本例程的封装函数,因此很少看到对这些函数的直接调用。例如后面的例子中用到的register_reboot_notifier和unregister_reboot_notifier就是简单的封装函数。
 
 简 单 示 例

    在kernel/sys.c文件中定义了一个全局reboot_notifier_list,该chain用来挂接想在系统shutdown时执行的函数,例如进行某种清理工作。前面提到过register_reboot_notifier和unregister_reboot_notifier是对notifier_chain_register和notifier_chain_unregister简单封装,具体请参考实现,在此不再赘述。下面给出一个简单的使用notification chain的例子。该模块向reboot_notifier_list注册了一个函数myreboot,该函数在系统reboot时会简单地打印一些信息(在系统shutdown时也可以)注意到传递给myreboot的event参数值为1,而include/linux/notifier.h文件中定义了与系统关机相关的一组事件常值,而1对应于事件SYS_DOWN。

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/notifier.h>

#include <linux/reboot.h>
static int myreboot(struct notifier_block *self, unsigned long event, void *data)
{
    printk(KERN_ALERT "Just a test! Event code: %li! System reboot now...", event);
    return NOTIFY_OK;
}

static struct notifier_block myreboot_notifier = {
    .notifier_call = myreboot,
};

static int myreboot_init(void)
{
    register_reboot_notifier(&myreboot_notifier);
    return 0;
}

static void myreboot_exit(void)
{
    unregister_reboot_notifier(&myreboot_notifier);
}

module_init(myreboot_init);
module_exit(myreboot_exit);

MODULE_AUTHOR("dj");
MODULE_DESCRIPTION("just a notify test!");
MODULE_LICENSE("Dual BSD/GPL");


关于使用EB tresos出现无法激活的情况解决 我在安装eb studio时就是在激活方面有问题导致无法使用,下面讲解出现了什么问题以及我如何去解除的。EB安装完成时需要激活才能使用的,不然都打开或者建立不了工程,一直都是报的dns服务器错误,好的,那我改dns服务器地址。填写dns服务器地址,也可以换成别的,自己百度一下适合自己的。这是解决方案哈哈哈哈。 阅读详情

相关推荐

手把手教你用ArduPilot搭建低成本无人车(附APM飞控+有刷电调配置清单)

本文提供了一份基于ArduPilot开源平台搭建低成本智能无人车的详细实战指南。核心内容包括APM架构飞控的选型、双向有刷电调的兼容性配置与校准、系统连接逻辑,以及通过Mission Planner地面站进行参数调校和自主导航功能设置的完整流程,帮助爱好者快速实现从手动控制到自主行驶的跨越。

java5的博客 850

Linux内核基础--事件通知链(notifier chain)

内核通知链 1.1. 概述        Linux内核中各个子系统相互依赖,当其中某个子系统状态发生改变时,就必须使用一定的机制告知使用其服务的其他子系统,以便其他子系统采取相应的措施。为满足这样的需求,内核实现了事件通知链机制(notificationchain)。        通知链只能用在各个子系统之间,而不能在内核和用户空间进行事件的通知。组成内核的核心系统代码均位于kernel

每一天为明天@liitokala 2万+

esp32-C3固件烧录用户手册

温馨提示:1.esp32-C3 BOOT脚为GPIO9,需要从芯片小板中焊接引出2.芯片小板中已经预留了所有烧录相关的引脚,大家可以按需焊接引线3.程序下载完,使用串口查看log时,需要使用220v供电使用(请务必准守用电安全)。原因:由于插座中包含继电器,计量计等耗电设备,所以usb转串口提供的3.3V电压和电流可能会出现供电不足,表现为usb转串口与电脑连接断断续续,导致无法查看log。

hbwang的博客 1万+

Linux Kernel -- notify chain

From http://bbs.chinaunix.net/thread-2011776-1-1.html 1.通知链表简介     大多数内核子系统都是相互独立的,因此某个子系统可能对其它子系统产生的事件感兴趣。为了满足这个需求,也即是让某个子系统在发生某个事件时通知其它的子系统,Linux内核提供了通知链的机制。通知链表只能够在内核的子系统之间使用,而不能够在内核与用户空间之间进行

spark_fountain的专栏 1691

DLMS—Cryptographic algorithms—(Green-Book)加密算法

密码学是数学的一个分支,基于数据的转换,并且可以用来提供多种安全服务:保密性、数据完整性、认证、授权和不可否认性。密码学依赖于两个基本组成部分:算法(或密码学方法)和密钥。算法是一个数学函数,而密钥是在转换过程中使用的参数。密码算法和密钥用于对数据应用密码保护(例如,加密数据或生成数字签名),以及移除或检查保护(例如,解密加密的数据或验证数字签名)。密码哈希函数:这类函数不需要密钥(尽管它们可以以使用密钥的模式使用)。哈希函数通常用作算法的一个组成部分,以提供安全服务。见9.2.3.2节。对称密钥算法。

一个bug是bug,多个bug能work 1709

ESP32-CAM与Thonny的完美搭配:从烧录到通信的完整流程

本文详细介绍了如何将ESP32-CAM与Thonny IDE完美结合,从固件烧录到通信测试的完整流程。通过硬件连接、MicroPython固件烧录、Thonny环境配置以及摄像头功能开发等步骤,帮助开发者快速搭建高效的物联网开发环境,实现图像采集与无线通信功能。

tomato的博客 1125

Linux内核通知链技术-notification chain

通知链技术( notification chain )           在 Linux 内核中,各个子系统之间有很强的相互关系,一些被一个子系统生成或者被探测到的事件,很可能是另一个或者多个子系统感兴趣的,也就是说这个事件的获取者必须能够通知所有对该事件感兴趣的子系统,并且还需要这种通知机制具有一定的通用性。基于这些, Linux 内核引入了“通知链”技术。           通知链表是

放牧羊犬的羊咩咩专栏 1041

Sentence-BERT 语义相似度双塔模型

论文介绍 发表:2019,EMNLP 论文题目:《Sentence-BERT:sentence embeddings using siaese BERT-networks》 论文地址:https://arxiv.org/abs/1908.10084 Github:https://github.com/UKPLab/sentence-transformers 适用领域: 句向量生成 语义相似度计算 语义搜索 无监督任务(聚类) 1 概述 在20年之前的各种预训练模型中,比如bert,XLNet,Alb

weiyaner的博客 9193

内核中的notification chain浅析

内核中的很多子系统都是联系很紧密的,因此有可能某个子系统的某些事件,其他多个子系统都很感兴趣,此时就需要用到notification chain. 举个具体的例子,比如说一台主机由于某个网卡的损坏或其他原因不能使用,从而导致连接此网卡的网络不能使用,这个时侯就是notification chain.来通知路由表去除这个网络的路由表项。 notification chain就是一个链表,...

但行好事 莫问前程 178

一文搞懂电流、电压的有效值 RMS

交流电有正半周、负半周,直接平均可能抵消成 0,但负半周一样会发热。这个交流电如果换成直流电,能产生同样发热功率时,对应的直流电压或电流”,电容耐压通常不能按 220V 选,常见会选 400V 或更高余量。所以做硬件时,220VAC 整流滤波后电容上会接近。电压/电流的有效值,也叫。如果它加在电阻上,发热按。

qq_52293640的博客 450

展锐 Android 15 无听筒方案删除配置

【代码】展锐 Android 15 无听筒方案删除配置。

m0_60898338的博客 165

Linux Notification 机制的分析

Linux Notification 机制的分析   1. 基本机制  1)数据结构  struct notifier_block  {  int (*notifier_call)(struct notifier_block *self, unsigned long, void *);  struct notifier_block *next;

随便写写 1482

2023年GESP12月认证C++五级真题解析

例如,如果a=4,那么4是最⼩的幸运数,而1不是,但我们可以连续对1做3次+1操作,使其变为4,所以我们可以说,1幸运化后的结果是 4。【题目大意】给一个完全平方数的标准,推导出哪些是超级幸运数,然后判断N个数字中,哪些是超级幸运数,是的输出“lucky”,不是的输出离该数字最近的比它大的数字。前一个数字,下标是j的数字是偶数,后面的数字下标是j+1的是奇数,按照要求,偶数在奇数的后面,要交换。A函数时间复杂度是O(n/2),B函数算法是O(sqrt(n)),大部分情况后者是优的,值更小。

lan_in的博客 1007

linux notification chains

linux内核由各个不同的子系统构成,比如网络子系统、存储管理子系统等,当然这种设计是为了使内核便于组织,有点类似于 ISO/OSI参考模型。各个子系统相对独立,但它们之间又存在联系。本问将谈谈内核中,各个子系统之间为了实现信息共享而提供的一种机制 ──notification chain。 从字面解释,它是条链表,而且它要完成通知这项工作。如何通知?靠的是在通知链中...

104

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Notification chain in bridge

这也是Bridge的副产品,真是好就没有没弄内核了,忘光了,还好Notification chain是个轻量级的东西。仍是联系Bridge来看,Brdige运用网络子体系的netdev_chain的有关操作也同时学习了。写这篇博客消耗2个小时。 Notification chain,翻译成告诉链,用于内核不一样的子体系之间彼此告诉一些事情,并主动触发告诉链上的函数对其进行处置。内核中注册了数以十

u013882375的专栏 724

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

< Linux Kernel > Notification Chain

A notification chain is simply a list of functions to execute when a given event occurs. Each function lets one other subsystem know about an event that occurred within, or was detected by, the subsy

1301

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Linux notifier chain机制

 内 核许多子系统之间关联紧密,因此在一个子系统发生或者检测到的事件信息很可能对其他子系统来说也是有价值的。为了满足其他子系统对这些事件信息的需求,即 在某个子系统内发生或检测到事件时,其他对此感兴趣的子系统也能知道事件的发生,内核提供了notification chain机制。 注意:notification chain适用于内核子系统之间的信息传递,不涉及用户态。 Notificat

401

Linux内核源码——通知链(notifier chain)

写在前面的话: 刚入手Linux驱动的时候,各种Linux内核的机制是我们需要搬起的一块大砖块。搬砖的过程中,我发现自己不能很好的理解相关的业务驱动的很大的一个原因就是对内核的基本机制掌握不太准确。刚看内核机制代码的时候,需要借助百度上面的各种文档、结合自己的业务代码开展学习。后面有一定基础了,看内核源码、再看业务代码,最后看看网上的博客,效果我自己感觉还可以。通知链(notifier chain...

舞动的心 1150

notification chain and timer interrupt

notification chain Class: notifier_block member: notifier_call: callback function   next:  single list notifier_block --> notifier_block --> ... --> notifier_block --> notifier_block 

ssmale的专栏 1013

Linux内核事件通知链(notifier chain)

Linux内核基础--事件通知链(notifier chain) 简介: 内核许多子系统之间关联紧密,因此在一个子系统发生或者检测到的事件信息很可能对其他子系统来说也是有价值的。为了满足其他子系统对这些事件信息的需求,即在某个子系统内发生或检测到事件时,其他对此感兴趣的子系统也能知道事件的发生,内核提供了notification chain机制。 注意:notification chain适用于内核子系统之间的信息传递,不涉及用户态。 Notification chain使用发布-订阅模型(pub...

深蓝旭的博客 552

linux system 实现,Linux system notification

Notification不像信号一样,他必须注册了以后才可以使用。也不像信号一样有默认的信号处理方法。要使用Notifier我们需要在notifier_chain里边注册notifier_block结构。Notifier系统是有文件kernel/sys.c实现的。该系统导出了三个API:notifier_chain_registernotifier_chain_unregisternotifier...

weixin_32347459的博客 274
上一篇: Linux PCI设备驱动
下一篇: NAPI In Linux Network Device Driver
kernel_learner
博客等级 码龄15年 60粉丝 16原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值