When qemu cannot startup, we will call EOF notify callback. Unfortunately, there is a bug in libvirt, and it will cause mon->ref to be 0 while we call EOF notify callback. This bug will cause the libvirt to be deadlock. We call the other callback while holding the reference. So I think we should also hold the reference here. Note: this patch does not fix the bug. The libvirt will be deadlock in qemuMonitorUnwatch() because the monitor is freed unexpectedly. I am still investigating this bug. But if I set a breakpoint in qemuMonitorUnref(), it does not happen now. If i remove the breakpoint, it will happen sometime(the probability is about 20%). The steps to reproduce this bug: 1. use newest qemu-kvm 2. add a host pci device into guest config file 3. start the guest The qemu will fail with the following error message: Failed to assign irq for "hostdev0": Input/output error Perhaps you are assigning a device that shares an IRQ with another device? I have reported qemu's problem to qemu maillist. --- src/qemu/qemu_monitor.c | 16 ++++++++++++---- 1 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 78eb492..20eb9ea 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -668,10 +668,14 @@ qemuMonitorIO(int watch, int fd, int events, void *opaque) { /* Make sure anyone waiting wakes up now */ virCondSignal(&mon->notify); - if (qemuMonitorUnref(mon) > 0) - qemuMonitorUnlock(mon); + + /* hold the reference when call monitor's callback to avoid deadlock */ + qemuMonitorUnlock(mon); VIR_DEBUG("Triggering EOF callback"); (eofNotify)(mon, vm); + qemuMonitorLock(mon); + if (qemuMonitorUnref(mon) > 0) + qemuMonitorUnlock(mon); } else if (error) { void (*errorNotify)(qemuMonitorPtr, virDomainObjPtr) = mon->cb->errorNotify; @@ -679,10 +683,14 @@ qemuMonitorIO(int watch, int fd, int events, void *opaque) { /* Make sure anyone waiting wakes up now */ virCondSignal(&mon->notify); - if (qemuMonitorUnref(mon) > 0) - qemuMonitorUnlock(mon); + + /* hold the reference when call monitor's callback to avoid deadlock */ + qemuMonitorUnlock(mon); VIR_DEBUG("Triggering error callback"); (errorNotify)(mon, vm); + qemuMonitorLock(mon); + if (qemuMonitorUnref(mon) > 0) + qemuMonitorUnlock(mon); } else { if (qemuMonitorUnref(mon) > 0) qemuMonitorUnlock(mon); -- 1.7.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list