如何從命令行為已存在的程序創建 systemd 範圍?
我有一台執行 cgroups v2(統一)層次結構的機器,因此 systemd 負責管理所有 cgroups 和委託給 systemd 使用者實例的工作。我想對一組程序執行資源控制,所以我需要將它們放在一個單元中——大概是一個systemd 範圍。
通常,
systemd-run
會這樣做——但不幸的是,這些程序已經在執行,我不想重新啟動它們。如何從現有流程中創建systemd 範圍?控制組介面文件告訴我這是可能的,但我無法從命令行找到方法。
systemctl
兩者似乎都systemd-run
無法做到這一點。有沒有辦法從命令行?如果重要,我正在執行 systemd v241。
有多種命令行工具可以進行 dbus 呼叫;systemd 自帶一個叫做
busctl
. 所以你可以StartTransientUnit
從命令行呼叫。命令
語法確實很煩人,但看起來像這樣(對於一個程序 ID,14460):
busctl call --user org.freedesktop.systemd1 /org/freedesktop/systemd1 \ org.freedesktop.systemd1.Manager StartTransientUnit 'ssa(sv)a(sa(sv))' \ 'SCOPE-NAME.scope' fail 1 PIDs au 1 14460 0
解釋
這確實是不透明的(並且嘗試了一些嘗試來正確,並最終使用它
dbus-monitor
來查看它是如何systemd-run
做到的——儘管僅在系統管理器上,systemd-run --user
似乎沒有通過 dbus)。所以一個解釋,一個參數一個參數:busctl call --user # use user session dbus, not system org.freedesktop.systemd1 # dbus service name /org/freedesktop/systemd1 # dbus object in that service org.freedesktop.systemd1.Manager # interface name in that service StartTransientUnit # method we're going to call 'ssa(sv)a(sa(sv))' # signature of method, see below 'SCOPE-NAME.scope' # first argument, name of scope fail # second argument, how to handle conflicts (see below) 1 # start of third argument, number of systemd properties for unit PIDs # name of first property au # data type of first property, (a)rray [aka list] of (u)nsigned integers 1 # count of array — that is, number of pids 14460 # first pid 0 # fourth argument: array size=0 (unused parameter)
添加到命令
更多樓盤
要將另一個 systemd 屬性添加到單元中,您需要增加屬性的數量並添加它。請注意,每個屬性至少是三個附加的命令行參數:鍵、值類型和值。例如,添加 Slice 屬性將來自:
… fail 1 PIDs au 1 14460 0
到
… fail 2 PIDs au 1 14460 Slice s whatever.slice 0 ^ ^^^^^ ^ ^^^^^^^^^^^^^^ count key type value
類型“s”是字元串。它們的列表可以在D-Bus 規範的“類型系統”一章中找到
您當然可以將計數更改為 3 並添加第三個屬性。等等。
更多 pid
類似於更多屬性,但這次是隱藏在“PIDs”屬性值中的計數。一個例子應該更清楚:
… fail 1 PIDs au 1 14460 0
變成
… fail 1 PIDs au 2 14460 14461 0 ^ ^^^^^ internal count second pid
如果您添加 PID 14461 和 14460。
您可以以相同的方式添加第三個、第四個等 PID。
結合它們
您當然可以將其他屬性與其他 pid 結合起來。請記住,pids 列表是一個屬性值,因此它需要保持在一起。您不能將 pid 參數與其他屬性混合使用。正確的方法是改變:
… fail 1 PIDs au 1 14460 0
到:
… fail 2 PIDs au 2 14460 14461 Slice s whatever.slice 0
(順序無關緊要,您可以將 Slice 塊放在 PIDs 塊之前)。
簽名從哪裡來?
簽名可以從systemd dbus API 文件中獲得,或者可能更容易通過使用 dbus 內省獲得:
$ busctl introspect org.freedesktop.systemd1 /org/freedesktop/systemd1 \ org.freedesktop.systemd1.Manager | grep1 StartTransientUnit NAME TYPE SIGNATURE RESULT/VALUE FLAGS .StartTransientUnit method ssa(sv)a(sa(sv)) o -
(對於
grep1
,請參閱https://unix.stackexchange.com/a/279518)列出了很多方法和 dbus 屬性,這裡有 180 多個。所以不要省略
grep
.“失敗”處理衝突是什麼意思?那裡還有什麼?
根據systemd 文件(在“CreateUnit”下查看),有用的值是
fail
和replace
。fail
意味著如果發生衝突,您的範圍將無法啟動。replace
意味著 systemd 將擺脫衝突的單元。請注意,這似乎僅適用於目前正在啟動或計劃的單元(它確實說“排隊”) - 例如,replace 不會用相同的名稱替換已經執行的範圍。