22

So, I'm trying to make systemd service on Debian Jessie. I need it to start after network-online.target is reached.

The problem is network-online.target fires in the same time as network.target and in that time my interfaces are not configured yet, just started DHCP query.

It looks like issue specific to Debian because it uses legacy network configuration.

How to bypass this problem or how to make network-online.target working?

  • What's the output of systemctl list-dependencies network-online.target? Also, note that the network-online.target may not necessary mean that there is Internet access. See this page for more info. – saiarcot895 Jul 22 '15 at 23:10
  • Output of the command is: network-online.target ● └─systemd-networkd-wait-online.service I've read that page already, I understand the basic concept there, but still it is very strange to have no defined point where network critical services can start. At least it could wait for proper DHCP assign. – 10robinho Jul 22 '15 at 23:42
  • This means that the network-online.target depends only on the systemd-networkd-wait-online.service saying that it is ready. It doesn't depend on NetworkManager saying it's ready, nor check that ifup brought all links up successfully (if you use that method to configure your network). Ubuntu, on the other hand, depends on ifup and NetworkManager, but not for systemd-networkd-wait-online.. – saiarcot895 Jul 23 '15 at 0:12
  • How are you configuring your network: /etc/network/interfaces, systemd .network files, or NetworkManager? – saiarcot895 Jul 23 '15 at 0:18
  • Your are right, network-online.target and network.target are triggered right after ifup. I use debian default, so /etc/network/interfaces with dhcp address. It looks like networkd could be better solution, but it's not straightforward to implement. – 10robinho Jul 23 '15 at 0:24
18
+150

Since you're using /etc/network/interfaces, you'll need a systemd service to monitor the status of each interface. Check to see if you have /lib/systemd/system/ifup-wait-all-auto.service (installed by the ifupdown package in Ubuntu 15.04). If not, then create /etc/systemd/system/ifup-wait-all-auto.service, and paste in the following:

[Unit]
Description=Wait for all "auto" /etc/network/interfaces to be up for network-online.target
Documentation=man:interfaces(5) man:ifup(8)
DefaultDependencies=no
After=local-fs.target
Before=network-online.target

[Service]
Type=oneshot
RemainAfterExit=yes
TimeoutStartSec=2min
ExecStart=/bin/sh -ec '\
  for i in $(ifquery --list --exclude lo --allow auto); do INTERFACES="$INTERFACES$i "; done; \
  [ -n "$INTERFACES" ] || exit 0; \
  while ! ifquery --state $INTERFACES >/dev/null; do sleep 1; done; \
  for i in $INTERFACES; do while [ -e /run/network/ifup-$i.pid ]; do sleep 0.2; done; done'

[Install]
WantedBy=network-online.target

This is the service file as present on an Ubuntu 15.04 system, but with the [Install] section added in to make things a little easier. I'm hoping that the behavior of ifup in Ubuntu 15.04 is the same as the behavior of ifup in Debian Jessie. If not, some modification will be necessary (particularly with the last line).

Then, run sudo systemctl enable ifup-wait-all-auto.service. After rebooting your computer, you should see that the network-online.target is reached after the interfaces are brought up (at least).

  • Thanks for effort, let me try it now and I'll give you feedback – 10robinho Jul 23 '15 at 1:13
  • I've ended up running slightly modified version ExecStart = /bin/bash -c 'while [ -z "$(hostname -I)" ]; do sleep 1; done;'. It depends on hostname to check if IP address has been assigned. – luka5z May 1 '17 at 20:04
  • Don't try spin doctor it. it's not because he's using /etc/network/interfaces. It's because systemd is so sloppy and the work is offloaded to every user instead of solving the problem where it was created. – Florian Heigl Sep 19 '17 at 22:32
  • 1
    fwiw, the ifup-wait-all-auto.service has been dropped in ifupdown version 0.8.5ubuntu1: ”Drop ifup-wait-all-auto.service. This has been implemented more elegantly by making network-online.target Wants=networking.service directly.“ [changelog] – myrdd Jul 10 '18 at 5:26
0

Attention! Just figured out it on a Raspbian Jessie : remove ALL commented lines in /etc/network interfaces and it will work! It seems to be a parsing bug =) In my specific case I've left commented iface eth0 inet dhcp and just forgot about it eons ago, but after upgrade to Raspbian Jessie and rebuilding a kernel I've got very odd behaviour : it used DHCP and refused to make a tuning from /etc/network/interfaces. So I've stripped it out of any comments - just working lines, reboot - and it works! NO SCRIPT PATCHING/EDITING NEEDED!

  • Interestin, I need to try this. Although it doesn't make much sense :) – 10robinho Jan 18 '16 at 12:10
  • 1
    Do you have any references about this? I'd like to read the bug report(s) and see the buggy code. – ʇsәɹoɈ Feb 9 '17 at 22:27
  • No, I haven't opened a bug ticket. To reproduce it just add some comments in your /etc/network/interfaces file - it will fire up if it's still there. – Alexey Vesnin Feb 9 '17 at 23:10
0

Per https://www.freedesktop.org/wiki/Software/systemd/NetworkTarget/ the recommended way to start a service AFTER networking is level is to use "network-online.target" in the .service file:

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

However after using "network-online.target" and my service failing because networking wasn't fully level, I discovered there's a bug (https://github.com/coreos/bugs/issues/1966) with it: not guaranteed to be 100% infallible.

Indeed, where dynamic networking configuration tools such as "NetworkManager" are used as in this case, the state of networking can never be 100% precise or predictable. Apparently from the link describing the bug, "network-online.target" can behave inconsistently depending on different applications it's used with.

Workaround:
You need to analyze the start-up order of services and use one that starts later than "network-online.target":

 systemd-analyze plot > /home/pi/graph.svg

This is an iterative process changing the targets incrementally to later and later services until you find the one that ensures networking is level and your service starts without error. In my own case I even had to put a sleep 10 in my script the SystemD service called.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.