如何在systemd单元中将dbus/systemd设置为依赖项?

huangapple go评论63阅读模式
英文:

How to set dbus/systemd as dependency in systemd unit

问题

我有一个用Go编写的小程序,它使用go-systemd库通过dbus与systemd进行交互。

该程序本身被注册为一个systemd单元,并在启动时启动。当程序正在运行时,它会定期查询多个单元的systemd单元状态。

现在,当我手动启动程序时,一切正常。然而,当由systemd在重启后启动时,它会“挂起”,也就是说它无法通过dbus查询systemd单元的状态。我会从go-systemd库中得到以下消息:

Process org.freedesktop.systemd1 exited with status 1

现在,当我重新启动我的程序时,它将立即能够无错误地查询systemd单元。这让我认为我的程序存在错误/配置错误的依赖关系,因此在启动时会出现竞争条件,导致程序无法通过dbus与systemd进行通信。

现在,我已经尝试了这个配置以及其他几个组合,但没有帮助:

Requires=dbus.service
After=dbus.service
Wants=org.freedesktop.systemd1

为了使我的自定义systemd单元(go程序的单元)能够在重启后立即通过dbus与systemd进行通信,我需要如何配置它?我需要配置哪些依赖关系?

英文:

I have a small program written in Go which uses the go-systemd library to interact with systemd using dbus.

The program itself is registered as a systemd unit and shall start upon boot. When the program is running, it will regularly query systemd unit status for several units.

Now when I manually start the program, everything is fine. However, when started after reboot by systemd, it will "hang", means it will be unable to query systemd unit status via dbus. I will get the following message from the go-systemd library:

Process org.freedesktop.systemd1 exited with status 1

Now when I just restart my program, it will immediately be able to query systemd units without error. This leads me to the assumption of wrong/misconfigured dependencies for my program, so that upon boot there will be a race condition which leads to the program being unable to communicate with systemd over dbus.

Now I have already put this, and several other combinations, however it does not help:

Requires=dbus.service
After=dbus.service
Wants=org.freedesktop.systemd1

How do I need to configure my own systemd unit (of the go-program) in order for it to be able to communicate with systemd over dbus right after reboot? What dependency do I have to configure?

答案1

得分: 1

根据你的描述,听起来你的程序默认尝试连接到 DBus 会话总线,因为你说手动运行时它可以正常工作。当一个应用程序从 Systemd 启动时,默认情况下它将以 root 身份运行,没有会话总线可连接,所以会失败。

会话总线通常在每个登录用户在图形终端上登录时启动。在终端登录时,默认情况下不会启动会话总线。

如果是这种情况,目前我能看到两个选项:

  1. 使用系统总线而不是会话总线。
  2. 创建自己的总线,与会话总线和系统总线不同。最简单的方法是使用 dbus-launch 创建一个新的总线,你的应用程序可以连接到该总线。
英文:

It sounds like your program is trying to connect to the DBus Session bus by default, since you say it works fine when you run it manually. When an application starts up from Systemd, it will by default running as root with no session bus to connect to, so it will fail.

The session bus is generally started on a per-login basis when a user logs in on a graphical terminal. It does not start by default when logging in on a terminal.

If this is the case, you have two options that I can see at the moment:

  1. Use the system bus instead of the session bus.
  2. Create your own bus that you connect to, different from the session bus and the system bus. The simplest way is to use dbus-launch to create a new bus that your application can connect to.

huangapple
  • 本文由 发表于 2023年7月3日 14:33:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/76602338.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定