栏目介绍:“玩转OurBMC”是OurBMC社区开创的知识分享类栏目,主要聚焦于社区和BMC全栈技术相关基础知识的分享,全方位涵盖了从理论原理到实践操作的知识传递。OurBMC社区将通过“玩转OurBMC”栏目,帮助开发者们深入了解到社区文化、理念及特色,增进开发者对BMC全栈技术的理解。
欢迎各位关注“玩转OurBMC”栏目,共同探索OurBMC社区的精彩世界。同时,我们诚挚地邀请各位开发者向“玩转OurBMC”栏目投稿,共同学习进步,将栏目打造成为汇聚智慧、激发创意的知识园地。
在 OpenBMC 中,进程间通信(IPC)是一个重要的组成部分,而 D-Bus 作为一种轻量级且高效的 IPC 机制,被广泛采用。本期内容将聚焦于这张通信网的编织者——D-Bus。首先,对 D-Bus 提供的接口和主要概念进行介绍。然后,结合 OpenBMC 社区应用对 D-Bus 进行更深入的剖析。通过对 D-Bus 的解析,希望能够帮助读者更好地理解和运用这一强大的 IPC 机制,以提升系统的整体性能和稳定性。
D-bus 介绍
D-Bus(Desktop Bus)是一个高级的进程间通信(IPC)机制,广泛应用于 Linux 操作系统中。它允许软件应用程序进行同步或异步通信,发送和接收跨进程的消息,相较于传统意义上的 IPC 机制(例如 PIPE/FIFO/Socket/共享内存/SysvIpc ),D-Bus 提供了一个低延迟、低开销和高可用性的 IPC 机制,隐藏了底层 IPC 机制的复杂性,为开发者提供了更加高级和易用的接口:
- 方法调用(Method Call):
用来实现跨进程的方法(函数)调用,配合代码生成工具,可以做到让进程间的函数调用和普通的函数调用几乎无区别。
- 信号(Signal):
发布订阅(Pub-Sub)模式的通信机制,发送进程注册并发送(广播)信号,接收进程订阅自己感兴趣的信号。
- 属性(Property):
可类比 C++ 类中成员变量的 Getter-Setter,如果进程 A 提供了一个属性,那么其他进程可以通过 D-Bus 来读取、写入该属性。
同时通过以下概念用于确定 D-Bus 调用具体的对象:
- 总线名称(Bus Name):
服务注册到总线的名称,是每个应用程序(或是通信对象)用来标识自己的唯一名称。这个名称对于 D-Bus 系统来说是全局唯一的,因此可以被其他应用程序用来引用和通信。可以当成是 “IP” 地址来理解,类比为 lib 库的名字。
- 对象路径(Object Path):
用于在 D-Bus 上标识特定应用程序或服务中的对象,它类似于文件系统中的路径,但用于 D-Bus 对象而不是文件。对象路径通常遵循一种层次结构,以便于组织和管理。对象路径的命名规则是 /com/example/MusicPlayer1,表示一个名为 “MusicPlayer1” 的应用程序中的根对象。可以类比为 C++ 中同类(class)不同的对象(object)。
- 接口(Interface):
接口定义了 D-Bus 对象提供的功能,包含方法、属性和信号。接口可以被多个对象实现,并且可以被多个应用程序或服务使用。接口类似于 C++ 中的类或者头文件,它描述了对象的行为和可访问的属性。在 D-Bus 中,一个对象可以实现多个接口,每个接口都包含了一组方法、属性和信号。这些方法和属性可以被其他应用程序或服务通过 D-Bus 调用或访问。
D-bus 实际应用
在 OpenBMC 中,D-Bus 被广泛应用于传感器数据收集、硬件故障管理、远程管理接口等场景。它使得不同组件之间的通信变得简单而高效,为系统的稳定运行提供了有力保障。
下面结合 OpenBMC 社区的实际应用来对 D-Bus 进行更深入的剖析。
- D-Bus工具(busctl)
busctl 是 systemd 提供的用于与 D-Bus 系统总线进行交互的命令行工具。通过 busctl 工具输入 bus 名称(bus name)、对象路径(object path)、接口(interface)等参数来获取 D-Bus 对象所提供的详细信息,包括属性(property)、信号(signal)、方法调用(method)等,使用户对 D-Bus 中各种抽象的概念有更直观的认识。
- 属性(Property)
以 adcsensor 程序为例,该进程通过配置文件识别芯片 SOC 将内核提供的 ADC 的原始值转换为电压,并会根据配置文件描述的传感器以 D-Bus 的形式显示出来:
总线名:xyz.openbmc_project.ADCSensor
对象路径:/xyz/openbmc_project/sensors/voltage/xxx,根据板级配置文件生成若干对象路径用于表示电压传感器。
接口1:xyz.openbmc_project.Sensor.Value
该接口提供的属性:
MaxValue (double类型):传感器最大值
MinValue (double类型):传感器最小值
Unit (字符串类型):值的类型,伏特
Value (double类型):传感器当前值
接口2:xyz.openbmc_project.Sensor.Threshold.Critical
该接口提供的属性:
CriticalAlarmHigh (bool类型):是否达到高严重的阈值
CriticalAlarmLow (bool类型):是否达到低严重的阈值
CriticalHigh (double类型):严重高阈值
CriticalLow (double类型):严重低阈值
接口3:xyz.openbmc_project.Sensor.Threshold. Warning
该接口提供的属性:
WarningAlarmHigh (bool类型):是否达到高警告的阈值
WarningAlarmLow (bool类型):是否达到低警告的阈值
WarningHigh (double类型):警告高阈值
WarningLow (double类型):警告低阈值
至此其他应用模块可以通过这些抽象出来的 D-Bus 属性实现相关功能。如 IPMI 传感器模块可动态生成 IPMI SDR,IPMI SEL 模块监控属性生成告警日志,Redfish 模块生成传感器 redfish 接口等。
- 信号(Signal)
所有 D-Bus 对象都会有 org.freedesktop.DBus.Properties 接口和其下的 PropertiesChanged 信号。这个对象下所有接口的任一属性发生变化后就会触发该信号发送到 D-Bus 上,该信号内容格式为 sa{sv}as,对应的含义为:
STRING: 接口名
ARRAY of DICT_ENTRY<STRING,VARIANT> 属性名和改变的值(多个)
ARRAY<STRING> 值改变的属性名,但改变的值未知。(多个)
再加上所有的 D-Bus 消息都会包含 bus name 和 object path,其他进程可以自由选择这些参数进行监控,以捕获关心的变量。
- 方法(Method)
D-Bus 总线只有两种类型的消息,一种是 Signal,一种是 Method。这两者的主要区别如下:
- Signal 是在总线中进行广播的,而 Method 是发送给特点对象的消息;
- Signal 没有返回值,而 Method 可以有返回值(同步的或是异步的),这取决于被调用的方法是否定义了返回值;
- Signal 主要用于事件通知,而 Method 通常用于请求数据或执行操作;
读写 Property 本质上也是调用 Dbus 标准接口 org.freedesktop.DBus.Properties 中的 Get、Set 的 Method。
以创建网卡 IP 地址的 method 为例:
Bus Name:xyz.openbmc_project.Network
Object:/xyz/openbmc_project/network/<network_name>
Interface:xyz.openbmc_project.Network.IP.Create
Method:IP ssys:“<IP Protocol>:ipv6\ipv4”“<IP Address>” “<Netmask Prefix>” “<Network Gateway>”,return “New IP Object Path”
使用busctl工具创建IP:
busctl --verbose call xyz.openbmc_project.Network /xyz/openbmc_project/network/eth0 xyz.openbmc_project.Network.IP.Create IP ssys "xyz.openbmc_project.Network.IP.Protocol.IPv4" "10.10.10.192" 24 "10.10.10.1"
返回值:
MESSAGE "o" {
OBJECT_PATH "/xyz/openbmc_project/network/eth0/_310_2e10_2e10_2e192_2f24";
};
也可以将 xyz.openbmc_project.Network.IP.Create 接口的 IP 方法看成一个输入 IP 信息,实现给网卡新增 IP 地址,并返回新生成 object path 的函数:
string IP(string protocol,string ip_addr,unsigned char netmask,string gateway)
总之,D-Bus 是 OpenBMC 中实现进程间通信的重要机制之一。它通过提供可靠且灵活的消息总线系统,使不同进程和应用程序之间能够相互通信。它简化了进程间通信的复杂性,提供了许多有用的功能,从而提高 OpenBMC 系统的可靠性和可维护性。
欢迎大家关注OurBMC社区,了解更多BMC技术干货。
OurBMC社区官方网站:
https://www.ourbmc.cn/
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。