Make systemd user service depend on system target
I was having the same problem, with a userland backup script that needs access to the internet. I solved it by adding ~/.config/systemd/user/wait-for-network.service
that just pings google.com
until it is reachable:
[Unit]
Description=Ping a server on the internet until it becomes reachable
[Service]
Type=oneshot
ExecStart=/bin/bash -c 'while ! ping -c1 google.com; do sleep 1; done'
TimeoutStartSec=60s
Then I made my backup script depend on it like this:
[Unit]
Description=...
Requires=wait-for-network.service
After=wait-for-network.service
This works regardless of whether you use NetworkManager
or some other means to establish the connection.
Forget the network.target
. man systemd.special
says:
network.target systemd automatically adds dependencies of type After for this target unit to all SysV init script service units with an LSB header referring to the $network facility.
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
defines Before=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 called NetworkManager-wait-online
. It uses the nm-online
utility program to block until there is an active connection established. Try to Require, Before
that in your Unit definition or use that tool on its own.