概念
如果你所知道的作業系統在進入到application layer開啟的的一支程式是init.d, 然後你會看到rcx等等的目錄伴隨著數字編號一個一個把應用程式開起來的這種方式, 那表示你玩電腦的年份跟我是差不多了!
新世代的同學應該剛開始用Ubuntu或者Centos就已經是systemd了!他是誰?**Systemd是「系統與服務管理器」, 負責系統開機後的初始化、服務啟動、監控、記錄, 以及系統關閉等管理任務,徹底取代了舊有的 SysVInit。**他跟舊時代的SysVInit最顯著的差異就是他可以平行開啟好多個service. 這樣彼此沒有相依性的service就可以同時被啟動, 縮短開機的時間。有相依性的程式也會因為service的unit檔案設定, 讓Systemd確切知道哪些process程式彼此有衝突不能同時開啟, 哪些程式在開啟的時候彼此有順序關係, 又有哪些程式被關閉的時候也要同時關閉相關的服務避免無用的service空轉。
以上, 只是簡而言之, 讓你對systemd在系統中扮演的角色, 有些概念。如果你真的真的想知道很多的細節, 請看官方網站:https://www.freedesktop.org/wiki/Software/systemd/ 不過你放心, 如果你是OpenBMC的工程師, 你幾乎不會也不太可能改到這部分的程式碼, 如果你會….而且還改很大, 那就嚴重了!所以不太需要花時間去看systemd的cod, 但如果你是opensource 迷, 你可以去看看無仿!那你需要會的是什麼?我幹嘛要知道systemd? (請往下看)
如果你有Linux的環境, 你們可以安裝並執行看看 “systemd-analyze plot >bootup.svg"這個command, 他可以把你系統從kernel開進每一個service的時間順序, 畫成向量圖給你看, 你會看到有些平行啟動, 有些有前後關係, 然後各個service花了多少時間開啟, 於是整體開機時間是多久! (我碰過的幾個大客戶, 最後PVT或者MP的階段都會很要求開機時間要在某個時間之內喔!) 這個command還有很多不同的sub-command可以看到不同的結果, 詳情請詳閱公開說明書:https://www.freedesktop.org/software/systemd/man/latest/systemd-analyze.html
現在, 你應該可以理解systemd, services之間的關係了!那麼service和我們上週討論到的Process又有什麼不同呢?**service是有特定管理規範和功能目的process。**很多簡體書上面會說service是常駐程式, 沒錯常駐程式是其中之一但不限定, 因為service的unit file裡面可以定義這支程式被啟動與停止的時間點或條件。Process只是統稱所有正在執行中的程式。既然如此, 這個unit file就很重要了, 他決定了這個service如何被systemd管理。這就是OpenBMC的工程師經常要做的事情了!
假設你的系統需要一支風扇控制的service(當然他必須是常駐程式, 他如果開機只執行一次, 設定完轉速就把自己殺了, 機器很快就會燒掉, 然後你也很快會被火掉…) , 你的系統也需要有一個Sensor Monitoring的service (當然他也必須一直在執行, 不然他如果不報告溫度給風扇控制的service, 風扇本人會直接不知道怎麼控制強制全轉, 你還沒被火掉, 你就會先在實驗室裡面被你機器的風扇吵死 RIP…)。講到這裡, 你發現了嗎? 這兩支程式有可能有先後順序的關係 (在業界的朋友請根據SPEC決定), 我們這裡假設Fan control servce要比Sensor monitoring service晚起來, 確保sensor都已經有讀到值, 風扇才開始根據溫度值與控制演算法來決定轉速。這個先後順序的關係就是設定在unit file裡面的 “After= “ or “Before=”. 當然裡面可以設定的東西可多了, 網路上能有正確答案的東西…我就不浪費時間翻譯成中文, 詳情請看:https://www.freedesktop.org/software/systemd/man/latest/systemd.service.html
PS. 如果現階段你覺得看英文文章太過困難, 在韌體領域我不准你不知道「鳥哥」!https://linux.vbird.org/linux_basic_train/centos7/unit13.php
(特別是如果你看我寫的東西, 覺得完全不能理解, 有一種可能是我真的寫得太爛, 另一種可能是你的背景知識還不夠, 但不管是哪一種, 拜託你們都去看鳥哥!)
實作
回來了嗎?好怕你們連結點出去之後, 點著點著就點到IG還是Tiktok, 然後就沒有回來了!
現在我們來做一些實驗, 你只要先準備一個小腳本hello-world.sh,大概長這樣: (拜託你要拿去面試的不要長這麽陽春! :)哈哈哈哈!)
#!/bin/bash
while true; do
echo "hello systemd!"
sleep 5
done
記得給它執行權限:
chmod +x ~/hello-world.sh
然後,unit file 長怎麼樣?來,下面給你一個範本。
範例 (hello-world.service)
[Unit]
Description=Hello World Service
After=network.target
[Service]
ExecStart=/home/[...你的真實路徑...]/hello-world.sh
Restart=always
[Install]
WantedBy=multi-user.target
這個 hello-world.service 的 systemd unit file 定義了一個簡單的系統服務, 用來執行一個我們自己寫的 hello-world.sh 腳本。整個檔案分為三個主要區塊, 分別是 [Unit]、[Service] 和 **[Install] ,**它們分別負責描述服務的基礎資訊、執行細節以及安裝時的整合行為。
首先,在 [Unit] 區塊裡,我們有一行 Description=Hello World Service,這是對這個服務的一段簡短描述,方便系統管理者理解這個服務的用途。接著 After=network.target 這一行則是設定服務啟動的時機條件,它的意思是「這個服務會在網路服務啟動完成之後才開始執行」,這樣可以確保若有依賴網路的需求,系統已經準備好相關資源。
接著是 [Service] 區塊,這是這個 unit file 的核心部分。其中的 ExecStart=/home/..../hello-world.sh 指定了 systemd 啟動這項服務時,要執行的程式完整路徑。也就是說,當你用 systemctl start hello-world.service 啟動服務時,systemd 自動替你呼叫這支腳本,並由這支腳本執行你想要完成的工作。這個腳本可以是任何可執行檔,包括 shell script、Python 程式等,只要它有可執行權限並能在該系統環境運作即可。
同時,這個區塊裡的 Restart=always 設定非常重要,它代表系統會保證這個服務持續運行。如果該服務因為任何原因崩潰或意外停止(例如程式出錯、自行退出或被使用者強制殺掉),systemd 都會立刻幫你重新啟動它。這讓服務擁有較高的穩定性與可用性,適合長時間需要運行、且不希望中斷的關鍵程式。
最後的 [Install] 區塊則決定了這個服務如何與系統整合,特別是當你執行 systemctl enable hello-world.service 這類指令時會用到。裡面的 WantedBy=multi-user.target 表示這個服務會被加入到 multi-user.target(類似傳統 Linux runlevel 3)的啟動序列裡。換句話說,當 Linux 系統進入多用戶模式(一般伺服器運轉階段)時,這個服務就會自動啟動,而不需要使用者手動干預。
總結來說,這份 unit file 讓我們透過 systemd 管理一個簡單的腳本服務,從設定啟動條件(網路必須先啟動)、指定啟動內容(執行 hello-world.sh)、到確保服務在失敗時自動重啟,再到整合系統開機流程中自動啟動,整個架構清楚且功能完善。透過此方法,我們可以快速將任何程式變成一個可控的背景服務,並利用 systemd 提供的可靠機制來穩定運行。
<aside> 💡
實作任務一:Restart復活之術
- 先啟動服務,然後:
bash ps aux | grep hello-world.sh *# 假設找到 PID 12345* kill 12345
幾秒後用 ps 查查,欸!又出現新的 PID,馬上復活了!
實作任務二:OpenBMC中的Unit File在哪裏?
- 到 OpenBMC底下找找有沒有看到service unit file, 你使用了什麼方法找到他們呢? (https://github.com/openbmc/openbmc)
- 你能不能拿其中一個你找到的service unit file, 然後解釋他的設定代表什麼意思呢? (你可以把它複製下來, 寫上註解, 或著拿我們的範例來改成像他一樣的設定, 然後確認你以為的功能和實際的行為是否相符?) </aside>
下一期, 我們接著來講 unit file在OpenBMC當中被使用的最精彩的 Power Control ➡️
















