我有一台运行 cgroups v2(统一)层次结构的机器,因此 systemd 负责管理所有 cgroups 和委托给 systemd 用户实例的工作。我想对一组进程执行资源控制,所以我需要将它们放在一个单元中——大概是一个systemd 范围。
通常,systemd-run
会这样做——但不幸的是,这些进程已经在运行,我不想重新启动它们。
如何从现有流程中创建systemd 范围?控制组接口文档告诉我这是可能的,但我无法从命令行找到方法。systemctl
两者似乎都systemd-run
无法做到这一点。
有没有办法从命令行?如果重要,我正在运行 systemd v241。
有多种命令行工具可以进行 dbus 调用;systemd 自带一个叫做
busctl
. 所以你可以StartTransientUnit
从命令行调用。命令
语法确实很烦人,但看起来像这样(对于一个进程 ID,14460):
解释
这确实是不透明的(并且尝试了一些尝试来正确,并最终使用它
dbus-monitor
来查看它是如何systemd-run
做到的——尽管仅在系统管理器上,systemd-run --user
似乎没有通过 dbus)。因此,逐个参数的解释:添加到命令
更多楼盘
要将另一个 systemd 属性添加到单元中,您需要增加属性的数量并添加它。请注意,每个属性至少是三个附加的命令行参数:键、值类型和值。例如,添加 Slice 属性将来自:
至
类型“s”是字符串。它们的列表可以在D-Bus 规范的“类型系统”一章中找到
您当然可以将计数更改为 3 并添加第三个属性。等等。
更多 pid
类似于更多属性,但这次是隐藏在“PIDs”属性值中的计数。一个例子应该更清楚:
变成
如果您添加 PID 14461 和 14460。
您可以以相同的方式添加第三个、第四个等 PID。
结合它们
您当然可以将其他属性与其他 pid 结合起来。请记住,pids 列表是一个属性值,因此它需要保持在一起。您不能将 pid 参数与其他属性混合使用。正确的方法是改变:
至:
(顺序无关紧要,您可以将 Slice 块放在 PIDs 块之前)。
签名从哪里来?
签名可以从systemd dbus API 文档中获得,或者可能更容易通过使用 dbus 内省获得:
(对于
grep1
,请参阅https://unix.stackexchange.com/a/279518)列出了很多方法和 dbus 属性,这里有 180 多个。所以不要省略
grep
.“失败”处理冲突是什么意思?那里还有什么?
根据systemd 文档(在“CreateUnit”下查看),有用的值是
fail
和replace
。fail
意味着如果发生冲突,您的范围将无法启动。replace
意味着 systemd 将摆脱冲突的单元。请注意,这似乎仅适用于当前正在启动或计划的单元(它确实说“排队”) - 例如,replace 不会用相同的名称替换已经运行的范围。