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.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.
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)
由于这个主题在谷歌搜索结果中排名第一,我为所有面临同样问题的人分享一个替代解决方案。
在我的系统中,我添加了一个简化的等效项/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 link
fornetwork.target
和network-online.target
as 此处的其他建议,但我决定保持简单;)
请注意,尽管创建了到系统服务的符号链接,但您不会告诉经理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)