如何让我的用户服务等到网络上线?

Lev*_*sky 17 linux arch-linux systemd systemd-networkd

我已经编写了几个 systemd 用户服务文件,我希望用户启用它们并且需要一个有效的网络连接。我认为这很简单:

Wants=network-online.target
After=network-online.target
Run Code Online (Sandbox Code Playgroud)

但是,这些服务似乎开始得太早了,在journalctl我看来:

network-online.target: Cannot add dependency job, ignoring: Unit network-online.target failed to load: No such file or directory.
Run Code Online (Sandbox Code Playgroud)

然后我搜索了更多并尝试

Wants=network.target
After=network.target
Run Code Online (Sandbox Code Playgroud)

并做了sudo systemctl enable systemd-networkd-wait-online.service

现在我有journalctl

network.target: Cannot add dependency job, ignoring: Unit network.target failed to load: No such file or directory.
Run Code Online (Sandbox Code Playgroud)

服务再次开始得太早。

那条消息应该在那里吗?我该如何调试我的问题?


编辑:原因很简单,并且在Arch Wiki 中有明确说明:

systemd --user作为独立于进程的systemd --system进程运行。用户单位不能参考或依赖系统单位。

这个论坛帖子似乎提出了一个简单的解决方案:我应该link作为用户必要的系统单元,从而在单元搜索路径上创建一个可用的符号链接。

这样做之后,我没有看到任何No such file or directory消息,但是,我仍然无法在网络上线后使服务真正运行。我尝试链接network.target,network-online.targetsystemd-networkd-wait-online.service,将我的单位设置为依赖于它们中的每一个,但没有成功。当我在用户模式下检查链接单元的状态时, 它们中的一些都已死,例如:

$ systemctl --user status network.target
? network.target - Network
   Loaded: loaded (/usr/lib/systemd/system/network.target; linked; vendor preset: enabled)
   Active: inactive (dead)
     Docs: man:systemd.special(7)
           http://www.freedesktop.org/wiki/Software/systemd/NetworkTarget
$ systemctl status network.target
? network.target - Network
   Loaded: loaded (/usr/lib/systemd/system/network.target; static; vendor preset: disabled)
   Active: active since Sat 2015-07-18 19:20:11 MSK; 3h 35min ago
     Docs: man:systemd.special(7)
           http://www.freedesktop.org/wiki/Software/systemd/NetworkTarget

Jul 18 19:20:11 calc-server systemd[1]: Reached target Network.
Jul 18 19:20:11 calc-server systemd[1]: Starting Network.
Run Code Online (Sandbox Code Playgroud)

但是,我可以network-online.target在链接后看到在用户模式下处于活动状态:

$ systemctl --user status network-online.target
? network-online.target - Network is Online
   Loaded: loaded (/usr/lib/systemd/system/network-online.target; linked; vendor preset: enabled)
   Active: active since Sun 2015-07-19 00:35:38 MSK; 2min 48s ago
     Docs: man:systemd.special(7)
           http://www.freedesktop.org/wiki/Software/systemd/NetworkTarget

Jul 19 00:35:38 calc-server systemd[469]: Reached target Network is Online.
Jul 19 00:35:38 calc-server systemd[469]: Starting Network is Online.
Run Code Online (Sandbox Code Playgroud)

Vit*_*aly 6

由于这个主题在谷歌搜索结果中排名第一,我为所有面临同样问题的人分享一个替代解决方案。

在我的系统中,我添加了一个简化的等效项/lib/systemd/system/systemd-networkd-wait-online.service(即WantedBy=network-online.target)并将其存储在用户服务目录中:

[Unit]
Description=User Wait for Network to be Configured

[Service]
Type=oneshot
ExecStart=/lib/systemd/systemd-networkd-wait-online
RemainAfterExit=yes

[Install]
WantedBy=default.target
Run Code Online (Sandbox Code Playgroud)

然后我让我的用户服务依赖于这个新服务:

Wants=networkd-wait-online.service
After=networkd-wait-online.service
Run Code Online (Sandbox Code Playgroud)

不过,Wants=似乎不需要,因为WantedBy=default.target. 您可以删除WantedBy=default.target,因此这成为network-wait-online.service可选的,但您肯定需要Wants=network-wait-online.service

原始服务systemd-networkd-wait-online.service包含更多依赖项,但它们似乎无法在用户上下文中工作。有人可能会为所有这些依赖项提供用户运行等效项,例如通过使用systemctl --user linkfornetwork.targetnetwork-online.targetas 此处的其他建议,但我决定保持简单;)

请注意,尽管创建了到系统服务的符号链接,但您不会告诉经理systemd --user使用管理器中的某些事件来systemd --system监视系统服务状态,而是使其从用户上下文运行该服务的另一个实例。


小智 1

我建议测试这样的东西:

# /etc/systemd/system/foo.service
[Unit]
After=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/bin/logger -t foo "testing online target"

[Install]
WantedBy=multi-user.target
Run Code Online (Sandbox Code Playgroud)

其次是:

# systemctl daemon-reload && systemctl enable foo.service
Run Code Online (Sandbox Code Playgroud)

  • 但这是一个系统服务,我正在尝试设置一个用户服务。 (9认同)