2022年4月17日 星期日

openBMC 的 D-Bus & Object Mapper

簡單紀錄一下我對openbmc dbus 相關repository 的理解

OpenBMC 和 D-Bus 有關的 repository 大概有以下幾個

  • systemd/sd-bus
  • sdbusplus & sdbus++
  • the object mapper
  • phosphor-dbus-interfaces

OpenBMC 和 D-Bus 的關係

OpenBMC - Wikipedia中有一段描述

    OpenBMC uses D-Bus as an inter-process communication (IPC).
    (OpenBMC 使用 D-Bus 作為進程間通信 (IPC))

下面的圖是我簡單畫的openBMC架構,在user space 中是由很多process (daemon)所組成的

例如sensor monitor daemon會去定期讀取sensor value,使用者可以透過 redfish 來獲取讀值,那redfish daemon 要去哪裡獲取讀值呢?OpenBMC 給的答案是 "D-Bus"

只要所有資料都放到D-Bus上,這樣這些 daemon 就能共享資料了,那dbus 的協議和操作方法可以看官方建議的 The new sd-bus API of systemd (0pointer.net) 這篇文章

操作D-Bus可以先認識幾個名詞

Service - A daemon attached to the dbus and providing objects. (附加到 dbus 並提供對象的守護進程。)

root@romulus:~# busctl
xyz.openbmc_project.State.BMC

Object Paths – A tree, like a file system, of paths to objects.(對象路徑的樹,如文件系統)

root@romulus:~# busctl  tree xyz.openbmc_project.State.BMC
└─/xyz
  └─/xyz/openbmc_project
    └─/xyz/openbmc_project/state
      └─/xyz/openbmc_project/state/bmc0

Interface – The 'class' of an object. Objects support multiple inheritance.(對象的“ class ”。 對象支持多重繼承) (也有人稱作a set of method and signal)

  • Property – Store values. Some can be written to (存儲值。有些可以改寫)
  • Method – Make method calls.(進行方法調用)
  • Signal – Inform other process about an event. (將事件通知其他進程)

root@romulus:~# busctl introspect xyz.openbmc_project.State.BMC /xyz/openbmc_project/state/bmc0
NAME                                TYPE			SIGNATURE       RESULT/VALUE                                 FLAGS
xyz.openbmc_project.State.BMC       interface		-				-                                            -
.CurrentBMCState                    property        s               "xyz.openbmc_project.State.BMC.BMCState…     emits-change writable
.LastRebootTime                     property        t               1619401752000                                emits-change writable
.RequestedBMCTransition             property		s               "xyz.openbmc_project.State.BMC.Transiti…     emits-change writable

例如PSUSensor 註冊了一個Service "xyz.openbmc_project.PSUSensor"

產生一個object "/xyz/openbmc_project/sensors/power/PSU_Output_Voltage"

並且assign的其中一個interface是 "xyz.openbmc_project.Sensor.Value" 這樣他應該會繼承四個property (phosphor-dbus-interfaces/Value.interface.yaml at master · openbmc/phosphor-dbus-interfaces · GitHub),並且把讀到的PSU_Output_Voltage放到 "Value" 中

可以透過指令get-property SERVICE OBJECT INTERFACE PROPERTY...來獲得PSU_Output_Voltage

~# busctl get-property xyz.openbmc_project.PSUSensor    //service
/xyz/openbmc_project/sensors/power/PSU_Output_Voltage   //object
xyz.openbmc_project.Sensor.Value                        //interface
Value                                                   //property

是的,所以IPMI 和 redfish只要到指定路徑就可以拿到想要的 sensor value,或是系統資料


systemd/sd-bus

systemd/sd-bus.h at main · systemd/systemd · GitHub

sd-bus 是最小的 D-Bus IPC C library,和systemd 一起released 


sdbusplus & sdbus++

sdbusplus/README.md at master · openbmc/sdbusplus · GitHub

sdbusplus 是用於與 D-Bus 交互的 C++ library (libsdbusplus),構建在 systemd 的 sd-bus library之上,這樣C++可以直接呼叫API,更方便好用

另外sdbus++是一個生成 C++ 綁定的工具,以簡化基於 D-Bus 的應用程序的開發,搭配phosphor-dbus-interfaces GitHub - openbmc/phosphor-dbus-interfaces: YAML descriptors of standard dbus interfaces 使用。


The Object Mapper

GitHub - openbmc/phosphor-objmgr: Phosphor Object Manager

docs/object-mapper.md at master · openbmc/docs · GitHub

這個很像BMC內部小型的database,主要兩個功能是

  • Methods - 提供 D-Bus 發現相關功能。
  • Associations - 將兩個不同的對象相互關聯。

Methods 

前面有提到OpenBMC是由很多process所組成的,我們可以任意替換成自己開發的 psusensor daemon 或是 biosconfig daemon,但這樣redfish 怎麼知道她想要的值是哪些services所提供的?

因此object mapper會監測dbus上的動作,例如新增/刪除 interface、object,或是 service rename等行為,redfish 可以透過 object mapper 查找想要的資訊,例如

GetObject : 查找實現特定object path的service及其interface。


GetSubTree: 在指定的subtree中查找實現某個interface的object、service和interface。

例如底下範例就是查找有"xyz.openbmc_project.Sensor.Threshold.Warning"這個interface的object、service和interface


GetSubTreePaths: 這與 GetSubTree 相同,但只返回object path


GetAncestors: 查找實現特定interface的object的所有祖先。


以上這些method都是提供查找相對應的service和interface或是object path,但如果需要讀值,還是要透過dbus api去讀取,也是帶入"service, object path, interface, property"


Associations 

關聯,用一個指針指向相關聯的物件,例如

    一條sel, 可能是關於某個sensor的出了問題

    一個sensor ,可能是長在某一塊板子上的

創建一個關聯很簡單,只要在object pathA中加入"xyz.openbmc_project.Association.Definitions"這個interface,並且新增一個tuple,[forward, reverse, object path]

這樣就能在object mapper 中產生一個Association


再來個例子,大概是這樣的操作,所以我們就能知道每塊板子上有哪些sensor

先這樣,之後有機會再補


沒有留言:

張貼留言

注意:只有此網誌的成員可以留言。