命令

命令

我有一台运行 cgroups v2(统一)层次结构的计算机,因此 systemd 负责管理所有 cgroup 并委托给 systemd 用户实例工作。我想表演资源控制在一组进程上,所以我需要将它们放在一个单元中——大概是一个系统范围

通常情况下,systemd-run会这样做 - 但不幸的是这些进程已经在运行,我不想重新启动它们。

我怎样才能创建一个系统范围从现有流程中?这控制组接口文档告诉我这是可能的,但我无法从命令行找到方法。两者systemctl似乎都systemd-run无法做到这一点。

有没有从命令行的方法?如果重要的话,我正在运行 systemd v241。

答案1

有多种命令行工具可以进行 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 并添加第三个属性。 ETC。

更多 pid

与更多属性类似,但这次是隐藏在“PID”属性值中的计数。一个例子应该更清楚:

… fail 1 PIDs au 1 14460 0

变成

… fail 1 PIDs au 2 14460 14461 0
                 ^       ^^^^^
         internal count  second pid

如果添加 PID 14461 和 14460。

您可以用同样的方式添加第三个、第四个等等 PID。

将它们结合起来

当然,您可以将其他属性与其他 pid 结合起来。请记住,pid 列表是一个属性值,因此它需要保持在一起。您不能将 pid 参数与其他属性混合。正确的做法是改变:

… fail 1 PIDs au 1 14460 0

到:

… fail 2 PIDs au 2 14460 14461 Slice s whatever.slice 0

(顺序并不重要,您可以将 Slice 块放在 PID 块之前)。

签名从哪里来?

签名可以从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-properties,超过 180 个。所以不要省略grep.

处理冲突“失败”意味着什么?那里还有什么?

根据系统文档(查看“CreateUnit”下),有用的值是failreplacefail意味着如果存在某些冲突,您的作用域将无法启动。replace意味着 systemd 将摆脱冲突的单元。请注意,这似乎仅适用于当前正在启动或计划的单元(它确实说“排队”) - 例如,替换不会用相同的名称替换已经运行的范围。

相关内容