When we kill the qemu, the function qemuMonitorSetCapabilities() failed and then we close monitor. In another thread, mon->fd is broken and the function qemuHandleMonitorEOF() is called. The function qemuHandleMonitorEOF() calls qemudShutdownVMDaemon() to shutdown vm. The monitor will be closed in the function qemudShutdownVMDaemon(). The monitor close twice and the reference is decreased to 0 unexpectedly. The memory will be freed when reference is decreased to 0. We will remove the watch of mon->fd when the monitor is closed. This request will be done in the function qemuMonitorUnwatch() in the qemuloop thread. In the function qemuMonitorUnwatch(), we will lock monitor, but the lock is destroyed and we will block here, In the main thread, we may add some watch or timeout, and will be blocked because the lock of eventLoop is hold by qemuLoop thread. We should close monitor only once. Signed-off-by: Wen Congyang <wency@xxxxxxxxxxxxxx> --- src/qemu/qemu_monitor.c | 10 ++++++++++ 1 files changed, 10 insertions(+), 0 deletions(-) diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 3026733..0e95f74 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -47,6 +47,7 @@ struct _qemuMonitor { virMutex lock; /* also used to protect fd */ virCond notify; + bool closed; int refs; int fd; @@ -623,6 +624,7 @@ qemuMonitorOpen(virDomainObjPtr vm, mon->vm = vm; mon->json = json; mon->cb = cb; + mon->closed = false; qemuMonitorLock(mon); switch (config->type) { @@ -695,6 +697,14 @@ void qemuMonitorClose(qemuMonitorPtr mon) qemuMonitorLock(mon); + if (mon->closed) { + /* We have closed monitor in other thread. */ + qemuMonitorUnlock(mon); + return; + } + + mon->closed = true; + if (mon->fd >= 0) { if (mon->watch) virEventRemoveHandle(mon->watch); -- 1.7.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list