11

I'm using systemd-networkd to configure my interfaces:

[Match]
Name=enp3s0

[Network]
DHCP=v4    

It works quite well except that at boot, some services are not waiting for DHCP to finish. For instances my NFS-mounted directories and nginx fail because there is no network at the time they boot.

Is there a way to force network.target to wait for DHCP?


Note from the editor. According to the documentation:

Many network management solutions provide a way to unconditionally pull in network-online.target, and thus upgrading the effect of network.target to the effect of network-online.target.

If you use systemd-networkd you can do this by enabling systemd-networkd-wait-online.service:

systemctl enable systemd-networkd-wait-online.service

However I tried this and it did not make services depending on network.target wait for DHCP. It only made services which explicitly depend on network-online.target wait for DHCP, and in fact it is required to make that work.

5
  • The other services should be waiting for the network, with {After,Wants}=network-online.target.
    – jasonwryan
    Commented Sep 25, 2014 at 17:29
  • @jasonwryan I can edit my own services, but what about NFS mount for instance ? There is no service file for that. Or sshd.service, should I edit all of them ? Isn't there any way to force network.target = network-online.target ? Commented Oct 1, 2014 at 6:53
  • Do you need to wait for DHCP? Can you assign a static IP?
    – jasonwryan
    Commented Oct 1, 2014 at 7:28
  • Yes, I need to wait. I switched from static IP to DHCP and that's caused all the problems. No, I do not want to assign static IPs. Commented Oct 1, 2014 at 10:23
  • 2
    I'm also having this problem. I have {After,Wants}=network-online.target in my service unit, and systemd-networkd-wait-online.service is enabled. Still, my service immediately starts after the links is activated, but without having an ipv4 address via DHCP. Commented Jul 23, 2016 at 10:35

5 Answers 5

8

When using systemd-networkd, to make sure that all interfaces are up and have an IP address assigned use:

systemctl enable systemd-networkd-wait-online.service

Someone else may be using NetworkManager, in which case that would be:

systemctl enable NetworkManager-wait-online.service

See: http://www.freedesktop.org/wiki/Software/systemd/NetworkTarget/

3
3

Actually, the definition of "online" in this context is defined in .network file.

[Link]
RequiredForOnline=routable

https://www.freedesktop.org/software/systemd/man/systemd.network.html#RequiredForOnline= https://www.freedesktop.org/software/systemd/man/systemd.network.html#RequiredFamilyForOnline= RequiredForOnline has a default value of yes which I cannot find a definition of it. But you should set to one of the values listed here: https://www.freedesktop.org/software/systemd/man/networkctl.html I choose routable because it will wait for an IP.

3

According to the man page for systemd-networkd-wait-online.service:

By default, it will wait for all links it is aware of and which are managed by systemd-networkd.service(8) to be fully configured or failed, and for at least one link to be online. Here, online means that the link's operational state is equal or higher than "degraded". The threshold can be configured by --operational-state= option.

So if you want a specific link to be fully configured and routable to be considered "online", you could edit /lib/systemd/system/systemd-networkd-wait-online.service and change ExecStart to:

ExecStart=/usr/lib/systemd/systemd-networkd-wait-online --operational-state=routable
1

I haven't used systemd-networkd specifically before, but systemd definitely should be able to resolve this by adjusting the systemd service file that systemd-networkd uses.

Finding Service File

If you run:

systemctl status systemd-networkd

You should get output that looks similar to this (using systemd-modules-load.service as an example because I don't have systemd-networkd):

systemd-modules-load.service - Load Kernel Modules
Loaded: loaded (/usr/lib/systemd/system/systemd-modules-load.service; static)
Active: failed (Result: exit-code) since So 2013-08-25 11:48:13 CEST; 32s ago
 Docs: man:systemd-modules-load.service(8).
       man:modules-load.d(5)
Process: 15630 ExecStart=/usr/lib/systemd/systemd-modules-load (code=exited, status=1/FAILURE)

The second line tells you the location of the service file (in the example it's /usr/lib/systemd/system/systemd-modules-load.service). The service file determines when in the systemd hierarchy things should be started.

Modifying Service File

If you open this file in a text editor there are 3 very important sections:

  • [Unit]

  • [Service]

  • [Install]

The [Unit] section can contain After and Requires directives. After forces the service to start after another systemd unit, Requires forces another systemd unit to be started if it's not already enabled (but doesn't force an ordering).

So if you locate the systemd-networkd service file, determine which unit you want systemd-networkd to start after, and add to the [Unit] section you should be set:

[Unit]
...
Requires=[unit name]
After=[unit name]

With this method you can force the systemd-networkd service to start after any other unit.

Other Concerns

You say your network mounts fail, if you're mounting the via /etc/fstab do their entries contain the _netdev option?

10
  • This doesn't address the question at all. Also you just created a circular dependency where the thing that brings up network interfaces won't run until the network interfaces are up.
    – ali1234
    Commented Oct 6, 2016 at 20:43
  • @ali1234 "Is there a way to force systemd-networkd to wait for DHCP or another target to wait for in the other service files" The systemd service file is what determines when the service is started, so I wouldn't say it "doesn't address the question at all". I'll concede that network-online.target is not the unit needed here, but the rest of the answer is still valid. I'll take out the network-online.target mention though and look into the dhcpclient a little more. Seems like the network-functions normally call /sbin/dhcpclient which systemd-networkd is probably also doing.
    – Centimane
    Commented Oct 6, 2016 at 21:35
  • The person who originally asked this question phrased it very badly. They actually want to make network.target wait until an interface has been assigned an address on DHCP. According to the documentation linked in the other answer 'systemctl enable systemd-networkd-wait-online.service' does that. But in reality it does not.
    – ali1234
    Commented Oct 7, 2016 at 11:58
  • @ali1234 A bit of a hack way to achieve this would be a new systemd service that is before systemd-networkd, with an ExecPre calling a script that loops trying to call dhcpclient on the first interface until it suceeds. Even if the first interface isn't DHCP it'll get overwritten when systemd-network does start. This assumes systemd-networkd is mostly just responsible for configuring the interfaces.
    – Centimane
    Commented Oct 7, 2016 at 12:42
  • systemd-networkd does all interface management from bringing up the interfaces to doing DHCP so that would still cause a circular dependency.
    – ali1234
    Commented Oct 10, 2016 at 23:10
1

Most linux variants use Network Manager with systemd using NetworkManager-wait-online.service to determine whether or not the network is up. If this is the case, you can edit /lib/systemd/system/NetworkManager-wait-online.service and change:

ExecStart=/usr/bin/nm-online -s -q --timeout=30

To:

ExecStart=/usr/bin/nm-online -q --timeout=30

The -s option means: Wait for NetworkManager startup to complete, rather than waiting for network connectivity specifically.

Removing it will give a better indication of the network status and systemd can wait for it to come up before starting the dependant services.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .