Running Services After the Network is up (original) (raw)

Back to systemd




This page has been obsoleted and replaced: https://systemd.io/NETWORK_ONLINE.




So you have configured your service to run after network.target but it still gets run before your network is up? And now you are wondering why that is and what you can do about it?

LSB init scripts know the $network facility. As this facility is defined only very unprecisely people tend to have different ideas what it is supposed to mean. Here are a couple of ideas people came up with so far:

And so on and so on. All these are valid approaches to the question "When is the network up?", but none of them would be useful to be good as generic default.

Modern networking tends to be highly dynamic: machines are moved between networks, network configuration changes, hardware is added and removed, virtual networks are set up, reconfigured and shut down again. Network connectivity is not unconditionally and continuously available, and a machine is connected to different networks at different times. This is particularly true for mobile hardware such as handsets, tablets and laptops, but also for embedded and servers. Software that is written under the assumption that network connectivity is available continuously and never changes is hence not up-to-date with modern standards. Well-written software should be able to handle dynamic configuration changes. It should react to changing network configuration and make the best of it. If it cannot reach a server it must retry. If network configuration connectivity is lost it must react. Reacting to local network configuration changes in daemon code is not particularly hard. In fact many well-known network-facing services running on Linux have been doing this for decades. A service written like this is robust, can be started at any time, and will always do the best of the circumstances it is running in.

$network is a mechanism that is required only to deal with software that assumes continuous network is available (i.e. of the simple non-well-written kind). Which facet of it it requires is undefined. An IMAP server might just require a certain IP to be assigned so that it can listen on it. OTOH a network file system client might need DNS up, and the service to contact up, as well. What precisely is required for $network is not obvious and can be different things depending on local configuration.

A robust system boots up independently of external services. More specifically, if a network DHCP server does not react this should not slow down boot on most setups, but only for those where network connectivity is strictly needed (for example, because the host actually boots from the network).

Concepts in systemd

In systemd, three target units take the role of $network:

Whenever systemd encounters a $network dependency in LSB headers of init scripts it will translate this to a Wants= and After= dependency on network-online.target hence staying relatively close to traditional LSB behaviour.

For more details, see the systemd.special(7) man page.

Cut the crap! How do I make sure that my service starts after the network is really online?

Well, that depends on your setup and the services you plan to run after it (see above). If you need to delay you service after the network is up, include

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

in the .service file.

This will ensure that all configured network devices are up and have an IP address assigned before the service is started. network-online.target will time out after 90s. Enabling this might considerably delay your boot even if the timeout is not reached.

The right "wait" service must be enabled too (NetworkManager-wait-online.service if NetworkManager is used to configure the network, systemd-networkd-wait-online.service if systemd-networkd is used, etc.). systemd-networkd.service has Also=systemd-networkd-wait-online.service in its [Install] section, so when systemd-networkd.service is enabled, systemd-networkd-wait-online.service will be enabled too, which means that network-online.target will include systemd-networkd-wait-online.service when and only when systemd-networkd.service is enabled. NetworkManager-wait-online.service is set up similarly. Verify that the right service is enabled (usually only one should be):

$ systemctl is-enabled NetworkManager-wait-online.service systemd-networkd-wait-online.service
disabled
enabled

What does this mean for me, a Developer?

If you are a developer, instead of wondering what to do about network.target, please just fix your program to be friendly to dynamically changing network configuration. That way you will make your users happy because things just start to work, and you will get fewer bug reports as your stuff is just rock solid. You also make the boot faster for your users, as they don't have to delay arbitrary services for the network anymore (which is particularly annoying for folks with slow address assignment replies from a DHCP server).

Here are a couple of possible approaches: