[libvirt] [PATCH] nwfilter:fix deadlock when nwfilter reload

Wang Yechao wang.yechao255 at zte.com.cn
Fri Sep 7 07:54:31 UTC 2018


user run "firewalld-cmd --reload"
nwfilterStateReload called in main thread
step 1. virRWLockWrite(&updateLock)
step 2. virNWFilterLoadAllConfigs
step 3. virRWLockUnlock(&updateLock);

lauch a vm: qemuDomainCreateXML runs in other thread
step 1. virRWLockRead(&updateLock);
step 2. qemuProcessStart
step 3. qemuProcessWaitForMonitor
step 4. ...
step 5  virRWLockUnlock(&updateLock);

if nwfilterStateReload called in the middle of step 1 and step 5 of
qemuDomainCreateXML, it can't get the updateLock and then block the event_loop,
so event_loop can't handle the qemu-monitor messages, cause deadlock

move nwfilterStateReload into thread to fix this problem.

Signed-off-by: Wang Yechao <wang.yechao255 at zte.com.cn>
Reviewed-by: Wang Yi <wang.yi59 at zte.com.cn>
---
 src/nwfilter/nwfilter_driver.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)
 mode change 100644 => 100755 src/nwfilter/nwfilter_driver.c

diff --git a/src/nwfilter/nwfilter_driver.c b/src/nwfilter/nwfilter_driver.c
old mode 100644
new mode 100755
index ac3a964..2c099e2
--- a/src/nwfilter/nwfilter_driver.c
+++ b/src/nwfilter/nwfilter_driver.c
@@ -81,17 +81,28 @@ static void nwfilterDriverUnlock(void)
 
 #if HAVE_FIREWALLD
 
+static void nwfilterThread(void *opaque ATTRIBUTE_UNUSED)
+{
+    nwfilterStateReload();
+}
+
 static DBusHandlerResult
 nwfilterFirewalldDBusFilter(DBusConnection *connection ATTRIBUTE_UNUSED,
                             DBusMessage *message,
                             void *user_data ATTRIBUTE_UNUSED)
 {
+    virThread thread;
+
     if (dbus_message_is_signal(message, DBUS_INTERFACE_DBUS,
                                "NameOwnerChanged") ||
         dbus_message_is_signal(message, "org.fedoraproject.FirewallD1",
                                "Reloaded")) {
         VIR_DEBUG("Reload in nwfilter_driver because of firewalld.");
-        nwfilterStateReload();
+
+        /* create thread handle the nwfilter reload, don't block the event_loop.*/
+        if (virThreadCreate(&thread, false, nwfilterThread, NULL) < 0) {
+            VIR_ERROR("create nwfilterThread failed.");
+        }
     }
 
     return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-- 
1.8.3.1




More information about the libvir-list mailing list