diff options
author | Alvin Šipraga <alsi@bang-olufsen.dk> | 2021-03-30 21:39:18 +0200 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2021-05-19 10:33:55 +0900 |
commit | bcdcc59648dabefaed4267a2432a9e7928f93cb5 (patch) | |
tree | 97653a2cd0da13178b6c0dae7d7204e8ae7c4ff8 /src/network/networkd-state-file.c | |
parent | e7901aba1480db21e06e21cef4f6486ad71b2ec5 (diff) | |
download | systemd-bcdcc59648dabefaed4267a2432a9e7928f93cb5.tar.gz |
network: add an online state for links and manager
Add a new state of type LinkOnlineState which indicates whether a link
is online or not. The state is also used by networkd's manager to expose
the overall online state of the system.
The possible states are:
offline the link (or system) is offline
partial at least one required link is online (see below)
online all required links are online
For links, a link is defined to be "online" if:
- it is managed; and
- its operational state is within the range defined by
RequiredForOnline=; and
- it has an IPv4 address if RequiredFamilyForOnline=ipv4 or =both; and
- it has an IPv6 address if RequiredFamilyForOnline=ipv6 or =both.
A link is defined to be "offline" if:
- it is managed; and
- it is not online, i.e. its operational state is not within the range
defined by RequiredForOnline=, and/or it is missing an IP address in
a required address family.
Otherwise, the link online state is undefined (represented internally as
_LINK_ONLINE_STATUS_INVALID or -EINVAL). Put another way, networkd will
only offer a meaningful online state for managed links where
RequiredForOnline=yes.
For the manager, the online state is a function of the online state of
all links which are requried for online, i.e. RequiredForOnline=yes. If
all required links are online, then the manager online state is defined
to be "online". If at least one of the required links is online, then
the manager online state is defined to be "partial". If none of
the required links are online, then the manager online state is defined
to be "offline". If there are no managed links, or RequiredForOnline=no
for all managed links, then the manager online state is undefined as
above.
The purpose of the "partial" state is analogous to the --any switch in
systemd-networkd-wait-online.service(8). For example, a required link
which lacks a carrier on boot will not force the overall (manager)
online state to "offline" if there is an alternative link available.
Diffstat (limited to 'src/network/networkd-state-file.c')
-rw-r--r-- | src/network/networkd-state-file.c | 31 |
1 files changed, 29 insertions, 2 deletions
diff --git a/src/network/networkd-state-file.c b/src/network/networkd-state-file.c index f8243cc3ee..b9dab9b211 100644 --- a/src/network/networkd-state-file.c +++ b/src/network/networkd-state-file.c @@ -105,11 +105,13 @@ static int ordered_set_put_in4_addrv( int manager_save(Manager *m) { _cleanup_ordered_set_free_ OrderedSet *dns = NULL, *ntp = NULL, *sip = NULL, *search_domains = NULL, *route_domains = NULL; - const char *operstate_str, *carrier_state_str, *address_state_str, *ipv4_address_state_str, *ipv6_address_state_str; + const char *operstate_str, *carrier_state_str, *address_state_str, *ipv4_address_state_str, *ipv6_address_state_str, *online_state_str; LinkOperationalState operstate = LINK_OPERSTATE_OFF; LinkCarrierState carrier_state = LINK_CARRIER_STATE_OFF; LinkAddressState ipv4_address_state = LINK_ADDRESS_STATE_OFF, ipv6_address_state = LINK_ADDRESS_STATE_OFF, address_state = LINK_ADDRESS_STATE_OFF; + LinkOnlineState online_state; + size_t links_offline = 0, links_online = 0; _cleanup_(unlink_and_freep) char *temp_path = NULL; _cleanup_strv_free_ char **p = NULL; _cleanup_fclose_ FILE *f = NULL; @@ -134,6 +136,13 @@ int manager_save(Manager *m) { if (!link->network) continue; + if (link->network->required_for_online) { + if (link->online_state == LINK_ONLINE_STATE_OFFLINE) + links_offline++; + else if (link->online_state == LINK_ONLINE_STATE_ONLINE) + links_online++; + } + /* First add the static configured entries */ if (link->n_dns != UINT_MAX) r = ordered_set_put_dns_servers(&dns, link->ifindex, link->dns, link->n_dns); @@ -215,6 +224,10 @@ int manager_save(Manager *m) { if (carrier_state >= LINK_CARRIER_STATE_ENSLAVED) carrier_state = LINK_CARRIER_STATE_CARRIER; + online_state = links_online > 0 ? + (links_offline > 0 ? LINK_ONLINE_STATE_PARTIAL : LINK_ONLINE_STATE_ONLINE) : + (links_offline > 0 ? LINK_ONLINE_STATE_OFFLINE : _LINK_ONLINE_STATE_INVALID); + operstate_str = link_operstate_to_string(operstate); assert(operstate_str); @@ -245,6 +258,10 @@ int manager_save(Manager *m) { "IPV6_ADDRESS_STATE=%s\n", operstate_str, carrier_state_str, address_state_str, ipv4_address_state_str, ipv6_address_state_str); + online_state_str = link_online_state_to_string(online_state); + if (online_state_str) + fprintf(f, "ONLINE_STATE=%s\n", online_state_str); + ordered_set_print(f, "DNS=", dns); ordered_set_print(f, "NTP=", ntp); ordered_set_print(f, "SIP=", sip); @@ -291,6 +308,12 @@ int manager_save(Manager *m) { log_oom(); } + if (m->online_state != online_state) { + m->online_state = online_state; + if (strv_extend(&p, "OnlineState") < 0) + log_oom(); + } + if (p) { r = manager_send_changed_strv(m, p); if (r < 0) @@ -445,9 +468,13 @@ int link_save(Link *link) { if (link->network) { char **dhcp6_domains = NULL, **dhcp_domains = NULL; - const char *dhcp_domainname = NULL, *p; + const char *dhcp_domainname = NULL, *online_state, *p; bool space; + online_state = link_online_state_to_string(link->online_state); + if (online_state) + fprintf(f, "ONLINE_STATE=%s\n", online_state); + fprintf(f, "REQUIRED_FOR_ONLINE=%s\n", yes_no(link->network->required_for_online)); |