Merge pull request #11893 from yuwata/wait-online-take-operstate
wait-online: optionally take required minimum operational state
This commit is contained in:
+8
-3
@@ -115,6 +115,13 @@
|
||||
<para>the device has a carrier, but is not yet ready for normal traffic</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>degraded-carrier</term>
|
||||
<listitem>
|
||||
<para>for bond or bridge master, one of the bonding or bridge slave network interfaces is
|
||||
in off, no-carrier, or dormant state</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>carrier</term>
|
||||
<listitem>
|
||||
@@ -125,9 +132,7 @@
|
||||
<varlistentry>
|
||||
<term>degraded</term>
|
||||
<listitem>
|
||||
<para>the link has carrier and addresses valid on the local link configured, or for bond
|
||||
or bridge master, one of the bonding or bridge slave network interfaces is in off,
|
||||
no-carrier, or dormant</para>
|
||||
<para>the link has carrier and addresses valid on the local link configured</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
SPDX-License-Identifier: LGPL-2.1+
|
||||
-->
|
||||
|
||||
<refentry id="systemd-networkd-wait-online.service" conditional='ENABLE_NETWORKD'>
|
||||
<refentry id="systemd-networkd-wait-online.service" conditional='ENABLE_NETWORKD'
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||
|
||||
<refentryinfo>
|
||||
<title>systemd-networkd-wait-online.service</title>
|
||||
@@ -48,8 +49,8 @@
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><option>-i</option></term>
|
||||
<term><option>--interface=</option></term>
|
||||
<term><option>-i</option> <replaceable>INTERFACE</replaceable><optional>:<replaceable>OPERSTATE</replaceable></optional></term>
|
||||
<term><option>--interface=</option><replaceable>INTERFACE</replaceable><optional>:<replaceable>OPERSTATE</replaceable></optional></term>
|
||||
|
||||
<listitem><para>Network interface to wait for before deciding
|
||||
if the system is online. This is useful when a system has
|
||||
@@ -57,21 +58,53 @@
|
||||
one is necessary to access some network resources. This option
|
||||
may be used more than once to wait for multiple network
|
||||
interfaces. When used, all other interfaces are ignored.
|
||||
Optinally, required minimum operational state can be
|
||||
specified after a colon <literal>:</literal>. Please see
|
||||
<citerefentry><refentrytitle>networkctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
|
||||
for possible operational states. If the operational state is not specified here, then
|
||||
the value from <varname>RequiredForOnline=</varname> in the corresponding
|
||||
<filename>.network</filename> file is used if present, and <literal>degraded</literal> otherwise.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--ignore=</option></term>
|
||||
<term><option>--ignore=</option><replaceable>INTERFACE</replaceable></term>
|
||||
|
||||
<listitem><para>Network interfaces to be ignored when deciding
|
||||
if the system is online. By default, only the loopback
|
||||
interface is ignored. This option may be used more than once
|
||||
to ignore multiple network interfaces. </para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--timeout=</option></term>
|
||||
<term><option>-o</option> <replaceable>OPERSTATE</replaceable></term>
|
||||
<term><option>--operational-state=</option><replaceable>OPERSTATE</replaceable></term>
|
||||
|
||||
<listitem><para>Takes an operational state. Please see
|
||||
<citerefentry><refentrytitle>networkctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
|
||||
for possible operational states. If set, the specified value overrides
|
||||
<varname>RequiredForOnline=</varname> settings in <filename>.network</filename> files.
|
||||
But this does not override operational states specified in <option>--interface</option> option.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--timeout=</option> <replaceable>SECS</replaceable></term>
|
||||
|
||||
<listitem><para>Fail the service if the network is not online
|
||||
by the time the timeout elapses. A timeout of 0 disables the
|
||||
timeout. Defaults to 120 seconds. </para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>-q</option></term>
|
||||
<term><option>--quiet</option></term>
|
||||
|
||||
<listitem><para>Suppress log messages.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<xi:include href="standard-options.xml" xpointer="help" />
|
||||
<xi:include href="standard-options.xml" xpointer="version" />
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
@@ -80,7 +113,8 @@
|
||||
<para>
|
||||
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
|
||||
<citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
|
||||
<citerefentry><refentrytitle>systemd-networkd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
|
||||
<citerefentry><refentrytitle>systemd-networkd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
|
||||
<citerefentry><refentrytitle>networkctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
|
||||
+10
-6
@@ -255,15 +255,19 @@
|
||||
<varlistentry>
|
||||
<term><varname>RequiredForOnline=</varname></term>
|
||||
<listitem>
|
||||
<para>Takes a boolean. When <literal>yes</literal>, the network is deemed
|
||||
required when determining whether the system is online when running
|
||||
<literal>systemd-networkd-wait-online</literal>.
|
||||
When <literal>no</literal>, the network is ignored when checking for
|
||||
online state. Defaults to <literal>yes</literal>.</para>
|
||||
<para>Takes a boolean or operational state. Please see
|
||||
<citerefentry><refentrytitle>networkctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
|
||||
for possible operational states. When <literal>yes</literal>, the network is deemed required when
|
||||
determining whether the system is online when running
|
||||
<command>systemd-networkd-wait-online</command>. When <literal>no</literal>, the network is ignored
|
||||
when checking for online state. When an operational state is set, <literal>yes</literal> is implied,
|
||||
and this controls the operational state required for the network interface to be considered online.
|
||||
Defaults to <literal>yes</literal>.</para>
|
||||
|
||||
<para>The network will be brought up normally in all cases, but in
|
||||
the event that there is no address being assigned by DHCP or the
|
||||
cable is not plugged in, the link will simply remain offline and be
|
||||
skipped automatically by <literal>systemd-networkd-wait-online</literal>
|
||||
skipped automatically by <command>systemd-networkd-wait-online</command>
|
||||
if <literal>RequiredForOnline=no</literal>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
@@ -412,9 +412,11 @@ static inline char **ordered_hashmap_get_strv(OrderedHashmap *h) {
|
||||
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, hashmap_free);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, hashmap_free_free);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, hashmap_free_free_key);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, hashmap_free_free_free);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(OrderedHashmap*, ordered_hashmap_free);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(OrderedHashmap*, ordered_hashmap_free_free);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(OrderedHashmap*, ordered_hashmap_free_free_key);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(OrderedHashmap*, ordered_hashmap_free_free_free);
|
||||
|
||||
#define _cleanup_hashmap_free_ _cleanup_(hashmap_freep)
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "alloc-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "network-util.h"
|
||||
#include "string-table.h"
|
||||
#include "strv.h"
|
||||
|
||||
bool network_is_online(void) {
|
||||
@@ -18,3 +19,16 @@ bool network_is_online(void) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static const char* const link_operstate_table[_LINK_OPERSTATE_MAX] = {
|
||||
[LINK_OPERSTATE_OFF] = "off",
|
||||
[LINK_OPERSTATE_NO_CARRIER] = "no-carrier",
|
||||
[LINK_OPERSTATE_DORMANT] = "dormant",
|
||||
[LINK_OPERSTATE_DEGRADED_CARRIER] = "degraded-carrier",
|
||||
[LINK_OPERSTATE_CARRIER] = "carrier",
|
||||
[LINK_OPERSTATE_DEGRADED] = "degraded",
|
||||
[LINK_OPERSTATE_ENSLAVED] = "enslaved",
|
||||
[LINK_OPERSTATE_ROUTABLE] = "routable",
|
||||
};
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP(link_operstate, LinkOperationalState);
|
||||
|
||||
@@ -3,4 +3,22 @@
|
||||
|
||||
#include "sd-network.h"
|
||||
|
||||
#include "macro.h"
|
||||
|
||||
bool network_is_online(void);
|
||||
|
||||
typedef enum LinkOperationalState {
|
||||
LINK_OPERSTATE_OFF,
|
||||
LINK_OPERSTATE_NO_CARRIER,
|
||||
LINK_OPERSTATE_DORMANT,
|
||||
LINK_OPERSTATE_DEGRADED_CARRIER,
|
||||
LINK_OPERSTATE_CARRIER,
|
||||
LINK_OPERSTATE_DEGRADED,
|
||||
LINK_OPERSTATE_ENSLAVED,
|
||||
LINK_OPERSTATE_ROUTABLE,
|
||||
_LINK_OPERSTATE_MAX,
|
||||
_LINK_OPERSTATE_INVALID = -1
|
||||
} LinkOperationalState;
|
||||
|
||||
const char* link_operstate_to_string(LinkOperationalState s) _const_;
|
||||
LinkOperationalState link_operstate_from_string(const char *s) _pure_;
|
||||
|
||||
@@ -164,6 +164,27 @@ _public_ int sd_network_link_get_required_for_online(int ifindex) {
|
||||
return parse_boolean(s);
|
||||
}
|
||||
|
||||
_public_ int sd_network_link_get_required_operstate_for_online(int ifindex, char **state) {
|
||||
_cleanup_free_ char *s = NULL;
|
||||
int r;
|
||||
|
||||
assert_return(state, -EINVAL);
|
||||
|
||||
r = network_link_get_string(ifindex, "REQUIRED_OPER_STATE_FOR_ONLINE", &s);
|
||||
if (r < 0) {
|
||||
if (r != -ENODATA)
|
||||
return r;
|
||||
|
||||
/* For compatibility, assuming degraded. */
|
||||
s = strdup("degraded");
|
||||
if (!s)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
*state = TAKE_PTR(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_network_link_get_llmnr(int ifindex, char **llmnr) {
|
||||
return network_link_get_string(ifindex, "LLMNR", llmnr);
|
||||
}
|
||||
|
||||
@@ -213,7 +213,7 @@ static int list_links(int argc, char *argv[], void *userdata) {
|
||||
(void) pager_open(arg_pager_flags);
|
||||
|
||||
if (arg_legend)
|
||||
printf("%3s %-16s %-18s %-11s %-10s\n",
|
||||
printf("%3s %-16s %-18s %-16s %-10s\n",
|
||||
"IDX",
|
||||
"LINK",
|
||||
"TYPE",
|
||||
@@ -241,7 +241,7 @@ static int list_links(int argc, char *argv[], void *userdata) {
|
||||
|
||||
t = link_get_type_string(links[i].iftype, d);
|
||||
|
||||
printf("%3i %-16s %-18s %s%-11s%s %s%-10s%s\n",
|
||||
printf("%3i %-16s %-18s %s%-16s%s %s%-10s%s\n",
|
||||
links[i].ifindex, links[i].name, strna(t),
|
||||
on_color_operational, strna(operational_state), off_color_operational,
|
||||
on_color_setup, strna(setup_state), off_color_setup);
|
||||
|
||||
@@ -407,15 +407,14 @@ void link_update_operstate(Link *link, bool also_update_master) {
|
||||
link_is_enslaved(link))
|
||||
operstate = LINK_OPERSTATE_ENSLAVED;
|
||||
|
||||
if (IN_SET(operstate, LINK_OPERSTATE_CARRIER, LINK_OPERSTATE_ENSLAVED, LINK_OPERSTATE_ROUTABLE)) {
|
||||
if (operstate >= LINK_OPERSTATE_CARRIER) {
|
||||
Link *slave;
|
||||
|
||||
HASHMAP_FOREACH(slave, link->slaves, i) {
|
||||
link_update_operstate(slave, false);
|
||||
|
||||
if (IN_SET(slave->operstate,
|
||||
LINK_OPERSTATE_OFF, LINK_OPERSTATE_NO_CARRIER, LINK_OPERSTATE_DORMANT))
|
||||
operstate = LINK_OPERSTATE_DEGRADED;
|
||||
if (slave->operstate < LINK_OPERSTATE_CARRIER)
|
||||
operstate = LINK_OPERSTATE_DEGRADED_CARRIER;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4004,6 +4003,9 @@ int link_save(Link *link) {
|
||||
fprintf(f, "REQUIRED_FOR_ONLINE=%s\n",
|
||||
yes_no(link->network->required_for_online));
|
||||
|
||||
fprintf(f, "REQUIRED_OPER_STATE_FOR_ONLINE=%s\n",
|
||||
strempty(link_operstate_to_string(link->network->required_operstate_for_online)));
|
||||
|
||||
if (link->dhcp6_client) {
|
||||
r = sd_dhcp6_client_get_lease(link->dhcp6_client, &dhcp6_lease);
|
||||
if (r < 0 && r != -ENOMSG)
|
||||
@@ -4306,15 +4308,3 @@ static const char* const link_state_table[_LINK_STATE_MAX] = {
|
||||
};
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);
|
||||
|
||||
static const char* const link_operstate_table[_LINK_OPERSTATE_MAX] = {
|
||||
[LINK_OPERSTATE_OFF] = "off",
|
||||
[LINK_OPERSTATE_NO_CARRIER] = "no-carrier",
|
||||
[LINK_OPERSTATE_DORMANT] = "dormant",
|
||||
[LINK_OPERSTATE_CARRIER] = "carrier",
|
||||
[LINK_OPERSTATE_DEGRADED] = "degraded",
|
||||
[LINK_OPERSTATE_ENSLAVED] = "enslaved",
|
||||
[LINK_OPERSTATE_ROUTABLE] = "routable",
|
||||
};
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP(link_operstate, LinkOperationalState);
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
#include "sd-netlink.h"
|
||||
|
||||
#include "list.h"
|
||||
#include "log-link.h"
|
||||
#include "network-util.h"
|
||||
#include "set.h"
|
||||
|
||||
typedef enum LinkState {
|
||||
@@ -28,18 +30,6 @@ typedef enum LinkState {
|
||||
_LINK_STATE_INVALID = -1
|
||||
} LinkState;
|
||||
|
||||
typedef enum LinkOperationalState {
|
||||
LINK_OPERSTATE_OFF,
|
||||
LINK_OPERSTATE_NO_CARRIER,
|
||||
LINK_OPERSTATE_DORMANT,
|
||||
LINK_OPERSTATE_CARRIER,
|
||||
LINK_OPERSTATE_DEGRADED,
|
||||
LINK_OPERSTATE_ENSLAVED,
|
||||
LINK_OPERSTATE_ROUTABLE,
|
||||
_LINK_OPERSTATE_MAX,
|
||||
_LINK_OPERSTATE_INVALID = -1
|
||||
} LinkOperationalState;
|
||||
|
||||
typedef struct Manager Manager;
|
||||
typedef struct Network Network;
|
||||
typedef struct Address Address;
|
||||
@@ -180,9 +170,6 @@ int dhcp6_lease_pd_prefix_lost(sd_dhcp6_client *client, Link* link);
|
||||
const char* link_state_to_string(LinkState s) _const_;
|
||||
LinkState link_state_from_string(const char *s) _pure_;
|
||||
|
||||
const char* link_operstate_to_string(LinkOperationalState s) _const_;
|
||||
LinkOperationalState link_operstate_from_string(const char *s) _pure_;
|
||||
|
||||
extern const sd_bus_vtable link_vtable[];
|
||||
|
||||
int link_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error);
|
||||
@@ -193,30 +180,6 @@ uint32_t link_get_vrf_table(Link *link);
|
||||
uint32_t link_get_dhcp_route_table(Link *link);
|
||||
uint32_t link_get_ipv6_accept_ra_route_table(Link *link);
|
||||
|
||||
/* Macros which append INTERFACE= to the message */
|
||||
|
||||
#define log_link_full(link, level, error, ...) \
|
||||
({ \
|
||||
const Link *_l = (link); \
|
||||
_l ? log_object_internal(level, error, __FILE__, __LINE__, __func__, "INTERFACE=", _l->ifname, NULL, NULL, ##__VA_ARGS__) : \
|
||||
log_internal(level, error, __FILE__, __LINE__, __func__, ##__VA_ARGS__); \
|
||||
}) \
|
||||
|
||||
#define log_link_debug(link, ...) log_link_full(link, LOG_DEBUG, 0, ##__VA_ARGS__)
|
||||
#define log_link_info(link, ...) log_link_full(link, LOG_INFO, 0, ##__VA_ARGS__)
|
||||
#define log_link_notice(link, ...) log_link_full(link, LOG_NOTICE, 0, ##__VA_ARGS__)
|
||||
#define log_link_warning(link, ...) log_link_full(link, LOG_WARNING, 0, ##__VA_ARGS__)
|
||||
#define log_link_error(link, ...) log_link_full(link, LOG_ERR, 0, ##__VA_ARGS__)
|
||||
|
||||
#define log_link_debug_errno(link, error, ...) log_link_full(link, LOG_DEBUG, error, ##__VA_ARGS__)
|
||||
#define log_link_info_errno(link, error, ...) log_link_full(link, LOG_INFO, error, ##__VA_ARGS__)
|
||||
#define log_link_notice_errno(link, error, ...) log_link_full(link, LOG_NOTICE, error, ##__VA_ARGS__)
|
||||
#define log_link_warning_errno(link, error, ...) log_link_full(link, LOG_WARNING, error, ##__VA_ARGS__)
|
||||
#define log_link_error_errno(link, error, ...) log_link_full(link, LOG_ERR, error, ##__VA_ARGS__)
|
||||
|
||||
#define LOG_LINK_MESSAGE(link, fmt, ...) "MESSAGE=%s: " fmt, (link)->ifname, ##__VA_ARGS__
|
||||
#define LOG_LINK_INTERFACE(link) "INTERFACE=%s", (link)->ifname
|
||||
|
||||
#define ADDRESS_FMT_VAL(address) \
|
||||
be32toh((address).s_addr) >> 24, \
|
||||
(be32toh((address).s_addr) >> 16) & 0xFFu, \
|
||||
|
||||
@@ -36,7 +36,7 @@ Link.ARP, config_parse_tristate,
|
||||
Link.Multicast, config_parse_tristate, 0, offsetof(Network, multicast)
|
||||
Link.AllMulticast, config_parse_tristate, 0, offsetof(Network, allmulticast)
|
||||
Link.Unmanaged, config_parse_bool, 0, offsetof(Network, unmanaged)
|
||||
Link.RequiredForOnline, config_parse_bool, 0, offsetof(Network, required_for_online)
|
||||
Link.RequiredForOnline, config_parse_required_for_online, 0, 0
|
||||
Network.Description, config_parse_string, 0, offsetof(Network, description)
|
||||
Network.Bridge, config_parse_ifname, 0, offsetof(Network, bridge_name)
|
||||
Network.Bond, config_parse_ifname, 0, offsetof(Network, bond_name)
|
||||
|
||||
@@ -366,6 +366,7 @@ int network_load_one(Manager *manager, const char *filename) {
|
||||
.name = TAKE_PTR(name),
|
||||
|
||||
.required_for_online = true,
|
||||
.required_operstate_for_online = LINK_OPERSTATE_DEGRADED,
|
||||
.dhcp = ADDRESS_FAMILY_NO,
|
||||
.dhcp_use_ntp = true,
|
||||
.dhcp_use_dns = true,
|
||||
@@ -1671,3 +1672,46 @@ int config_parse_iaid(const char *unit,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_required_for_online(
|
||||
const char *unit,
|
||||
const char *filename,
|
||||
unsigned line,
|
||||
const char *section,
|
||||
unsigned section_line,
|
||||
const char *lvalue,
|
||||
int ltype,
|
||||
const char *rvalue,
|
||||
void *data,
|
||||
void *userdata) {
|
||||
|
||||
Network *network = data;
|
||||
LinkOperationalState s;
|
||||
bool required = true;
|
||||
int r;
|
||||
|
||||
if (isempty(rvalue)) {
|
||||
network->required_for_online = true;
|
||||
network->required_operstate_for_online = LINK_OPERSTATE_DEGRADED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
s = link_operstate_from_string(rvalue);
|
||||
if (s < 0) {
|
||||
r = parse_boolean(rvalue);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to parse %s= setting, ignoring assignment: %s",
|
||||
lvalue, rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
required = r;
|
||||
s = LINK_OPERSTATE_DEGRADED;
|
||||
}
|
||||
|
||||
network->required_for_online = required;
|
||||
network->required_operstate_for_online = s;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -241,6 +241,7 @@ struct Network {
|
||||
bool iaid_set;
|
||||
|
||||
bool required_for_online; /* Is this network required to be considered online? */
|
||||
LinkOperationalState required_operstate_for_online;
|
||||
|
||||
LLDPMode lldp_mode; /* LLDP reception */
|
||||
LLDPEmit lldp_emit; /* LLDP transmission */
|
||||
@@ -324,6 +325,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_section_route_table);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_user_class);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_ntp);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_iaid);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_required_for_online);
|
||||
/* Legacy IPv4LL support */
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_ipv4ll);
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
int link_new(Manager *m, Link **ret, int ifindex, const char *ifname) {
|
||||
_cleanup_(link_freep) Link *l = NULL;
|
||||
_cleanup_free_ char *n = NULL;
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
@@ -23,30 +24,33 @@ int link_new(Manager *m, Link **ret, int ifindex, const char *ifname) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
l = new0(Link, 1);
|
||||
n = strdup(ifname);
|
||||
if (!n)
|
||||
return -ENOMEM;
|
||||
|
||||
l = new(Link, 1);
|
||||
if (!l)
|
||||
return -ENOMEM;
|
||||
|
||||
l->manager = m;
|
||||
|
||||
l->ifname = strdup(ifname);
|
||||
if (!l->ifname)
|
||||
return -ENOMEM;
|
||||
*l = (Link) {
|
||||
.manager = m,
|
||||
.ifname = TAKE_PTR(n),
|
||||
.ifindex = ifindex,
|
||||
.required_operstate = LINK_OPERSTATE_DEGRADED,
|
||||
};
|
||||
|
||||
r = hashmap_put(m->links_by_name, l->ifname, l);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
l->ifindex = ifindex;
|
||||
|
||||
r = hashmap_put(m->links, INT_TO_PTR(ifindex), l);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (ret)
|
||||
*ret = l;
|
||||
l = NULL;
|
||||
|
||||
TAKE_PTR(l);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -60,6 +64,7 @@ Link *link_free(Link *l) {
|
||||
hashmap_remove(l->manager->links_by_name, l->ifname);
|
||||
}
|
||||
|
||||
free(l->state);
|
||||
free(l->ifname);
|
||||
return mfree(l);
|
||||
}
|
||||
@@ -87,9 +92,8 @@ int link_update_rtnl(Link *l, sd_netlink_message *m) {
|
||||
if (!new_ifname)
|
||||
return -ENOMEM;
|
||||
|
||||
hashmap_remove(l->manager->links_by_name, l->ifname);
|
||||
free(l->ifname);
|
||||
l->ifname = new_ifname;
|
||||
assert_se(hashmap_remove(l->manager->links_by_name, l->ifname) == l);
|
||||
free_and_replace(l->ifname, new_ifname);
|
||||
|
||||
r = hashmap_put(l->manager->links_by_name, l->ifname, l);
|
||||
if (r < 0)
|
||||
@@ -100,17 +104,49 @@ int link_update_rtnl(Link *l, sd_netlink_message *m) {
|
||||
}
|
||||
|
||||
int link_update_monitor(Link *l) {
|
||||
_cleanup_free_ char *operstate = NULL, *required_operstate = NULL, *state = NULL;
|
||||
LinkOperationalState s;
|
||||
int r, ret = 0;
|
||||
|
||||
assert(l);
|
||||
assert(l->ifname);
|
||||
|
||||
l->required_for_online = sd_network_link_get_required_for_online(l->ifindex) != 0;
|
||||
r = sd_network_link_get_required_for_online(l->ifindex);
|
||||
if (r < 0)
|
||||
ret = log_link_debug_errno(l, r, "Failed to determine whether the link is required for online or not, "
|
||||
"ignoring: %m");
|
||||
else
|
||||
l->required_for_online = r > 0;
|
||||
|
||||
l->operational_state = mfree(l->operational_state);
|
||||
r = sd_network_link_get_required_operstate_for_online(l->ifindex, &required_operstate);
|
||||
if (r < 0)
|
||||
ret = log_link_debug_errno(l, r, "Failed to get required operational state, ignoring: %m");
|
||||
else {
|
||||
s = link_operstate_from_string(required_operstate);
|
||||
if (s < 0)
|
||||
ret = log_link_debug_errno(l, SYNTHETIC_ERRNO(EINVAL),
|
||||
"Failed to parse required operational state, ignoring: %m");
|
||||
else
|
||||
l->required_operstate = s;
|
||||
}
|
||||
|
||||
sd_network_link_get_operational_state(l->ifindex, &l->operational_state);
|
||||
r = sd_network_link_get_operational_state(l->ifindex, &operstate);
|
||||
if (r < 0)
|
||||
ret = log_link_debug_errno(l, r, "Failed to get operational state, ignoring: %m");
|
||||
else {
|
||||
s = link_operstate_from_string(operstate);
|
||||
if (s < 0)
|
||||
ret = log_link_debug_errno(l, SYNTHETIC_ERRNO(EINVAL),
|
||||
"Failed to parse operational state, ignoring: %m");
|
||||
else
|
||||
l->operational_state = s;
|
||||
}
|
||||
|
||||
l->state = mfree(l->state);
|
||||
r = sd_network_link_get_setup_state(l->ifindex, &state);
|
||||
if (r < 0)
|
||||
ret = log_link_debug_errno(l, r, "Failed to get setup state, ignoring: %m");
|
||||
else
|
||||
free_and_replace(l->state, state);
|
||||
|
||||
sd_network_link_get_setup_state(l->ifindex, &l->state);
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
|
||||
#include "sd-netlink.h"
|
||||
|
||||
#include "log-link.h"
|
||||
#include "network-util.h"
|
||||
|
||||
typedef struct Link Link;
|
||||
typedef struct Manager Manager;
|
||||
|
||||
@@ -14,7 +17,8 @@ struct Link {
|
||||
unsigned flags;
|
||||
|
||||
bool required_for_online;
|
||||
char *operational_state;
|
||||
LinkOperationalState required_operstate;
|
||||
LinkOperationalState operational_state;
|
||||
char *state;
|
||||
};
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include "time-util.h"
|
||||
#include "util.h"
|
||||
|
||||
bool manager_ignore_link(Manager *m, Link *link) {
|
||||
static bool manager_ignore_link(Manager *m, Link *link) {
|
||||
assert(m);
|
||||
assert(link);
|
||||
|
||||
@@ -22,7 +22,7 @@ bool manager_ignore_link(Manager *m, Link *link) {
|
||||
return true;
|
||||
|
||||
/* if interfaces are given on the command line, ignore all others */
|
||||
if (m->interfaces && !strv_contains(m->interfaces, link->ifname))
|
||||
if (m->interfaces && !hashmap_contains(m->interfaces, link->ifname))
|
||||
return true;
|
||||
|
||||
if (!link->required_for_online)
|
||||
@@ -32,45 +32,73 @@ bool manager_ignore_link(Manager *m, Link *link) {
|
||||
return strv_fnmatch(m->ignore, link->ifname, 0);
|
||||
}
|
||||
|
||||
bool manager_all_configured(Manager *m) {
|
||||
Iterator i;
|
||||
Link *l;
|
||||
char **ifname;
|
||||
bool one_ready = false;
|
||||
static int manager_link_is_online(Manager *m, Link *l, LinkOperationalState s) {
|
||||
/* This returns the following:
|
||||
* -EAGAIN: not processed by udev or networkd
|
||||
* 0: operstate is not enough
|
||||
* 1: online */
|
||||
|
||||
/* wait for all the links given on the command line to appear */
|
||||
STRV_FOREACH(ifname, m->interfaces) {
|
||||
l = hashmap_get(m->links_by_name, *ifname);
|
||||
if (!l) {
|
||||
log_debug("still waiting for %s", *ifname);
|
||||
return false;
|
||||
}
|
||||
if (!l->state)
|
||||
return log_link_debug_errno(l, SYNTHETIC_ERRNO(EAGAIN),
|
||||
"link has not yet been processed by udev");
|
||||
|
||||
if (STR_IN_SET(l->state, "configuring", "pending"))
|
||||
return log_link_debug_errno(l, SYNTHETIC_ERRNO(EAGAIN),
|
||||
"link is being processed by networkd");
|
||||
|
||||
if (s < 0)
|
||||
s = m->required_operstate >= 0 ? m->required_operstate : l->required_operstate;
|
||||
|
||||
if (l->operational_state < s) {
|
||||
log_link_debug(l, "Operational state '%s' is below '%s'",
|
||||
link_operstate_to_string(l->operational_state),
|
||||
link_operstate_to_string(s));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool manager_all_configured(Manager *m) {
|
||||
bool one_ready = false;
|
||||
Iterator i;
|
||||
const char *ifname;
|
||||
void *p;
|
||||
Link *l;
|
||||
int r;
|
||||
|
||||
/* wait for all the links given on the command line to appear */
|
||||
HASHMAP_FOREACH_KEY(p, ifname, m->interfaces, i) {
|
||||
LinkOperationalState s = PTR_TO_INT(p);
|
||||
|
||||
l = hashmap_get(m->links_by_name, ifname);
|
||||
if (!l) {
|
||||
log_debug("still waiting for %s", ifname);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (manager_link_is_online(m, l, s) <= 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!hashmap_isempty(m->interfaces))
|
||||
/* all interfaces given by the command line are online. */
|
||||
return true;
|
||||
|
||||
/* wait for all links networkd manages to be in admin state 'configured'
|
||||
and at least one link to gain a carrier */
|
||||
* and at least one link to gain a carrier */
|
||||
HASHMAP_FOREACH(l, m->links, i) {
|
||||
if (manager_ignore_link(m, l)) {
|
||||
log_info("ignoring: %s", l->ifname);
|
||||
log_link_info(l, "link is ignored");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!l->state) {
|
||||
log_debug("link %s has not yet been processed by udev",
|
||||
l->ifname);
|
||||
r = manager_link_is_online(m, l, _LINK_OPERSTATE_INVALID);
|
||||
if (r < 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (STR_IN_SET(l->state, "configuring", "pending")) {
|
||||
log_debug("link %s is being processed by networkd",
|
||||
l->ifname);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (l->operational_state &&
|
||||
STR_IN_SET(l->operational_state, "degraded", "routable"))
|
||||
if (r > 0)
|
||||
/* we wait for at least one link to be ready,
|
||||
regardless of who manages it */
|
||||
* regardless of who manages it */
|
||||
one_ready = true;
|
||||
}
|
||||
|
||||
@@ -120,21 +148,21 @@ static int manager_process_link(sd_netlink *rtnl, sd_netlink_message *mm, void *
|
||||
r = link_new(m, &l, ifindex, ifname);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to create link object: %m");
|
||||
|
||||
r = link_update_monitor(l);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to initialize link object: %m");
|
||||
}
|
||||
|
||||
r = link_update_rtnl(l, mm);
|
||||
if (r < 0)
|
||||
return log_warning_errno(r, "Failed to process RTNL link message: %m");;
|
||||
log_link_warning_errno(l, r, "Failed to process RTNL link message, ignoring: %m");
|
||||
|
||||
r = link_update_monitor(l);
|
||||
if (r < 0)
|
||||
log_link_warning_errno(l, r, "Failed to update link state, ignoring: %m");
|
||||
|
||||
break;
|
||||
|
||||
case RTM_DELLINK:
|
||||
if (l) {
|
||||
log_debug("Removing link %i", l->ifindex);
|
||||
log_link_debug(l, "Removing link");
|
||||
link_free(l);
|
||||
}
|
||||
|
||||
@@ -217,7 +245,7 @@ static int on_network_event(sd_event_source *s, int fd, uint32_t revents, void *
|
||||
HASHMAP_FOREACH(l, m->links, i) {
|
||||
r = link_update_monitor(l);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to update monitor information for %i: %m", l->ifindex);
|
||||
log_link_warning_errno(l, r, "Failed to update monitor information: %m");
|
||||
}
|
||||
|
||||
if (manager_all_configured(m))
|
||||
@@ -251,18 +279,22 @@ static int manager_network_monitor_listen(Manager *m) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int manager_new(Manager **ret, char **interfaces, char **ignore, usec_t timeout) {
|
||||
int manager_new(Manager **ret, Hashmap *interfaces, char **ignore,
|
||||
LinkOperationalState required_operstate, usec_t timeout) {
|
||||
_cleanup_(manager_freep) Manager *m = NULL;
|
||||
int r;
|
||||
|
||||
assert(ret);
|
||||
|
||||
m = new0(Manager, 1);
|
||||
m = new(Manager, 1);
|
||||
if (!m)
|
||||
return -ENOMEM;
|
||||
|
||||
m->interfaces = interfaces;
|
||||
m->ignore = ignore;
|
||||
*m = (Manager) {
|
||||
.interfaces = interfaces,
|
||||
.ignore = ignore,
|
||||
.required_operstate = required_operstate,
|
||||
};
|
||||
|
||||
r = sd_event_default(&m->event);
|
||||
if (r < 0)
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "sd-network.h"
|
||||
|
||||
#include "hashmap.h"
|
||||
#include "network-util.h"
|
||||
|
||||
typedef struct Manager Manager;
|
||||
typedef struct Link Link;
|
||||
@@ -14,9 +15,12 @@ struct Manager {
|
||||
Hashmap *links;
|
||||
Hashmap *links_by_name;
|
||||
|
||||
char **interfaces;
|
||||
/* Do not free the two members below. */
|
||||
Hashmap *interfaces;
|
||||
char **ignore;
|
||||
|
||||
LinkOperationalState required_operstate;
|
||||
|
||||
sd_netlink *rtnl;
|
||||
sd_event_source *rtnl_event_source;
|
||||
|
||||
@@ -27,9 +31,9 @@ struct Manager {
|
||||
};
|
||||
|
||||
void manager_free(Manager *m);
|
||||
int manager_new(Manager **ret, char **interfaces, char **ignore, usec_t timeout);
|
||||
int manager_new(Manager **ret, Hashmap *interfaces, char **ignore,
|
||||
LinkOperationalState required_operstate, usec_t timeout);
|
||||
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
|
||||
|
||||
bool manager_all_configured(Manager *m);
|
||||
bool manager_ignore_link(Manager *m, Link *link);
|
||||
|
||||
@@ -9,14 +9,16 @@
|
||||
#include "manager.h"
|
||||
#include "pretty-print.h"
|
||||
#include "signal-util.h"
|
||||
#include "socket-util.h"
|
||||
#include "strv.h"
|
||||
|
||||
static bool arg_quiet = false;
|
||||
static usec_t arg_timeout = 120 * USEC_PER_SEC;
|
||||
static char **arg_interfaces = NULL;
|
||||
static Hashmap *arg_interfaces = NULL;
|
||||
static char **arg_ignore = NULL;
|
||||
static LinkOperationalState arg_required_operstate = _LINK_OPERSTATE_INVALID;
|
||||
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_interfaces, strv_freep);
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_interfaces, hashmap_free_free_keyp);
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_ignore, strv_freep);
|
||||
|
||||
static int help(void) {
|
||||
@@ -32,8 +34,11 @@ static int help(void) {
|
||||
" -h --help Show this help\n"
|
||||
" --version Print version string\n"
|
||||
" -q --quiet Do not show status information\n"
|
||||
" -i --interface=INTERFACE Block until at least these interfaces have appeared\n"
|
||||
" -i --interface=INTERFACE[:OPERSTATE]\n"
|
||||
" Block until at least these interfaces have appeared\n"
|
||||
" --ignore=INTERFACE Don't take these interfaces into account\n"
|
||||
" -o --operational-state=OPERSTATE\n"
|
||||
" Required operational state\n"
|
||||
" --timeout=SECS Maximum time to wait for network connectivity\n"
|
||||
"\nSee the %s for details.\n"
|
||||
, program_invocation_short_name
|
||||
@@ -43,6 +48,52 @@ static int help(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_interface_with_operstate(const char *str) {
|
||||
_cleanup_free_ char *ifname = NULL;
|
||||
LinkOperationalState s;
|
||||
const char *p;
|
||||
int r;
|
||||
|
||||
assert(str);
|
||||
|
||||
p = strchr(str, ':');
|
||||
if (p) {
|
||||
if (isempty(p + 1))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"Operational state is empty.");
|
||||
|
||||
s = link_operstate_from_string(p + 1);
|
||||
if (s < 0)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"Invalid operational state '%s'", p + 1);
|
||||
|
||||
ifname = strndup(optarg, p - optarg);
|
||||
} else {
|
||||
s = _LINK_OPERSTATE_INVALID;
|
||||
ifname = strdup(str);
|
||||
}
|
||||
if (!ifname)
|
||||
return log_oom();
|
||||
|
||||
if (!ifname_valid(ifname))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"Invalid interface name '%s'", ifname);
|
||||
|
||||
r = hashmap_ensure_allocated(&arg_interfaces, &string_hash_ops);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
r = hashmap_put(arg_interfaces, ifname, INT_TO_PTR(s));
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to store interface name: %m");
|
||||
if (r == 0)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"Interface name %s is already specified", ifname);
|
||||
|
||||
TAKE_PTR(ifname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_argv(int argc, char *argv[]) {
|
||||
|
||||
enum {
|
||||
@@ -52,12 +103,13 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
};
|
||||
|
||||
static const struct option options[] = {
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "version", no_argument, NULL, ARG_VERSION },
|
||||
{ "quiet", no_argument, NULL, 'q' },
|
||||
{ "interface", required_argument, NULL, 'i' },
|
||||
{ "ignore", required_argument, NULL, ARG_IGNORE },
|
||||
{ "timeout", required_argument, NULL, ARG_TIMEOUT },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "version", no_argument, NULL, ARG_VERSION },
|
||||
{ "quiet", no_argument, NULL, 'q' },
|
||||
{ "interface", required_argument, NULL, 'i' },
|
||||
{ "ignore", required_argument, NULL, ARG_IGNORE },
|
||||
{ "operational-state", required_argument, NULL, 'o' },
|
||||
{ "timeout", required_argument, NULL, ARG_TIMEOUT },
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -66,7 +118,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
assert(argc >= 0);
|
||||
assert(argv);
|
||||
|
||||
while ((c = getopt_long(argc, argv, "+hi:q", options, NULL)) >= 0)
|
||||
while ((c = getopt_long(argc, argv, "hi:qo:", options, NULL)) >= 0)
|
||||
|
||||
switch (c) {
|
||||
|
||||
@@ -82,9 +134,9 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
return version();
|
||||
|
||||
case 'i':
|
||||
if (strv_extend(&arg_interfaces, optarg) < 0)
|
||||
return log_oom();
|
||||
|
||||
r = parse_interface_with_operstate(optarg);
|
||||
if (r < 0)
|
||||
return r;
|
||||
break;
|
||||
|
||||
case ARG_IGNORE:
|
||||
@@ -93,11 +145,21 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
|
||||
break;
|
||||
|
||||
case 'o': {
|
||||
LinkOperationalState s;
|
||||
|
||||
s = link_operstate_from_string(optarg);
|
||||
if (s < 0)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"Invalid operational state '%s'", optarg);
|
||||
|
||||
arg_required_operstate = s;
|
||||
break;
|
||||
}
|
||||
case ARG_TIMEOUT:
|
||||
r = parse_sec(optarg, &arg_timeout);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
break;
|
||||
|
||||
case '?':
|
||||
@@ -124,11 +186,11 @@ static int run(int argc, char *argv[]) {
|
||||
return r;
|
||||
|
||||
if (arg_quiet)
|
||||
log_set_max_level(LOG_WARNING);
|
||||
log_set_max_level(LOG_ERR);
|
||||
|
||||
assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, -1) >= 0);
|
||||
|
||||
r = manager_new(&m, arg_interfaces, arg_ignore, arg_timeout);
|
||||
r = manager_new(&m, arg_interfaces, arg_ignore, arg_required_operstate, arg_timeout);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Could not create manager: %m");
|
||||
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
#include "log.h"
|
||||
|
||||
/*
|
||||
* The following macros append INTERFACE= to the message.
|
||||
* The macros require a struct named 'Link' which contains 'char *ifname':
|
||||
*
|
||||
* typedef struct Link {
|
||||
* char *ifname;
|
||||
* } Link;
|
||||
*
|
||||
* See, network/networkd-link.h for example.
|
||||
*/
|
||||
|
||||
#define log_link_full(link, level, error, ...) \
|
||||
({ \
|
||||
const Link *_l = (link); \
|
||||
(_l && _l->ifname) ? log_object_internal(level, error, __FILE__, __LINE__, __func__, "INTERFACE=", _l->ifname, NULL, NULL, ##__VA_ARGS__) : \
|
||||
log_internal(level, error, __FILE__, __LINE__, __func__, ##__VA_ARGS__); \
|
||||
}) \
|
||||
|
||||
#define log_link_debug(link, ...) log_link_full(link, LOG_DEBUG, 0, ##__VA_ARGS__)
|
||||
#define log_link_info(link, ...) log_link_full(link, LOG_INFO, 0, ##__VA_ARGS__)
|
||||
#define log_link_notice(link, ...) log_link_full(link, LOG_NOTICE, 0, ##__VA_ARGS__)
|
||||
#define log_link_warning(link, ...) log_link_full(link, LOG_WARNING, 0, ##__VA_ARGS__)
|
||||
#define log_link_error(link, ...) log_link_full(link, LOG_ERR, 0, ##__VA_ARGS__)
|
||||
|
||||
#define log_link_debug_errno(link, error, ...) log_link_full(link, LOG_DEBUG, error, ##__VA_ARGS__)
|
||||
#define log_link_info_errno(link, error, ...) log_link_full(link, LOG_INFO, error, ##__VA_ARGS__)
|
||||
#define log_link_notice_errno(link, error, ...) log_link_full(link, LOG_NOTICE, error, ##__VA_ARGS__)
|
||||
#define log_link_warning_errno(link, error, ...) log_link_full(link, LOG_WARNING, error, ##__VA_ARGS__)
|
||||
#define log_link_error_errno(link, error, ...) log_link_full(link, LOG_ERR, error, ##__VA_ARGS__)
|
||||
|
||||
#define LOG_LINK_MESSAGE(link, fmt, ...) "MESSAGE=%s: " fmt, (link)->ifname, ##__VA_ARGS__
|
||||
#define LOG_LINK_INTERFACE(link) "INTERFACE=%s", (link)->ifname
|
||||
@@ -93,6 +93,7 @@ shared_sources = files('''
|
||||
json.h
|
||||
lockfile-util.c
|
||||
lockfile-util.h
|
||||
log-link.h
|
||||
logs-show.c
|
||||
logs-show.h
|
||||
loop-util.c
|
||||
|
||||
@@ -89,6 +89,7 @@ int sd_network_link_get_setup_state(int ifindex, char **state);
|
||||
* -ENODATA: networkd is not aware of the link
|
||||
*/
|
||||
int sd_network_link_get_operational_state(int ifindex, char **state);
|
||||
int sd_network_link_get_required_operstate_for_online(int ifindex, char **state);
|
||||
|
||||
/* Indicates whether the network is relevant to being online.
|
||||
* Possible return codes:
|
||||
|
||||
@@ -1200,7 +1200,7 @@ class NetworkdNetWorkBondTests(unittest.TestCase, Utilities):
|
||||
|
||||
output = subprocess.check_output(['networkctl', 'status', 'bond99']).rstrip().decode('utf-8')
|
||||
print(output)
|
||||
self.assertRegex(output, 'State: degraded \(configured\)')
|
||||
self.assertRegex(output, 'State: degraded-carrier \(configured\)')
|
||||
|
||||
self.assertEqual(subprocess.call(['ip', 'link', 'set', 'dummy98', 'up']), 0)
|
||||
time.sleep(2)
|
||||
@@ -1219,7 +1219,7 @@ class NetworkdNetWorkBondTests(unittest.TestCase, Utilities):
|
||||
|
||||
self.assertEqual(subprocess.call(['ip', 'link', 'set', 'dummy98', 'down']), 0)
|
||||
self.assertEqual(subprocess.call(['ip', 'link', 'set', 'test1', 'down']), 0)
|
||||
time.sleep(2)
|
||||
time.sleep(5)
|
||||
|
||||
output = subprocess.check_output(['networkctl', 'status', 'dummy98']).rstrip().decode('utf-8')
|
||||
print(output)
|
||||
@@ -1231,7 +1231,7 @@ class NetworkdNetWorkBondTests(unittest.TestCase, Utilities):
|
||||
|
||||
output = subprocess.check_output(['networkctl', 'status', 'bond99']).rstrip().decode('utf-8')
|
||||
print(output)
|
||||
self.assertRegex(output, 'State: degraded \(configured\)')
|
||||
self.assertRegex(output, 'State: no-carrier \(configured\)')
|
||||
|
||||
class NetworkdNetWorkBridgeTests(unittest.TestCase, Utilities):
|
||||
links = [
|
||||
@@ -1313,7 +1313,7 @@ class NetworkdNetWorkBridgeTests(unittest.TestCase, Utilities):
|
||||
time.sleep(3)
|
||||
|
||||
output = subprocess.check_output(['networkctl', 'status', 'bridge99']).rstrip().decode('utf-8')
|
||||
self.assertRegex(output, 'State: degraded \(configured\)')
|
||||
self.assertRegex(output, 'State: degraded-carrier \(configured\)')
|
||||
|
||||
self.assertEqual(subprocess.call(['ip', 'link', 'del', 'dummy98']), 0)
|
||||
time.sleep(3)
|
||||
|
||||
Reference in New Issue
Block a user