summaryrefslogtreecommitdiff
path: root/src/network
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2022-12-22 09:40:37 +0900
committerYu Watanabe <watanabe.yu+github@gmail.com>2022-12-22 09:40:46 +0900
commitab3aed4a0349bbaa26f53340770c1b59b463e05d (patch)
tree7554fa5206a917e7e4d7436cbea9d453bdd0fc86 /src/network
parentcf451f382a6ebf6ad34b36939ed4f8dee1c04e61 (diff)
downloadsystemd-ab3aed4a0349bbaa26f53340770c1b59b463e05d.tar.gz
wait-online: exit with success when all interfaces are ready or unmanaged
Previously, when neither '--any' nor '--interface' options specified, at least one of the interfaces must be in configured state. This patch makes wait-online exit with success even if all interfaces are in unmanaged state. This may break backward compatibility in a rare situation. But in most cases, this typically not change anything, as at least one interface is managed by networkd.service when it is enabled. This is mostly for making wait-online gracefully handle the case that networkd.service and wait-online.service are enabled by mistake. In such situation, all interfaces are typically not managed. Fixes #25813.
Diffstat (limited to 'src/network')
-rw-r--r--src/network/wait-online/manager.c107
1 files changed, 50 insertions, 57 deletions
diff --git a/src/network/wait-online/manager.c b/src/network/wait-online/manager.c
index 43ac10704b..f481149d81 100644
--- a/src/network/wait-online/manager.c
+++ b/src/network/wait-online/manager.c
@@ -61,9 +61,11 @@ static int manager_link_is_online(Manager *m, Link *l, LinkOperationalStateRange
assert(l);
/* This returns the following:
- * -EAGAIN: not processed by udev or networkd
- * 0: operstate is not enough
- * 1: online */
+ * -EAGAIN : not processed by udev
+ * -EBUSY : being processed by networkd
+ * -EADDRNOTAVAIL: requested conditions (operstate and/or addresses) are not satisfied
+ * false : unmanaged
+ * true : online */
if (!l->state || streq(l->state, "pending"))
/* If no state string exists, networkd (and possibly also udevd) has not detected the
@@ -79,13 +81,13 @@ static int manager_link_is_online(Manager *m, Link *l, LinkOperationalStateRange
/* If the link is in unmanaged state, then ignore the interface unless the interface is
* specified in '--interface/-i' option. */
if (!link_in_command_line_interfaces(l, m)) {
- log_link_debug(l, "link is not managed by networkd (yet?).");
- return 0;
+ log_link_debug(l, "link is not managed by networkd.");
+ return false;
}
} 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),
+ return log_link_debug_errno(l, SYNTHETIC_ERRNO(EBUSY),
"link is being processed by networkd: setup state is %s.",
l->state);
@@ -97,84 +99,75 @@ static int manager_link_is_online(Manager *m, Link *l, LinkOperationalStateRange
s.max = m->required_operstate.max >= 0 ? m->required_operstate.max
: l->required_operstate.max;
- if (l->operational_state < s.min || l->operational_state > s.max) {
- log_link_debug(l, "Operational state '%s' is not in range ['%s':'%s']",
- link_operstate_to_string(l->operational_state),
- link_operstate_to_string(s.min), link_operstate_to_string(s.max));
- return 0;
- }
+ if (l->operational_state < s.min || l->operational_state > s.max)
+ return log_link_debug_errno(l, SYNTHETIC_ERRNO(EADDRNOTAVAIL),
+ "Operational state '%s' is not in range ['%s':'%s']",
+ link_operstate_to_string(l->operational_state),
+ link_operstate_to_string(s.min), link_operstate_to_string(s.max));
required_family = m->required_family > 0 ? m->required_family : l->required_family;
needs_ipv4 = required_family & ADDRESS_FAMILY_IPV4;
needs_ipv6 = required_family & ADDRESS_FAMILY_IPV6;
if (s.min < LINK_OPERSTATE_ROUTABLE) {
- if (needs_ipv4 && l->ipv4_address_state < LINK_ADDRESS_STATE_DEGRADED) {
- log_link_debug(l, "No routable or link-local IPv4 address is configured.");
- return 0;
- }
+ if (needs_ipv4 && l->ipv4_address_state < LINK_ADDRESS_STATE_DEGRADED)
+ return log_link_debug_errno(l, SYNTHETIC_ERRNO(EADDRNOTAVAIL),
+ "No routable or link-local IPv4 address is configured.");
- if (needs_ipv6 && l->ipv6_address_state < LINK_ADDRESS_STATE_DEGRADED) {
- log_link_debug(l, "No routable or link-local IPv6 address is configured.");
- return 0;
- }
+ if (needs_ipv6 && l->ipv6_address_state < LINK_ADDRESS_STATE_DEGRADED)
+ return log_link_debug_errno(l, SYNTHETIC_ERRNO(EADDRNOTAVAIL),
+ "No routable or link-local IPv6 address is configured.");
} else {
- if (needs_ipv4 && l->ipv4_address_state < LINK_ADDRESS_STATE_ROUTABLE) {
- log_link_debug(l, "No routable IPv4 address is configured.");
- return 0;
- }
+ if (needs_ipv4 && l->ipv4_address_state < LINK_ADDRESS_STATE_ROUTABLE)
+ return log_link_debug_errno(l, SYNTHETIC_ERRNO(EADDRNOTAVAIL),
+ "No routable IPv4 address is configured.");
- if (needs_ipv6 && l->ipv6_address_state < LINK_ADDRESS_STATE_ROUTABLE) {
- log_link_debug(l, "No routable IPv6 address is configured.");
- return 0;
- }
+ if (needs_ipv6 && l->ipv6_address_state < LINK_ADDRESS_STATE_ROUTABLE)
+ return log_link_debug_errno(l, SYNTHETIC_ERRNO(EADDRNOTAVAIL),
+ "No routable IPv6 address is configured.");
}
log_link_debug(l, "link is configured by networkd and online.");
- return 1;
+ return true;
}
bool manager_configured(Manager *m) {
- bool one_ready = false;
- const char *ifname;
Link *l;
int r;
if (!hashmap_isempty(m->command_line_interfaces_by_name)) {
LinkOperationalStateRange *range;
+ const char *ifname;
/* wait for all the links given on the command line to appear */
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) {
- one_ready = true;
- continue;
- }
-
if (!l) {
- log_debug("still waiting for %s", ifname);
- if (!m->any)
- return false;
+ if (range->min == LINK_OPERSTATE_MISSING) {
+ if (m->any)
+ return true;
+ } else {
+ log_debug("still waiting for %s", ifname);
+ if (!m->any)
+ return false;
+ }
continue;
}
- if (manager_link_is_online(m, l, *range) <= 0) {
- if (!m->any)
- return false;
- continue;
- }
-
- one_ready = true;
+ r = manager_link_is_online(m, l, *range);
+ if (r <= 0 && !m->any)
+ return false;
+ if (r > 0 && m->any)
+ return true;
}
- /* all interfaces given by the command line are online, or
- * one of the specified interfaces is online. */
- return one_ready;
+ /* With '--any' : no interface is ready
+ * Without '--any': all interfaces are ready */
+ return !m->any;
}
- /* wait for all links networkd manages to be in admin state 'configured'
- * and at least one link to gain a carrier */
+ /* wait for all links networkd manages */
HASHMAP_FOREACH(l, m->links_by_index) {
if (manager_ignore_link(m, l)) {
log_link_debug(l, "link is ignored");
@@ -184,15 +177,15 @@ bool manager_configured(Manager *m) {
r = manager_link_is_online(m, l,
(LinkOperationalStateRange) { _LINK_OPERSTATE_INVALID,
_LINK_OPERSTATE_INVALID });
- if (r < 0 && !m->any)
+ if (r < 0 && !m->any) /* Unlike the above loop, unmanaged interfaces are ignored here. */
return false;
- if (r > 0)
- /* we wait for at least one link to be ready,
- * regardless of who manages it */
- one_ready = true;
+ if (r > 0 && m->any)
+ return true;
}
- return one_ready;
+ /* With '--any' : no interface is ready
+ * Without '--any': all interfaces are ready or unmanaged */
+ return !m->any;
}
static int manager_process_link(sd_netlink *rtnl, sd_netlink_message *mm, void *userdata) {