diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2019-04-15 17:34:00 +0900 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2019-04-25 10:44:46 +0200 |
commit | bd08ce56156751d58584a44e766ef61340cdae2d (patch) | |
tree | bff9431752249fd71641cc74b3a1cd73f7a34586 | |
parent | 0beb9542e90ab1c5d1507a1046a326fbcf73861c (diff) | |
download | systemd-bd08ce56156751d58584a44e766ef61340cdae2d.tar.gz |
network: prevent interfaces to be initialized multiple times
When a uevent is received during the relevant interface is in
LINK_STATE_PENDING, then the interface may be initialized twice.
To prevent that, this introduces LINK_STATE_INITIALIZED.
-rw-r--r-- | src/network/networkd-link.c | 15 | ||||
-rw-r--r-- | src/network/networkd-link.h | 13 |
2 files changed, 17 insertions, 11 deletions
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 49363299e5..3bc7f69cb3 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -1455,7 +1455,7 @@ static int set_mtu_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) log_link_debug(link, "Setting MTU done."); - if (link->state == LINK_STATE_PENDING) + if (link->state == LINK_STATE_INITIALIZED) (void) link_configure_after_setting_mtu(link); return 1; @@ -2644,7 +2644,7 @@ static int link_enter_join_netdev(Link *link) { assert(link); assert(link->network); - assert(link->state == LINK_STATE_PENDING); + assert(link->state == LINK_STATE_INITIALIZED); link_set_state(link, LINK_STATE_CONFIGURING); @@ -3057,7 +3057,7 @@ static int link_configure(Link *link) { assert(link); assert(link->network); - assert(link->state == LINK_STATE_PENDING); + assert(link->state == LINK_STATE_INITIALIZED); if (STRPTR_IN_SET(link->kind, "can", "vcan")) return link_configure_can(link); @@ -3206,7 +3206,7 @@ static int link_configure_after_setting_mtu(Link *link) { assert(link); assert(link->network); - assert(link->state == LINK_STATE_PENDING); + assert(link->state == LINK_STATE_INITIALIZED); if (link->setting_mtu) return 0; @@ -3357,10 +3357,13 @@ static int link_initialized_and_synced(Link *link) { assert(link->ifname); assert(link->manager); - if (link->state != LINK_STATE_PENDING) + /* We may get called either from the asynchronous netlink callback, + * or directly for link_add() if running in a container. See link_add(). */ + if (!IN_SET(link->state, LINK_STATE_PENDING, LINK_STATE_INITIALIZED)) return 1; log_link_debug(link, "Link state is up-to-date"); + link_set_state(link, LINK_STATE_INITIALIZED); r = link_new_bound_by_list(link); if (r < 0) @@ -3436,6 +3439,7 @@ int link_initialized(Link *link, sd_device *device) { return 0; log_link_debug(link, "udev initialized link"); + link_set_state(link, LINK_STATE_INITIALIZED); link->sd_device = sd_device_ref(device); @@ -4353,6 +4357,7 @@ void link_clean(Link *link) { static const char* const link_state_table[_LINK_STATE_MAX] = { [LINK_STATE_PENDING] = "pending", + [LINK_STATE_INITIALIZED] = "initialized", [LINK_STATE_CONFIGURING] = "configuring", [LINK_STATE_CONFIGURED] = "configured", [LINK_STATE_UNMANAGED] = "unmanaged", diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h index e65246c87d..e322ec2262 100644 --- a/src/network/networkd-link.h +++ b/src/network/networkd-link.h @@ -20,12 +20,13 @@ #include "set.h" typedef enum LinkState { - LINK_STATE_PENDING, - LINK_STATE_CONFIGURING, - LINK_STATE_CONFIGURED, - LINK_STATE_UNMANAGED, - LINK_STATE_FAILED, - LINK_STATE_LINGER, + LINK_STATE_PENDING, /* udev has not initialized the link */ + LINK_STATE_INITIALIZED, /* udev has initialized the link */ + LINK_STATE_CONFIGURING, /* configuring addresses, routes, etc. */ + LINK_STATE_CONFIGURED, /* everything is configured */ + LINK_STATE_UNMANAGED, /* Unmanaged=yes is set */ + LINK_STATE_FAILED, /* at least one configuration process failed */ + LINK_STATE_LINGER, /* RTM_DELLINK for the link has been received */ _LINK_STATE_MAX, _LINK_STATE_INVALID = -1 } LinkState; |