栏目介绍:“玩转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 介绍

69902636111953cfd829bc884dd56527.png

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 来读取、写入该属性。

a7997a9d4b176345d285ba0f61655015.png

同时通过以下概念用于确定 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。这两者的主要区别如下:

  1. Signal 是在总线中进行广播的,而 Method 是发送给特点对象的消息;
  2. Signal 没有返回值,而 Method 可以有返回值(同步的或是异步的),这取决于被调用的方法是否定义了返回值;
  3. 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";

};

44bd8ffd7072a97f28472d5bd84fd8bd.png

31250a294a18fb8af73ce41a9249d260.png

44048f03000bda36dff69004bd55b5ad.png

也可以将 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/


OurBMC
28 声望14 粉丝

OurBMC社区是由基础软硬件企业、第三方机构、高等院校、个人开发者等各方共同参与建设的开源社区,社区基于开放、平等、协作、创新的基本原则,携手社区成员,共同构建自主、先进、软硬一体的BMC技术全栈,共同推...