我正在开发一个应用程序,它执行 dbus 调用来管理 systemd 单元。 为了了解调用的想法,我正在编写一个小型 shell 脚本,该脚本应该检测失败的单元,例如
systemctl
:
user$ systemctl --user start error-out.service
Job for error-out.service failed because ...
如何启动systemd单元可以在使用gdbus启动systemd服务中找到。它可以像这样使用
StartUnit
来工作:
user$ dbus-send --session --print-reply --dest=org.freedesktop.systemd1 /org/freedesktop/systemd1 org.freedesktop.systemd1.Manager.StartUnit string:"error-out.service" string:"fail"
method return time=1736951345.318505 sender=:1.0 -> destination=:1.5481 serial=21872 reply_serial=2
object path "/org/freedesktop/systemd1/job/63442"
此调用的选项在 systemd 的 D-Bus 接口 中进行了解释,但该文档根本没有给出任何示例。给我带来麻烦的是获取所创建的作业的状态。文档说:
这可以通过无竞争的方式实现,首先订阅 JobRemoved() 信号,然后调用 StartUnit() 并使用返回的作业对象过滤掉不相关的 JobRemoved() 信号,直到收到所需的信号,这将然后携带start操作的结果
我明白我应该做什么,但是如何做这件事对我来说相当模糊,即使在谷歌搜索并阅读
systemctl
源代码的相关部分之后也是如此。
通过 dbus 接口启动系统时如何监控 systemd 单元是否失败?
在完成问题的同时,至少使其对 root 用户有效。仍然缺少使其在会话总线上工作,因此所有提到的命令现在都需要 root。
此
dbus-monitor
调用显示系统总线上的 JobRemoved
信号:
root# dbus-monitor --system "type='signal',sender='org.freedesktop.systemd1',interface='org.freedesktop.systemd1.Manager',member='JobRemoved'"
signal time=1736954593.223214 sender=:1.5 -> destination=(null destination) serial=53301 path=/org/freedesktop/systemd1; interface=org.freedesktop.systemd1.Manager; member=JobRemoved
uint32 63442
object path "/org/freedesktop/systemd1/job/63442"
string "error-out.service"
string "failed"