[libvirt PATCH] nwfilter: spawn thread for reloading on firewalld trigger

Daniel P. Berrangé berrange at redhat.com
Fri Apr 1 09:28:54 UTC 2022


When firewalld is restarted or has its rules reloaded, we trigger a
reload of the nwfilter driver. This is done directly in the main
event loop thread which is a bad idea.

In a previous commit we fixed a actual deadlock problem with the
virStateReload API, when triggered from SIGHUP:

commit 33c6eb9689eb51dfe31dd05b24b3b6b1c948c267
Author: Jim Fehlig <jfehlig at suse.com>
Date:   Thu Mar 8 15:04:48 2018 -0700

    libvirtd: fix potential deadlock when reloading

The same deadlock problem previously existed with the firewalld reload
trigger, however, today it is not quite so series. The QEMU driver uses
a private event thread for each VM, so the particular deadlock would
not occur. None the less during the time the filters are reloading all
use of the event loop is blocked, which prevents APIs being serviced.

Signed-off-by: Daniel P. Berrangé <berrange at redhat.com>
---
 src/nwfilter/nwfilter_driver.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/src/nwfilter/nwfilter_driver.c b/src/nwfilter/nwfilter_driver.c
index 1f7d40e1b0..f620461f6a 100644
--- a/src/nwfilter/nwfilter_driver.c
+++ b/src/nwfilter/nwfilter_driver.c
@@ -59,6 +59,13 @@ static virMutex driverMutex = VIR_MUTEX_INITIALIZER;
 
 #ifdef WITH_FIREWALLD
 
+static void nwfilterStateReloadThread(void *opaque G_GNUC_UNUSED)
+{
+    VIR_INFO("Reloading configuration on firewalld reload/restart");
+
+    nwfilterStateReload();
+}
+
 static void
 nwfilterFirewalldDBusSignalCallback(GDBusConnection *connection G_GNUC_UNUSED,
                                     const char *senderName G_GNUC_UNUSED,
@@ -68,7 +75,15 @@ nwfilterFirewalldDBusSignalCallback(GDBusConnection *connection G_GNUC_UNUSED,
                                     GVariant *parameters G_GNUC_UNUSED,
                                     gpointer user_data G_GNUC_UNUSED)
 {
-    nwfilterStateReload();
+    virThread thr;
+
+    if (virThreadCreateFull(&thr, false, nwfilterStateReloadThread,
+                            "firewall-reload", false, NULL) < 0) {
+        /*
+         * Not much we can do on error here except log it.
+         */
+        VIR_ERROR(_("Failed to create thread to handle firewall reload/restart"));
+    }
 }
 
 static unsigned int restartID;
-- 
2.34.1



More information about the libvir-list mailing list