If the monitor met a error, and we will call qemuProcessHandleMonitorEOF().
But we may try to send monitor command after qemuProcessHandleMonitorEOF()
returned. Then libvirtd will be blocked in qemuMonitorSend().
Steps to reproduce this bug:
1. use gdb to attach libvirtd, and set a breakpoint in the function
qemuConnectMonitor()
2. start a vm
3. let the libvirtd to run until qemuMonitorOpen() returns.
4. kill the qemu process
5. continue running libvirtd
Signed-off-by: Wen Congyang <wency(a)cn.fujitsu.com>
---
src/qemu/qemu_monitor.c | 13 +++++++++++++
1 files changed, 13 insertions(+), 0 deletions(-)
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 800f744..eed83f4 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -572,6 +572,13 @@ qemuMonitorIO(int watch, int fd, int events, void *opaque) {
mon->msg->lastErrno = EIO;
virCondSignal(&mon->notify);
}
+ /* If qemu quited unexpectedly, and we may try to send monitor
+ * command later. But we have no chance to wake up it. So set
+ * mon->lastErrno to EIO, and check it before sending monitor
+ * command.
+ */
+ if (!mon->lastErrno)
+ mon->lastErrno = EIO;
quit = 1;
} else if (events) {
VIR_ERROR(_("unhandled fd event %d for monitor fd %d"),
@@ -725,6 +732,12 @@ int qemuMonitorSend(qemuMonitorPtr mon,
{
int ret = -1;
+ /* Check whether qemu quited unexpectedly */
+ if (mon->lastErrno) {
+ msg->lastErrno = mon->lastErrno;
+ return -1;
+ }
+
mon->msg = msg;
qemuMonitorUpdateWatch(mon);
--
1.7.1