network: wait for QDiscs to be configured
authorYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 29 Oct 2019 15:19:34 +0000 (00:19 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 30 Oct 2019 00:33:51 +0000 (09:33 +0900)
src/network/networkd-link.c
src/network/networkd-link.h
src/network/tc/qdisc.c

index ccac600..91de2be 100644 (file)
@@ -1095,6 +1095,9 @@ void link_check_ready(Link *link) {
         if (!link->routing_policy_rules_configured)
                 return;
 
+        if (!link->qdiscs_configured)
+                return;
+
         if (link_has_carrier(link) || !link->network->configure_without_carrier) {
 
                 if (link_ipv4ll_enabled(link, ADDRESS_FAMILY_IPV4) && !link->ipv4ll_address)
@@ -2581,21 +2584,42 @@ static int link_drop_config(Link *link) {
         return 0;
 }
 
-static int link_configure(Link *link) {
+static int link_configure_qdiscs(Link *link) {
         QDiscs *qdisc;
         Iterator i;
         int r;
 
+        link->qdiscs_configured = false;
+        link->qdisc_messages = 0;
+
+        ORDERED_HASHMAP_FOREACH(qdisc, link->network->qdiscs_by_section, i) {
+                r = qdisc_configure(link, qdisc);
+                if (r < 0)
+                        return r;
+        }
+
+        if (link->qdisc_messages == 0)
+                link->qdiscs_configured = true;
+        else
+                log_link_debug(link, "Configuring QDiscs");
+
+        return 0;
+}
+
+static int link_configure(Link *link) {
+        int r;
+
         assert(link);
         assert(link->network);
         assert(link->state == LINK_STATE_INITIALIZED);
 
+        r = link_configure_qdiscs(link);
+        if (r < 0)
+                return r;
+
         if (link->iftype == ARPHRD_CAN)
                 return link_configure_can(link);
 
-        ORDERED_HASHMAP_FOREACH(qdisc, link->network->qdiscs_by_section, i)
-                (void) qdisc_configure(link, qdisc);
-
         /* Drop foreign config, but ignore loopback or critical devices.
          * We do not want to remove loopback address or addresses used for root NFS. */
         if (!(link->flags & IFF_LOOPBACK) &&
index e6a9c41..0b62326 100644 (file)
@@ -114,6 +114,7 @@ typedef struct Link {
         bool static_routes_ready:1;
         bool static_nexthops_configured:1;
         bool routing_policy_rules_configured:1;
+        bool qdiscs_configured:1;
         bool setting_mtu:1;
 
         LIST_HEAD(Address, pool_addresses);
index 2a4724e..ed4a11d 100644 (file)
@@ -101,9 +101,16 @@ static int qdisc_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
         r = sd_netlink_message_get_errno(m);
         if (r < 0 && r != -EEXIST) {
                 log_link_error_errno(link, r, "Could not set QDisc: %m");
+                link_enter_failed(link);
                 return 1;
         }
 
+        if (link->route_messages == 0) {
+                log_link_debug(link, "QDiscs configured");
+                link->qdiscs_configured = true;
+                link_check_ready(link);
+        }
+
         return 1;
 }