Comment 12 for bug 1588915

Revision history for this message
Maciej Puzio (maciej-puzio) wrote :

I am also affected by this issue. In my case both network.target and network-online.target are reached too early, which results in sssd and autofs to start before network interfaces are up; autofs then fails to obtain mount maps and does not attempt to retry; it is necessary to restart autofs manually after network has started fully.

Similarly as the bug reporter, I run Ubuntu 16.04 server, and I use static addresses only, configured in /etc/network/interfaces.

The root cause is ifup exiting with success before network interfaces start operating. However, ifup behaved the same way in Ubuntu 14.04, and there it did not cause the problem. Apparently Upstart and its network-related units were able to deal with this issue correctly. In contrast, systemd configuration files packaged in ifupdown Xenial package are causing the "async" behavior of ifup to surface and create problems.

During system boot there are two attempts to start physical network interfaces by ifup: in ifup@.service (one service per interface) and in networking.service. All these services start in parallel and call ifup in parallel, but ifup uses a lock to prevent its concurrent execution (per interface), effectively serializing ifup@.service(s) and networking.service. In my tests, ifup@ services always win this race. This actually works fine if all interfaces are configured successfully. If not, networking.service performs a second attempt after ifup@.service failed, which may be problematic (see below).

Targets network.target and network-online.target are reached when networking.service finishes. This happens after interfaces are configured by ifup. Interfaces became operable significantly later.

The problem may be worked around in a particular configuration in several ways:

1. We can make ifup wait for the interface to come up, for example by including a loop in post-up command in /etc/network/interfaces, checking /sys/class/net/$INTERFACE/operstate. This would require using some timeout, after which the command would fail, to deal with situations such as a disconnected cable. In such a case, the delay would be twice as long as the specified timeout, because that timeout will have to be reached in both ifup@.service and networking service. If we do not configure any virtual interfaces, we can deal with this by disabling networking.service.

2. We can modify ifup@.service to wait for the interface to come up, similarly as above. It will also be necessary to change the type of this service from "simple" to "oneshot", to make it wait for its ExecStart command before exiting.

3. We can also modify networking.service to wait in a similar manner.

4. We can introduce an additional service which will wait for all or some interfaces to come up, and will delay network.target and network-online.target until it is done. It would be advantageous to wait on all interfaces in parallel, and I am not sure if that would be easy to implement in one service.

5. An active waiting in a loop is obviously not the most beautiful solution, so perhaps a cleaner way could be found?