一條 Dbus 消息觸發多個 systemd 服務
啟動 dbus 信號時如何觸發多個 systemd 服務。
我試圖
org.freedesktop.hostname1
通過創建如下服務來做到這一點:[Unit] Description=Set host name [Service] ExecStart=/home/administrator/set-hostname BusName=org.freedesktop.hostname1
啟用它並執行
netplan apply
腳本後不會執行。每。
我假設通過“觸發”服務,您希望新服務開始執行(這是 systemd 可以做的事情),而不是讓已經執行的服務做某事(這完全超出了 init 系統的範圍)。
D-Bus 基礎知識
每個 D-Bus 消息都有一個“接收者”欄位(可以是眾所周知的名稱,例如 ,或
org.example
唯一名稱,例如:1.234
,或廣播地址)。D-Bus信號(用於發布已經發生的事件)通常廣播到整個匯流排,因此它們不會導致任何服務啟動。如果您正在考慮發送到特定服務的單播消息,這些消息通常是方法呼叫,而不是信號。
D-Bus 服務自動啟動
匯流排守護程序將在以下情況下自動啟動服務:
- 有一條消息發送到特定的知名名稱,
- 並且該知名服務目前沒有在公共汽車上“聲明”,
- 並且該眾所周知的名稱在
/usr/share/dbus-1/system-services/
.從第 2 點開始值得注意的是,只有一個服務可以聲明一個眾所周知的名稱並接收發往該名稱的消息。只要真正的 systemd-hostnamed 已經在執行並且已經聲明
org.freedesktop.hostname1
,它就會收到這些消息——其他程序不能這樣做。第 2 點也意味著對於服務目前持有的名稱*不會發生自動啟動。*消息將簡單地傳遞到該已經執行的服務。
在第 3 點,文件名必須與眾所周知的匯流排名*完全匹配;*即,您不能讓多個服務以相同的名稱競爭自動啟動。因此,就 dbus-daemon 而言,每條消息最多只能啟動一個服務。
通過 systemd 自動啟動
如果 D-Bus .service 文件(在 /usr/share/dbus-1/…/ 下)包含一個
SystemdService=
選項,dbus-daemon 將嘗試通過 systemd 啟動該服務,而不是傳統上分叉/執行 Exec= 中列出的任何內容。(通常 systemd 服務會安裝一個名為 Alias 的別名——這只是一個允許 systemctl 啟用/禁用的約定,除此之外,語法沒有特殊含義。)
dbus-*[busname]*.service
由於 systemd 服務可以具有依賴項,因此您現在可以解決“每條消息只能啟動一個服務”的限制:直接啟動的服務可以將其他服務作為依賴項拉入。然而,前面解釋的一切仍然適用——一旦“真正的”服務執行,更多的消息將直接到達它並且不會觸發自動啟動。
結論
似乎您正在嘗試完全避免 systemd-hostnamed,並且每當 netplan 呼叫 hostnamed 的
SetHostname()
方法時,您都希望自己的程序接收它。這對於簡單的 shell 腳本是不可能的。您無法通過標準輸入、環境變數或命令行參數接收 D-Bus 消息。您的腳本只會知道它是出於某種原因啟動的,但它不知道它應該做什麼。
但一般來說這是可能的——只要您使用具有 D-Bus 模組的程式語言。您“只”需要連接到系統匯流排、聲明名稱、接收消息並以與 systemd-hostnamed 相同的方式處理它們。許多 dbus 模組都帶有“骨架 D-Bus 服務”範例。
(事實上,已經有各種 systemd 守護程序的第三方重新實現,例如 LoginKit、systembsd、systemd-shim。)