network: check if interface is initialized after enumeration completed
authorYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 1 Nov 2024 21:31:25 +0000 (06:31 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 4 Nov 2024 17:55:15 +0000 (02:55 +0900)
We enumerate interfaces at first, then enumerate other configurations
like addresses and so on. If we are running on a container, previously
we started to configure the enumerated interfaces before enumerating other
configurations.
Let's configure interfaces after all configurations are enumerated.

src/network/networkd-link.c
src/network/networkd-link.h
src/network/networkd-manager.c

index bc4374b42c3290c0e78e284c50f36c3e66009fcb..ea68b14a8cefcabea24d03a8e2cfd8741d133644 100644 (file)
@@ -1636,7 +1636,7 @@ static int link_initialized(Link *link, sd_device *device) {
         return link_call_getlink(link, link_initialized_handler);
 }
 
-static int link_check_initialized(Link *link) {
+int link_check_initialized(Link *link) {
         _cleanup_(sd_device_unrefp) sd_device *device = NULL;
         int r;
 
@@ -2836,6 +2836,10 @@ int manager_rtnl_process_link(sd_netlink *rtnl, sd_netlink_message *message, Man
                                 return 0;
                         }
 
+                        /* Do not enter initialized state if we are enumerating. */
+                        if (manager->enumerating)
+                                return 0;
+
                         r = link_check_initialized(link);
                         if (r < 0) {
                                 log_link_warning_errno(link, r, "Failed to check link is initialized: %m");
@@ -2858,6 +2862,10 @@ int manager_rtnl_process_link(sd_netlink *rtnl, sd_netlink_message *message, Man
                                 return 0;
                         }
 
+                        /* Do not configure interface if we are enumerating. */
+                        if (manager->enumerating)
+                                return 0;
+
                         r = link_reconfigure_impl(link, /* force = */ false);
                         if (r < 0) {
                                 log_link_warning_errno(link, r, "Failed to reconfigure interface: %m");
index 5efe226084536f08b8776ed6567a3d5f494003fc..1c5c9ec7096a561896ec99529bbb019dd5921ed0 100644 (file)
@@ -263,6 +263,8 @@ int link_reconfigure_impl(Link *link, bool force);
 int link_reconfigure(Link *link, bool force);
 int link_reconfigure_on_bus_method_reload(Link *link, sd_bus_message *message);
 
+int link_check_initialized(Link *link);
+
 int manager_udev_process_link(Manager *m, sd_device *device, sd_device_action_t action);
 int manager_rtnl_process_link(sd_netlink *rtnl, sd_netlink_message *message, Manager *m);
 
index 6dce901742c277265e79b91968250437bfda7bf7..73e9156e227eb6972e383a83cef7e736e88a4a74 100644 (file)
@@ -756,6 +756,17 @@ int manager_start(Manager *m) {
         if (r < 0)
                 return log_error_errno(r, "Failed to initialize speed meter: %m");
 
+        HASHMAP_FOREACH(link, m->links_by_index) {
+                if (link->state != LINK_STATE_PENDING)
+                        continue;
+
+                r = link_check_initialized(link);
+                if (r < 0) {
+                        log_link_warning_errno(link, r, "Failed to check if link is initialized: %m");
+                        link_enter_failed(link);
+                }
+        }
+
         /* The dirty handler will deal with future serialization, but the first one
            must be done explicitly. */