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


15

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

Wants=network-online.target
After=network-online.target

但是,服务似乎还为时过早,在journalctl我看来:

network-online.target: Cannot add dependency job, ignoring: Unit network-online.target failed to load: No such file or directory.

然后我搜索更多并尝试

Wants=network.target
After=network.target

并且做到了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.

再次,服务开始得太早了。

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


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

systemd --user与流程分开运行systemd --system。用户单位不能引用或依赖系统单位。

该论坛帖子似乎提出了一种简单的解决方案:我应该link以用户身份使用必要的系统单元,从而在其单元搜索路径上创建指向该系统的符号链接。

这样做之后,我看不到任何No such file or directory消息,但是,在网络联机之后,我仍然无法使服务真正运行。我曾尝试连接network.targetnetwork-online.target并且systemd-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.

但是,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.

希望您能回答。

@Deleteme谢谢,我想我找到了造成这种情况的原因(请参阅更新),但没有找到解决问题的方法。
Lev Levitsky

你们每个人都找到了解决这个问题的办法吗?另外,我注意到您强调只有一些链接的单元失效。哪些有效,它们有何不同?
Sparhawk

@Sparhawk不幸的是没有。解决方法是,我只使用设置为启动后几秒钟的计时器。这个问题有一个例子:链接后,网络联机目标处于活动状态,而网络目标未处于活动状态。
Lev Levitsky

也许我误会了,但是我正在寻找每次网络恢复可以触发的东西,以便在挂起恢复后检查我的电子邮件。我认为这将是这样做的方式。我现在看到示例。我以为您的意思是某些自定义服务被触发,而有些则没有。但是,我现在看到您正在谈论网络目标的用户版本。
Sparhawk

Answers:


3

由于您不能依赖系统服务,因此唯一的解决方案是提供检测网络是否在线的用户服务。(或使您的服务成为系统服务。)“检测在线”用户服务的详细信息取决于您对“在线”的定义。例如,它可以等待对8.8.8.8的ping成功。或使DNS名称解析成功。例如,在与vpnc类似的情况下,我等待对vpn IP的ping成功。

然后,可以使您的用户服务取决于(After =)您的在线检测用户服务。

#!/bin/sh

host="${1:-8.8.8.8}"

pingcheck() {
  ping -n -c 1 -w 5 $1 >/dev/null 2>&1
}

# Do you want a timeout ?
while :; do
  pingcheck ${host} && exit 0
  sleep 10
done

谢谢,这似乎足够合理和简单。但是,如果有10个用户启用了我的用户服务,则将有10个实例同时对同一台服务器执行ping操作,这似乎有点多余。实际上,这可能不是问题,但是我问这个问题是希望为所有用户服务提供一个“在线标志”。但是,尚未提出更好的解决方案。
Lev Levitsky

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

其次是:

# systemctl daemon-reload && systemctl enable foo.service

5
但是,这是一项系统服务,我正在尝试设置用户服务。
Lev Levitsky
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.