Merge pull request #22249 from yuwata/wait-online-fix-unmanaged-state
wait-online: fix handling of unmanaged state
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
@@ -44,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
|
||||
@@ -93,20 +110,21 @@ static int manager_link_is_online(Manager *m, Link *l, LinkOperationalStateRange
|
||||
}
|
||||
}
|
||||
|
||||
log_link_debug(l, "link is confiured by networkd and online.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
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 +155,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 +207,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 +310,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 +347,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 +365,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 +404,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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user