From 5f200833ed0754adaba548b0b617f6c192615acd Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 26 Jan 2022 20:54:39 +0900 Subject: [PATCH 1/2] wait-online: rename Manager elements --- src/network/wait-online/link.c | 4 ++-- src/network/wait-online/manager.c | 33 ++++++++++++++++++------------- src/network/wait-online/manager.h | 8 ++++---- 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/src/network/wait-online/link.c b/src/network/wait-online/link.c index a1ad16db47..ce6c8b181c 100644 --- a/src/network/wait-online/link.c +++ b/src/network/wait-online/link.c @@ -32,7 +32,7 @@ int link_new(Manager *m, Link **ret, int ifindex, const char *ifname) { .required_operstate = LINK_OPERSTATE_RANGE_DEFAULT, }; - r = hashmap_ensure_put(&m->links, NULL, INT_TO_PTR(ifindex), l); + r = hashmap_ensure_put(&m->links_by_index, NULL, INT_TO_PTR(ifindex), l); if (r < 0) return r; @@ -53,7 +53,7 @@ Link *link_free(Link *l) { return NULL; if (l->manager) { - hashmap_remove(l->manager->links, INT_TO_PTR(l->ifindex)); + hashmap_remove(l->manager->links_by_index, INT_TO_PTR(l->ifindex)); hashmap_remove(l->manager->links_by_name, l->ifname); } diff --git a/src/network/wait-online/manager.c b/src/network/wait-online/manager.c index 3890e92b61..2c6f263499 100644 --- a/src/network/wait-online/manager.c +++ b/src/network/wait-online/manager.c @@ -21,14 +21,15 @@ static bool manager_ignore_link(Manager *m, Link *link) { return true; /* if interfaces are given on the command line, ignore all others */ - if (m->interfaces && !hashmap_contains(m->interfaces, link->ifname)) + if (m->command_line_interfaces_by_name && + !hashmap_contains(m->command_line_interfaces_by_name, link->ifname)) return true; if (!link->required_for_online) return true; /* ignore interfaces we explicitly are asked to ignore */ - return strv_fnmatch(m->ignore, link->ifname); + return strv_fnmatch(m->ignored_interfaces, link->ifname); } static int manager_link_is_online(Manager *m, Link *l, LinkOperationalStateRange s) { @@ -99,14 +100,14 @@ static int manager_link_is_online(Manager *m, Link *l, LinkOperationalStateRange bool manager_configured(Manager *m) { bool one_ready = false; const char *ifname; - void *p; Link *l; int r; - if (!hashmap_isempty(m->interfaces)) { + if (!hashmap_isempty(m->command_line_interfaces_by_name)) { + LinkOperationalStateRange *range; + /* wait for all the links given on the command line to appear */ - HASHMAP_FOREACH_KEY(p, ifname, m->interfaces) { - LinkOperationalStateRange *range = p; + HASHMAP_FOREACH_KEY(range, ifname, m->command_line_interfaces_by_name) { l = hashmap_get(m->links_by_name, ifname); if (!l && range->min == LINK_OPERSTATE_MISSING) { @@ -137,7 +138,7 @@ bool manager_configured(Manager *m) { /* wait for all links networkd manages to be in admin state 'configured' * and at least one link to gain a carrier */ - HASHMAP_FOREACH(l, m->links) { + HASHMAP_FOREACH(l, m->links_by_index) { if (manager_ignore_link(m, l)) { log_link_debug(l, "link is ignored"); continue; @@ -189,7 +190,7 @@ static int manager_process_link(sd_netlink *rtnl, sd_netlink_message *mm, void * return 0; } - l = hashmap_get(m->links, INT_TO_PTR(ifindex)); + l = hashmap_get(m->links_by_index, INT_TO_PTR(ifindex)); switch (type) { @@ -292,7 +293,7 @@ static int on_network_event(sd_event_source *s, int fd, uint32_t revents, void * sd_network_monitor_flush(m->network_monitor); - HASHMAP_FOREACH(l, m->links) { + HASHMAP_FOREACH(l, m->links_by_index) { r = link_update_monitor(l); if (r < 0 && r != -ENODATA) log_link_warning_errno(l, r, "Failed to update link state, ignoring: %m"); @@ -329,10 +330,14 @@ static int manager_network_monitor_listen(Manager *m) { return 0; } -int manager_new(Manager **ret, Hashmap *interfaces, char **ignore, +int manager_new(Manager **ret, + Hashmap *command_line_interfaces_by_name, + char **ignored_interfaces, LinkOperationalStateRange required_operstate, AddressFamily required_family, - bool any, usec_t timeout) { + bool any, + usec_t timeout) { + _cleanup_(manager_freep) Manager *m = NULL; int r; @@ -343,8 +348,8 @@ int manager_new(Manager **ret, Hashmap *interfaces, char **ignore, return -ENOMEM; *m = (Manager) { - .interfaces = interfaces, - .ignore = ignore, + .command_line_interfaces_by_name = command_line_interfaces_by_name, + .ignored_interfaces = ignored_interfaces, .required_operstate = required_operstate, .required_family = required_family, .any = any, @@ -382,7 +387,7 @@ Manager* manager_free(Manager *m) { if (!m) return NULL; - hashmap_free_with_destructor(m->links, link_free); + hashmap_free_with_destructor(m->links_by_index, link_free); hashmap_free(m->links_by_name); sd_event_source_unref(m->network_monitor_event_source); diff --git a/src/network/wait-online/manager.h b/src/network/wait-online/manager.h index f2e091638c..01ad18f8f6 100644 --- a/src/network/wait-online/manager.h +++ b/src/network/wait-online/manager.h @@ -13,12 +13,12 @@ typedef struct Manager Manager; typedef struct Link Link; struct Manager { - Hashmap *links; + Hashmap *links_by_index; Hashmap *links_by_name; /* Do not free the two members below. */ - Hashmap *interfaces; - char **ignore; + Hashmap *command_line_interfaces_by_name; + char **ignored_interfaces; LinkOperationalStateRange required_operstate; AddressFamily required_family; @@ -34,7 +34,7 @@ struct Manager { }; Manager* manager_free(Manager *m); -int manager_new(Manager **ret, Hashmap *interfaces, char **ignore, +int manager_new(Manager **ret, Hashmap *command_line_interfaces_by_name, char **ignored_interfaces, LinkOperationalStateRange required_operstate, AddressFamily required_family, bool any, usec_t timeout); From cd7fcda54333dc95116a434cffc591f21edddbb2 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 26 Jan 2022 16:48:08 +0900 Subject: [PATCH 2/2] wait-online: make manager_link_is_online() return 0 when in unmanaged state Previously, even if a link is in unmanaged state, the function may returns positive value. So, even if all managed links are in the configured sate but do not satisfy the online criteria, e.g., IPv4 address state, then wait-online finishes with positive value. This makes the function always return 0 for unmanaged state. So, at least one managed link must satisfies the online criteria. This also adds more comments and debugging logs. Fixes #22246. --- src/network/wait-online/manager.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/network/wait-online/manager.c b/src/network/wait-online/manager.c index 2c6f263499..6656813f39 100644 --- a/src/network/wait-online/manager.c +++ b/src/network/wait-online/manager.c @@ -45,13 +45,29 @@ static int manager_link_is_online(Manager *m, Link *l, LinkOperationalStateRange * 0: operstate is not enough * 1: online */ - if (!l->state) + if (!l->state || streq(l->state, "pending")) + /* If no state string exists, networkd (and possibly also udevd) has not detected the + * interface yet, that mean we cannot determine whether the interface is managed or + * not. Hence, return negative value. + * If the link is in pending state, then udevd has not processed the link, and networkd + * has not tried to find .network file for the link. Hence, return negative value. */ return log_link_debug_errno(l, SYNTHETIC_ERRNO(EAGAIN), - "link has not yet been processed by udev"); + "link has not yet been processed by udev: setup state is %s.", + strna(l->state)); - if (STR_IN_SET(l->state, "configuring", "pending")) + if (streq(l->state, "unmanaged")) { + /* If the link is in unmanaged state, then ignore the interface unless the interface is + * specified in '--interface/-i' option. */ + if (!hashmap_contains(m->command_line_interfaces_by_name, l->ifname)) { + log_link_debug(l, "link is not managed by networkd (yet?)."); + return 0; + } + + } else if (!streq(l->state, "configured")) + /* If the link is in non-configured state, return negative value here. */ return log_link_debug_errno(l, SYNTHETIC_ERRNO(EAGAIN), - "link is being processed by networkd"); + "link is being processed by networkd: setup state is %s.", + l->state); if (s.min < 0) s.min = m->required_operstate.min >= 0 ? m->required_operstate.min @@ -94,6 +110,7 @@ static int manager_link_is_online(Manager *m, Link *l, LinkOperationalStateRange } } + log_link_debug(l, "link is confiured by networkd and online."); return 1; }