首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何从命令行为已经存在的进程创建系统范围?

如何从命令行为已经存在的进程创建系统范围?
EN

Unix & Linux用户
提问于 2019-06-18 23:53:21
回答 1查看 2.1K关注 0票数 13

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

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

如何从已经存在的进程中创建系统范围控制组接口文档告诉我这是可能的,但我还无法从命令行找到一种方法。systemctlsystemd-run似乎都无法做到这一点。

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

EN

回答 1

Unix & Linux用户

回答已采纳

发布于 2019-06-18 23:53:21

有各种命令行工具来进行dbus调用;systemd附带了一个名为busctl的命令行工具。这样您就可以从命令行调用StartTransientUnit

命令

语法确实很烦人,但看起来如下(对于一个进程id,14460):

代码语言:javascript
运行
复制
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)。因此,一个解释,参数按参数:

代码语言:javascript
运行
复制
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属性,可以增加属性的数量并将其添加到单元中。注意,每个属性至少是三个附加的命令行参数:键、值类型和值。例如,添加一个片属性来自:

代码语言:javascript
运行
复制
… fail 1 PIDs au 1 14460 0

代码语言:javascript
运行
复制
… fail 2 PIDs au 1 14460 Slice s whatever.slice 0
       ^                 ^^^^^ ^ ^^^^^^^^^^^^^^
     count                key type value

键入"s“是字符串。它们的列表可以在D总线规范的“类型系统”一章中找到。

当然,您可以将计数更改为3并添加第三个属性。等。

更多pids

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

代码语言:javascript
运行
复制
… fail 1 PIDs au 1 14460 0

变成了

代码语言:javascript
运行
复制
… fail 1 PIDs au 2 14460 14461 0
                 ^       ^^^^^
         internal count  second pid

如果你加上PID 14461和14460。

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

将它们组合成

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

代码语言:javascript
运行
复制
… fail 1 PIDs au 1 14460 0

至:

代码语言:javascript
运行
复制
… fail 2 PIDs au 2 14460 14461 Slice s whatever.slice 0

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

签名来自哪里?

签名可以从系统dbus API文档获得,或者可能更容易地通过使用dbus内省获得:

代码语言:javascript
运行
复制
$ 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

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

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

票数 15
EN
页面原文内容由Unix & Linux提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://unix.stackexchange.com/questions/525740

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档