summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel P. Berrange <berrange@redhat.com>2012-09-06 16:14:25 +0100
committerDaniel P. Berrange <berrange@redhat.com>2012-09-13 11:44:05 +0100
commit985a321ac0cba18f7f6721efd89e7f0e3e7fb2bf (patch)
tree780b3fc30e1cabbc8bdcdad8f28637882f79f346
parentAdd a virBitmapCopy API (diff)
downloadlibvirt-985a321ac0cba18f7f6721efd89e7f0e3e7fb2bf.tar.gz
libvirt-985a321ac0cba18f7f6721efd89e7f0e3e7fb2bf.tar.bz2
libvirt-985a321ac0cba18f7f6721efd89e7f0e3e7fb2bf.zip
Wait to receive QMP greeting before sending any monitor commands
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>
-rw-r--r--src/qemu/qemu_monitor.c9
-rw-r--r--tests/qemumonitortestutils.c12
2 files changed, 18 insertions, 3 deletions
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 65694bab7..543b6cd17 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -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);
diff --git a/tests/qemumonitortestutils.c b/tests/qemumonitortestutils.c
index 76b11e677..fcf866315 100644
--- a/tests/qemumonitortestutils.c
+++ b/tests/qemumonitortestutils.c
@@ -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)