From 2f96a29c2c55bdd67cdd8e0b0cfd6971968e4bca Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 29 May 2023 12:37:44 +0900 Subject: [PATCH] wait-online: request that at least one managed online interface exists Fixes a regression caused by ab3aed4a0349bbaa26f53340770c1b59b463e05d. I thought the commit does not cause any severe regression. However, drivers for network interfaces may be loaded later. So, we should wait if no network interface is found. Fixes #27822. --- src/network/wait-online/manager.c | 22 ++++++++++++++------- test/test-network/systemd-networkd-tests.py | 4 ---- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/network/wait-online/manager.c b/src/network/wait-online/manager.c index 2e845aa19f..9213795f54 100644 --- a/src/network/wait-online/manager.c +++ b/src/network/wait-online/manager.c @@ -162,12 +162,13 @@ bool manager_configured(Manager *m) { return true; } - /* With '--any' : no interface is ready - * Without '--any': all interfaces are ready */ + /* With '--any' : no interface is ready → return false + * Without '--any': all interfaces are ready → return true */ return !m->any; } /* wait for all links networkd manages */ + bool has_online = false; HASHMAP_FOREACH(l, m->links_by_index) { if (manager_ignore_link(m, l)) { log_link_debug(l, "link is ignored"); @@ -179,13 +180,20 @@ bool manager_configured(Manager *m) { _LINK_OPERSTATE_INVALID }); if (r < 0 && !m->any) /* Unlike the above loop, unmanaged interfaces are ignored here. */ return false; - if (r > 0 && m->any) - return true; + if (r > 0) { + if (m->any) + return true; + has_online = true; + } } - /* With '--any' : no interface is ready - * Without '--any': all interfaces are ready or unmanaged */ - return !m->any; + /* With '--any' : no interface is ready → return false + * Without '--any': all interfaces are ready or unmanaged + * + * In this stage, drivers for interfaces may not be loaded yet, and there may be only lo. + * To avoid that wait-online exits earlier than that drivers are loaded, let's request at least one + * managed online interface exists. See issue #27822. */ + return !m->any && has_online; } static int manager_process_link(sd_netlink *rtnl, sd_netlink_message *mm, void *userdata) { diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py index 8b01718d55..17dbb3b38d 100755 --- a/test/test-network/systemd-networkd-tests.py +++ b/test/test-network/systemd-networkd-tests.py @@ -1157,10 +1157,6 @@ class WaitOnlineTests(unittest.TestCase, Utilities): def tearDown(self): tear_down_common() - def test_wait_online_all_unmanaged(self): - start_networkd() - self.wait_online([]) - def test_wait_online_any(self): copy_network_unit('25-bridge.netdev', '25-bridge.network', '11-dummy.netdev', '11-dummy.network') start_networkd()