]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: extend link_reconfigure_full() and manager_reload() for Varlink
authornoxiouz <atiurin@proton.me>
Sun, 22 Feb 2026 15:11:37 +0000 (15:11 +0000)
committernoxiouz <atiurin@proton.me>
Wed, 18 Mar 2026 22:55:52 +0000 (22:55 +0000)
Add an sd_varlink* parameter to both functions so Varlink callers can
receive a deferred reply once all async work completes, symmetrically
with the existing sd_bus_message* path.

Co-developed-by: Claude Opus 4.6 <noreply@anthropic.com>
src/network/networkd-link-bus.c
src/network/networkd-link.c
src/network/networkd-link.h
src/network/networkd-manager-bus.c
src/network/networkd-manager.c
src/network/networkd-manager.h

index c411135a33f74a9fc9c8425d6531cca9fb9febac..a375d0c18b235ca64373bc67362dc08a896ca950 100644 (file)
@@ -653,7 +653,7 @@ int bus_link_method_reconfigure(sd_bus_message *message, void *userdata, sd_bus_
         if (r == 0)
                 return 1; /* Polkit will call us back */
 
-        r = link_reconfigure_full(l, LINK_RECONFIGURE_UNCONDITIONALLY | LINK_RECONFIGURE_CLEANLY, message, /* counter= */ NULL);
+        r = link_reconfigure_full(l, LINK_RECONFIGURE_UNCONDITIONALLY | LINK_RECONFIGURE_CLEANLY, message, /* varlink= */ NULL, /* counter= */ NULL);
         if (r != 0)
                 return r; /* Will reply later when r > 0. */
 
index c77b02b8e0192704f67b4a1b729330abb3b5c0fe..57b074e1be23586d44a90a8708e53b776f982ffb 100644 (file)
@@ -18,6 +18,7 @@
 #include "sd-ndisc.h"
 #include "sd-netlink.h"
 #include "sd-radv.h"
+#include "sd-varlink.h"
 
 #include "alloc-util.h"
 #include "arphrd-util.h"
@@ -1509,6 +1510,7 @@ typedef struct LinkReconfigurationData {
         Link *link;
         LinkReconfigurationFlag flags;
         sd_bus_message *message;
+        sd_varlink *varlink;
         unsigned *counter;
 } LinkReconfigurationData;
 
@@ -1518,6 +1520,7 @@ static LinkReconfigurationData* link_reconfiguration_data_free(LinkReconfigurati
 
         link_unref(data->link);
         sd_bus_message_unref(data->message);
+        sd_varlink_unref(data->varlink);
 
         return mfree(data);
 }
@@ -1528,24 +1531,30 @@ static void link_reconfiguration_data_destroy_callback(LinkReconfigurationData *
         int r;
 
         assert(data);
+        assert(!data->message || !data->varlink); /* D-Bus and Varlink callers are mutually exclusive */
 
-        if (data->message) {
-                if (data->counter) {
-                        assert(*data->counter > 0);
-                        (*data->counter)--;
-                }
+        if (data->counter) {
+                assert(*data->counter > 0);
+                (*data->counter)--;
+        }
 
-                if (!data->counter || *data->counter <= 0) {
-                        /* Update the state files before replying the bus method. Otherwise,
-                         * systemd-networkd-wait-online following networkctl reload/reconfigure may read an
-                         * outdated state file and wrongly handle an interface is already in the configured
-                         * state. */
-                        (void) manager_clean_all(data->manager);
+        if (!data->counter || *data->counter == 0) {
+                /* Update the state files before replying. Otherwise, systemd-networkd-wait-online following
+                 * networkctl reload/reconfigure may read an outdated state file and wrongly consider an
+                 * interface already in the configured state. */
+                (void) manager_clean_all(data->manager);
 
+                if (data->message) {
                         r = sd_bus_reply_method_return(data->message, NULL);
                         if (r < 0)
                                 log_warning_errno(r, "Failed to reply for DBus method, ignoring: %m");
                 }
+
+                if (data->varlink) {
+                        r = sd_varlink_reply(data->varlink, NULL);
+                        if (r < 0)
+                                log_warning_errno(r, "Failed to reply to Varlink request, ignoring: %m");
+                }
         }
 
         link_reconfiguration_data_free(data);
@@ -1568,7 +1577,7 @@ static int link_reconfigure_handler(sd_netlink *rtnl, sd_netlink_message *m, Lin
         return r;
 }
 
-int link_reconfigure_full(Link *link, LinkReconfigurationFlag flags, sd_bus_message *message, unsigned *counter) {
+int link_reconfigure_full(Link *link, LinkReconfigurationFlag flags, sd_bus_message *message, sd_varlink *varlink, unsigned *counter) {
         _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
         _cleanup_(link_reconfiguration_data_freep) LinkReconfigurationData *data = NULL;
         int r;
@@ -1576,6 +1585,7 @@ int link_reconfigure_full(Link *link, LinkReconfigurationFlag flags, sd_bus_mess
         assert(link);
         assert(link->manager);
         assert(link->manager->rtnl);
+        assert(!message || !varlink); /* D-Bus and Varlink callers are mutually exclusive */
 
         /* When the link is in the pending or initialized state, link_reconfigure_impl() will be called later
          * by link_initialized() or link_initialized_and_synced(). To prevent the function from being called
@@ -1594,6 +1604,7 @@ int link_reconfigure_full(Link *link, LinkReconfigurationFlag flags, sd_bus_mess
                 .link = link_ref(link),
                 .flags = flags,
                 .message = sd_bus_message_ref(message), /* message may be NULL, but _ref() works fine. */
+                .varlink = sd_varlink_ref(varlink),     /* varlink may be NULL, but _ref() works fine. */
                 .counter = counter,
         };
 
index 9c641fad39bdb827b269410a2698a5b0d217950e..33c2fd35a5c21fd281083797f583e319da09324a 100644 (file)
@@ -243,9 +243,9 @@ DECLARE_STRING_TABLE_LOOKUP(link_state, LinkState);
 int link_request_stacked_netdevs(Link *link, NetDevLocalAddressType type);
 
 int link_reconfigure_impl(Link *link, LinkReconfigurationFlag flags);
-int link_reconfigure_full(Link *link, LinkReconfigurationFlag flags, sd_bus_message *message, unsigned *counter);
+int link_reconfigure_full(Link *link, LinkReconfigurationFlag flags, sd_bus_message *message, sd_varlink *varlink, unsigned *counter);
 static inline int link_reconfigure(Link *link, LinkReconfigurationFlag flags) {
-        return link_reconfigure_full(link, flags, NULL, NULL);
+        return link_reconfigure_full(link, flags, NULL, NULL, NULL);
 }
 
 int link_check_initialized(Link *link);
index a98561b25e77a48eedbece42249262624059dff4..c335d34ff1c26c4b4ccae705cdc0c5f5f30fdfe4 100644 (file)
@@ -215,7 +215,7 @@ static int bus_method_reload(sd_bus_message *message, void *userdata, sd_bus_err
         if (r == 0)
                 return 1; /* Polkit will call us back */
 
-        r = manager_reload(manager, message);
+        r = manager_reload(manager, message, /* varlink= */ NULL);
         if (r < 0)
                 return r;
 
index 62e52717585c1bf1d7e55285c51583e13b4a2663..66366fe60d38ccf873c436e5f8f416a3504487a3 100644 (file)
@@ -533,7 +533,7 @@ static int signal_restart_callback(sd_event_source *s, const struct signalfd_sig
 static int signal_reload_callback(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
         Manager *m = ASSERT_PTR(userdata);
 
-        (void) manager_reload(m, /* message= */ NULL);
+        (void) manager_reload(m, /* message= */ NULL, /* varlink= */ NULL);
 
         return 0;
 }
@@ -1257,11 +1257,12 @@ int manager_set_timezone(Manager *m, const char *tz) {
         return 0;
 }
 
-int manager_reload(Manager *m, sd_bus_message *message) {
+int manager_reload(Manager *m, sd_bus_message *message, sd_varlink *varlink) {
         Link *link;
         int r;
 
         assert(m);
+        assert(!message || !varlink); /* D-Bus and Varlink callers are mutually exclusive */
 
         log_debug("Reloading...");
         (void) notify_reloading();
@@ -1279,8 +1280,12 @@ int manager_reload(Manager *m, sd_bus_message *message) {
         }
 
         HASHMAP_FOREACH(link, m->links_by_index)
-                (void) link_reconfigure_full(link, /* flags= */ 0, message,
-                                             /* counter= */ message ? &m->reloading : NULL);
+                (void) link_reconfigure_full(
+                                link,
+                                /* flags= */ 0,
+                                message,
+                                varlink,
+                                /* counter= */ (message || varlink) ? &m->reloading : NULL);
 
         log_debug("Reloaded.");
         r = 0;
index 7b014017200ddae6e3021c8b31843c7def1d9d81..bacf3df444474429baa21ad915879c8a4610df5a 100644 (file)
@@ -151,7 +151,7 @@ int manager_enumerate(Manager *m);
 int manager_set_hostname(Manager *m, const char *hostname);
 int manager_set_timezone(Manager *m, const char *tz);
 
-int manager_reload(Manager *m, sd_bus_message *message);
+int manager_reload(Manager *m, sd_bus_message *message, sd_varlink *varlink);
 
 static inline Hashmap** manager_get_sysctl_shadow(Manager *manager) {
 #if ENABLE_SYSCTL_BPF