]> xenbits.xensource.com Git - libvirt.git/commitdiff
network: inhibit idle timeout of daemon if there are any active networks
authorLaine Stump <laine@redhat.com>
Fri, 30 Aug 2024 16:37:05 +0000 (12:37 -0400)
committerLaine Stump <laine@redhat.com>
Thu, 10 Oct 2024 18:07:12 +0000 (14:07 -0400)
When the daemons were split out from the monolithic libvirtd, the
network driver didn't implement "inhibit idle timeout if there are any
active objects" as was done for other drivers, so virtnetworkd would
always exit after 120 seconds of no incoming connections. This didn't
every cause any visible problem, although it did mean that anytime a
network API was called after an idle time > 120 seconds, that the
restarting virtnetworkd would flush and reload all the
iptables/nftables rules for any active networks.

This patch replicates what is done in the QEMU driver - an nactive is
added to the network driver object, along with an inhibitCallback; the
latter is passed into networkStateInitialize when the driver is
loaded, and the former is incremented for each already-active network,
then incremented/decremented each time a network is started or
stopped. If nactive transitions from 0 to 1 or 1 to 0, inhibitCallback
is called, and it "does the right stuff" to prevent/enable the idle
timeout.

Signed-off-by: Laine Stump <laine@redhat.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
src/network/bridge_driver.c
src/network/bridge_driver_conf.h

index f604b2695c5ae9f95aa55a8b0c501f49fd5ffec7..550759881ac00410688e29212159201fa68339ed 100644 (file)
@@ -501,9 +501,13 @@ networkUpdateState(virNetworkObj *obj,
         return -1;
     }
 
-    if (virNetworkObjIsActive(obj))
+    if (virNetworkObjIsActive(obj)) {
         virNetworkObjPortForEach(obj, networkUpdatePort, obj);
 
+        if (g_atomic_int_add(&driver->nactive, 1) == 0 && driver->inhibitCallback)
+            driver->inhibitCallback(true, driver->inhibitOpaque);
+    }
+
     /* Try and read dnsmasq pids of both active and inactive networks, just in
      * case a network became inactive and we need to clean up. */
     if (def->ips && (def->nips > 0)) {
@@ -617,8 +621,8 @@ static virDrvStateInitResult
 networkStateInitialize(bool privileged,
                        const char *root,
                        bool monolithic G_GNUC_UNUSED,
-                       virStateInhibitCallback callback G_GNUC_UNUSED,
-                       void *opaque G_GNUC_UNUSED)
+                       virStateInhibitCallback callback,
+                       void *opaque)
 {
     virNetworkDriverConfig *cfg;
     bool autostart = true;
@@ -640,6 +644,9 @@ networkStateInitialize(bool privileged,
         goto error;
     }
 
+    network_driver->inhibitCallback = callback;
+    network_driver->inhibitOpaque = opaque;
+
     network_driver->privileged = privileged;
 
     if (!(network_driver->xmlopt = networkDnsmasqCreateXMLConf()))
@@ -2419,6 +2426,9 @@ networkStartNetwork(virNetworkDriverState *driver,
                                 obj, network_driver->xmlopt) < 0)
         goto cleanup;
 
+    if (g_atomic_int_add(&driver->nactive, 1) == 0 && driver->inhibitCallback)
+        driver->inhibitCallback(true, driver->inhibitOpaque);
+
     virNetworkObjSetActive(obj, true);
     VIR_INFO("Network '%s' started up", def->name);
     ret = 0;
@@ -2492,6 +2502,10 @@ networkShutdownNetwork(virNetworkDriverState *driver,
                    VIR_HOOK_SUBOP_END);
 
     virNetworkObjSetActive(obj, false);
+
+    if (g_atomic_int_dec_and_test(&driver->nactive) && driver->inhibitCallback)
+        driver->inhibitCallback(false, driver->inhibitOpaque);
+
     virNetworkObjUnsetDefTransient(obj);
     return ret;
 }
index 8f221f391eb73346156d9ec09b1e7f535b7010f1..1beed01efbd1dbe54c738a74a7b2ff383f8461a8 100644 (file)
@@ -21,7 +21,7 @@
 
 #pragma once
 
-#include "internal.h"
+#include "libvirt_internal.h"
 #include "virthread.h"
 #include "virdnsmasq.h"
 #include "virnetworkobj.h"
@@ -49,6 +49,13 @@ typedef struct _virNetworkDriverState virNetworkDriverState;
 struct _virNetworkDriverState {
     virMutex lock;
 
+    /* Atomic inc/dec only */
+    unsigned int nactive;
+
+    /* Immutable pointers. Caller must provide locking */
+    virStateInhibitCallback inhibitCallback;
+    void *inhibitOpaque;
+
     /* Read-only */
     bool privileged;