I have a user service in ~/.config/systemd/user/example.service
like so:
[Unit]
Description=Example service
After=network.target
[Service]
ExecStart=/bin/bash -c 'host google.com > /var/tmp/example'
[Install]
WantedBy=default.target
The actual service I'm trying to control actually does something useful and accesses the network, of course; this is just a simplified example.
The service is enabled via systemctl --user enable example.service
which creates the symlink ~/.config/systemd/user/default.target.wants/example.service
pointing to ~/.config/systemd/user/example.service
.
With this setup, and with systemd
user sessions enabled as described on the Arch Wiki, the service is started as my user upon startup. However, it is not actually started after the network is set up; instead, it seems to start immediately, since /var/tmp/example
contains:
;; connection timed out; no servers could be reached
(And the actual service that I'm trying to control can't reach the network either, and fails with similar name-lookup errors)
This means that the service doesn't actually run after network.target
. How do I make it wait for network.target
before running?
Best Answer
Forget the
network.target
.man systemd.special
says:So, this target is primarily a compatibility hack for SysV init scripts.
Assuming that your network connection is handled by NetworkManager you were of course right to depend on this target because
NetworkManager.service
definesBefore=network.target
. But this only means that NetworkManager has been started, not that the network connection is actually established. That may take a while (dhcp roundtrips, wifi handshake, etc.) and is entirely the business of NetworkManager. At least on my system (F18) there is a service calledNetworkManager-wait-online
. It uses thenm-online
utility program to block until there is an active connection established. Try toRequire, Before
that in your Unit definition or use that tool on its own.