欄目介紹:“玩轉OurBMC” 是OurBMC社區開創的知識分享類欄目,主要聚焦於社區和BMC全棧技術相關基礎知識的分享,全方位涵蓋了從理論原理到實踐操作的知識傳遞。OurBMC社區將通過 “玩轉OurBMC” 欄目,幫助開發者們深入瞭解到社區文化、理念及特色,增進開發者對BMC全棧技術的理解。
歡迎各位關注 “玩轉OurBMC” 欄目,共同探索OurBMC社區的精彩世界。同時,我們誠摯地邀請各位開發者向 “玩轉OurBMC” 欄目投稿,共同學習進步,將欄目打造成為匯聚智慧、激發創意的知識園地。
在上期內容中,我們深入剖析了OpenBMC完成固件更新的底層機制:無論是BMC自身的單分區或A/B分區更新,還是通過接管SPI、JTAG總線對BIOS、CPLD進行的燒錄,其本質都是直接執行底層的更新命令。然而,在生產環境中,管理員並不會手動執行這些底層命令。取而代之的,是通過Web界面或Redfish接口發起的遠程升級流程。
本期我們將聚焦於phosphor-bmc-code-mgmt 軟件棧,系統性解析從用户發起更新操作到固件最終寫入芯片的完整軟件協作流程,展示 OpenBMC 如何通過分層、事件驅動的架構,將高風險的固件更新流程封裝為安全、可控、可審計的標準化服務。
01核心架構:分層與事件驅動的設計
OpenBMC的固件更新系統採用基於D-Bus通信的鬆耦合分層架構,其設計可明確劃分為以下四個層級:
- 協議與策略層 (bmcweb):負責實現 Redfish 標準接口,將 HTTP 請求轉換為 D-Bus 操作,並決定更新的執行策略(如“立即激活”)。
- 管理層(phosphor-software-manager,內部核心協調組件:ItemUpdater):作為核心守護進程,負責軟件對象的生命週期管理、全局狀態維護以及系統級策略的執行。
- 業務邏輯層 (Activation):作為自主狀態機,封裝了從校驗到寫入的完整業務流程。執行層 (Systemd Services):服務中調用腳本,腳本中封裝與具體固件類型相關的更新命令,是軟件與硬件交互的最終邊界。
一次典型的更新流程,由一系列事件驅動的模塊交互構成。各模塊通過發佈與訂閲D-Bus信號、設置與監聽屬性變化來協同工作,形成一個鬆耦合但銜接緊密的自動化工作流。下圖以 OpenBMC 默認的“上傳後立即激活”策略為例,重點展示控制流與事件觸發關係,而非所有異常分支。
流程關鍵點解析如下:
- 自動激活策略:步驟5和6是默認行為的關鍵。bmcweb 在監聽到新 Activation 對象創建的信號後,其 softwareInterfaceAdded 回調函數會自動調用 activateImage() 來觸發激活。該策略通過事件驅動機制,將用户的單次上傳操作自動銜接至激活流程,實現"上傳-激活"的無縫銜接。
- 架構的靈活性:上述“自動激活”策略並非強制。產品可以通過修改 bmcweb 的回調邏輯,將其變為“手動激活”,即在界面上提供獨立的激活按鈕。這驗證了架構的鬆耦合特性——只要最終通過標準 D-Bus 接口設置 Activation 的屬性,就能驅動整個流程。
- 狀態機的自主性:從步驟7開始,Activation 對象進入完全自主的狀態流轉,它根據需要調用 ItemUpdater 提供的策略工具,並最終驅動 Systemd 服務,是執行業務流程的核心實體。
02模塊深度解析:各司其職的精密協作
bmcweb:Redfish協議實現與更新請求的轉換層
作為 Redfish 協議的服務端實現,bmcweb 是遠程更新流程的入口。它負責接收標準化的HTTP(S)請求,並將其翻譯為對底層 D-Bus 服務的調用。
它提供兩種主要的鏡像上傳接口:
- 簡單上傳:接收二進制鏡像文件(如tar.gz)。
- 多功能上傳:支持在請求中嵌入結構化參數(如目標固件類型 Targets、更新生效時間 ApplyTime)。
其核心策略邏輯體現在 softwareInterfaceAdded 函數中。該函數通過 D-Bus 信號監聽新 Activation 對象的創建,一旦發現,便根據產品預設的策略決定是否立即激活。這正是 “上傳後是否自動激活”這一產品行為的策略執行點,充分體現了 bmcweb 作為協議層與產品策略執行層的角色。
在OurBMC社區中,採用的是HTTP Push,但引入了BMC更新生效時間 ApplyTime參數,使得管理員在網頁更新BMC固件時,可以選擇是否勾選該參數,從而在全部流程以後走完後自動重啓或者下次手動重啓。
ImageManager :鏡像入庫管理
ImageManager 負責將原始固件包轉化為系統可管理的對象。它本身不主動掃描,而是由內置的 Watch 模塊通過 Linux inotify 監聽上傳目錄(/tmp/images)。當文件完全寫入後,Watch 觸發 ImageManager::processImage(),依次執行解包、解析 MANIFEST 文件(獲取固件用途 purpose、版本 version 等)、機型校驗,最終在 D-Bus 上創建一個狀態為 Ready 的 Version 對象,併發出 InterfacesAdded 信號,完成“入庫”。
ItemUpdater:全局狀態管理與策略執行
ItemUpdater 是更新系統的核心管理組件,但它不直接驅動更新流程。它的核心職責包括:
- 對象生命週期管理:監聽 ImageManager 的信號,為每個新 Version 創建並關聯對應的 Activation 對象,維護全局的對象映射表。
- 維護系統狀態關聯:通過 D-Bus Association 機制,管理 functional(當前運行的版本)和 active(下次啓動的版本)等關鍵關係。BMC管理界面基於此來查詢運行中固件和備用固件的狀態。
- 執行系統級策略:它提供的 freeSpace()(清理空間)、savePriority()(保存啓動優先級)等方法,並非更新流程的發起者,而是被 Activation 狀態機在運行過程中回調使用的“策略工具”。
ImageManager 的職責在 Version 對象創建完成後即告結束,它不參與任何激活或刷寫邏輯。
Activation:自主運行的狀態機
每個 Activation 對象都是一個自包含的有限狀態機(Ready -> Activating -> Active/Failed)。它是更新流程的真正執行核心,其設計精髓在於自主性:
- 由屬性觸發:當 bmcweb 或其他授權服務設置 RequestedActivation 屬性後,Activation 狀態機開始按既定邏輯流轉。
- 自主決策與協調:在 Activating 狀態中,它自主進行安全校驗(簽名驗證、最小版本限制 MSL),並根據自身的 purpose 屬性,決定調用哪個底層 systemd 刷寫服務。在此過程中,它會根據需要調用 ItemUpdater 的策略工具。
- 自主完成:監聽 systemd 服務的回調,並自主更新最終狀態,再通知 ItemUpdater 刷新全局關聯。
至此,Activation 的職責邊界結束,後續執行完全由 systemd 服務及其腳本接管。
Systemd 服務:硬件操作的最終執行層
這是與上篇硬件操作對接的最後一環。Activation 通過封裝好的 D-Bus 接口觸發對應的 systemd 服務(如 obmc-flash-bios@.service)。該過程並非直接執行底層刷寫命令,而是由 systemd 單元負責啓動腳本,腳本中再封裝與具體固件類型相關的更新命令,從而實現上層狀態機與具體刷寫實現細節之間的清晰隔離。
03總結
通過對完整流程的剖析,我們可以看到 OpenBMC 固件更新架構呈現出的清晰層次:
這種架構的優勢在於高度的模塊化與解耦,任意一層只要遵循約定接口,便可獨立替換或升級。例如,改變 bmcweb 的信號處理邏輯即可將“自動激活”改為“手動確認”;增加新的 systemd 服務便能支持新的固件類型,而整個核心狀態機和管理框架無需改動。
最終,這一套從用户界面到固件刷寫命令的協同機制,將複雜且高風險的固件更新操作,轉化為一個安全、可觀測、可審計的標準化服務。正是這種模塊化、事件驅動的架構設計,使 OpenBMC 能夠在保證系統安全性的前提下,將固件更新納入大規模數據中心的自動化運維體系之中。