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@xxxxxxxxxx> Reviewed-by: Wang Yi <wang.yi59@xxxxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list