]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
Wait to receive QMP greeting before sending any monitor commands
authorDaniel P. Berrange <berrange@redhat.com>
Thu, 6 Sep 2012 15:14:25 +0000 (16:14 +0100)
committerDaniel P. Berrange <berrange@redhat.com>
Thu, 13 Sep 2012 10:44:05 +0000 (11:44 +0100)
Technically speaking we should wait until we receive the QMP
greeting message before attempting to send any QMP monitor
commands. Mostly we've got away with this, but there is a race
in some QEMU which cause it to SEGV if you sent it data too
soon after startup. Waiting for the QMP greeting avoids the
race

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
src/qemu/qemu_monitor.c
tests/qemumonitortestutils.c

index 65694bab719e59bb8825b555d4ca40dd782e1283..543b6cd17a03771bb8f671f9f03d3de957d20f44 100644 (file)
@@ -79,6 +79,7 @@ struct _qemuMonitor {
 
     unsigned json: 1;
     unsigned json_hmp: 1;
+    unsigned wait_greeting: 1;
 };
 
 static virClassPtr qemuMonitorClass;
@@ -365,6 +366,9 @@ qemuMonitorIOProcess(qemuMonitorPtr mon)
     if (len < 0)
         return -1;
 
+    if (len && mon->wait_greeting)
+        mon->wait_greeting = 0;
+
     if (len < mon->bufferOffset) {
         memmove(mon->buffer, mon->buffer + len, mon->bufferOffset - len);
         mon->bufferOffset -= len;
@@ -538,7 +542,8 @@ static void qemuMonitorUpdateWatch(qemuMonitorPtr mon)
     if (mon->lastError.code == VIR_ERR_OK) {
         events |= VIR_EVENT_HANDLE_READABLE;
 
-        if (mon->msg && mon->msg->txOffset < mon->msg->txLength)
+        if ((mon->msg && mon->msg->txOffset < mon->msg->txLength) &&
+            !mon->wait_greeting)
             events |= VIR_EVENT_HANDLE_WRITABLE;
     }
 
@@ -718,6 +723,8 @@ qemuMonitorOpenInternal(virDomainObjPtr vm,
     mon->hasSendFD = hasSendFD;
     mon->vm = vm;
     mon->json = json;
+    if (json)
+        mon->wait_greeting = 1;
     mon->cb = cb;
     qemuMonitorLock(mon);
 
index 76b11e677537372623fa8750a7f06a37b2370c16..fcf8663152be8873429cd44b1eb37bd375a7cd37 100644 (file)
@@ -418,6 +418,9 @@ static qemuMonitorCallbacks qemuCallbacks = {
     .errorNotify = qemuMonitorTestErrorNotify,
 };
 
+#define QEMU_JSON_GREETING "{\"QMP\": {\"version\": {\"qemu\": {\"micro\": 1, \"minor\": 0, \"major\": 1}, \"package\": \" (qemu-kvm-1.0.1)\"}, \"capabilities\": []}}"
+#define QEMU_TEXT_GREETING "QEMU 1.0,1 monitor - type 'help' for more information"
+
 qemuMonitorTestPtr qemuMonitorTestNew(bool json, virCapsPtr caps)
 {
     qemuMonitorTestPtr test;
@@ -458,7 +461,7 @@ qemuMonitorTestPtr qemuMonitorTestNew(bool json, virCapsPtr caps)
 
     if (!(test->mon = qemuMonitorOpen(test->vm,
                                       &src,
-                                      true,
+                                      json ? 1 : 0,
                                       &qemuCallbacks)))
         goto error;
     qemuMonitorLock(test->mon);
@@ -468,8 +471,13 @@ qemuMonitorTestPtr qemuMonitorTestNew(bool json, virCapsPtr caps)
     if (!test->client)
         goto error;
 
+    if (qemuMonitorTestAddReponse(test, json ?
+                                  QEMU_JSON_GREETING :
+                                  QEMU_TEXT_GREETING) < 0)
+        goto error;
+
     if (virNetSocketAddIOCallback(test->client,
-                                  VIR_EVENT_HANDLE_READABLE,
+                                  VIR_EVENT_HANDLE_WRITABLE,
                                   qemuMonitorTestIO,
                                   test,
                                   NULL) < 0)