[libvirt] PATCH Fix QEMU monitor prompt confusion

Daniel P. Berrange berrange at redhat.com
Tue Jul 7 16:43:34 UTC 2009


When you first connect to the QEMU monitor after a VM starts, it will
print out 

  QEMU 0.10.5 monitor - type 'help' for more information

We already have code to detect & discard this. Unfortunately it seems that
with QEMU >= 0.10.0 it will also print out this prompt when you disconnect
and reconnect to the QEMU monitor. Except it doesn't print this out every
time. It only appears to happen 50% of the time when libvirtd restarts
and reconnects. When it does happen though it totally breaks all future
monitor commands libvirt tries to run.

This patch takes a fairly simple approach to solving it. Before running
any QEMU monitor command, read and discard all pending data. 99% of the
time there will be none, but if there is, this saves us from disaster.

Daniel

diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index 95ea882..fdbbb56 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -1656,6 +1656,28 @@ cleanup:
     qemuDriverUnlock(driver);
 }
 
+
+/* Throw away any data available on the monitor
+ * This is done before executing a command, in order
+ * to allow re-synchronization if something went badly
+ * wrong in the past. it also deals with problem of
+ * QEMU *sometimes* re-printing its initial greeting
+ * when we reconnect to the monitor after restarts.
+ */
+static void
+qemuMonitorDiscardPendingData(virDomainObjPtr vm) {
+    char buf[1024];
+    int ret = 0;
+
+    /* Monitor is non-blocking, so just loop till we
+     * get -1 or 0. Don't bother with detecting
+     * errors, since we'll deal with that better later */
+    do {
+        ret = read(vm->monitor, buf, sizeof (buf)-1);
+    } while (ret > 0);
+}
+
+
 static int
 qemudMonitorCommandExtra(const virDomainObjPtr vm,
                          const char *cmd,
@@ -1667,6 +1689,8 @@ qemudMonitorCommandExtra(const virDomainObjPtr vm,
     size_t cmdlen = strlen(cmd);
     size_t extralen = extra ? strlen(extra) : 0;
 
+    qemuMonitorDiscardPendingData(vm);
+
     if (safewrite(vm->monitor, cmd, cmdlen) != cmdlen)
         return -1;
     if (safewrite(vm->monitor, "\r", 1) != 1)
-- 
1.6.2.5



-- 
|: Red Hat, Engineering, London   -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org  -o-  http://virt-manager.org  -o-  http://ovirt.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-  F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|




More information about the libvir-list mailing list