Start for on detecting & dispatching async events fed into the
QEMU monitor.
In RHEL-5 fork of QEMU, the 'notify' command turns on events,
and events are prefixed with a leading '#' character.
* src/qemu/qemu_monitor_text.h, src/qemu/qemu_monitor_text.c:
Detect and filter any async events
---
src/qemu/qemu_conf.c | 5 ++---
src/qemu/qemu_monitor.c | 6 ++++++
src/qemu/qemu_monitor_text.c | 33 +++++++++++++++++++++++++++++++++
src/qemu/qemu_monitor_text.h | 2 ++
4 files changed, 43 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index 16bde05..11b8db9 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -1760,7 +1760,6 @@ int qemudBuildCommandLine(virConnectPtr conn,
if (qemudBuildCommandLineChrDevStr(monitor_chr, buf, sizeof(buf)-8) < 0)
goto error;
#endif
-
ADD_ARG_LIT("-monitor");
ADD_ARG_LIT(buf);
}
@@ -1894,8 +1893,8 @@ int qemudBuildCommandLine(virConnectPtr conn,
}
if (disk->src)
- virBufferVSprintf(&opt, "file=%s", disk->src ?
disk->src : "");
- virBufferVSprintf(&opt, ",if=%s", bus);
+ virBufferVSprintf(&opt, "file=%s,", disk->src ?
disk->src : "");
+ virBufferVSprintf(&opt, "if=%s", bus);
if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM)
virBufferAddLit(&opt, ",media=cdrom");
virBufferVSprintf(&opt, ",index=%d", idx);
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 875d339..26f92f8 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -508,6 +508,12 @@ qemuMonitorOpen(virDomainObjPtr vm,
virDomainObjRef(vm);
+ if (!mon->json) {
+ if (qemuMonitorTextNotifyEnable(mon) < 0) {
+ VIR_INFO0("This QEMU does not support notifications");
+ }
+ }
+
VIR_DEBUG("New mon %p fd =%d watch=%d", mon, mon->fd, mon->watch);
qemuMonitorUnlock(mon);
diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
index db7ff57..e250abc 100644
--- a/src/qemu/qemu_monitor_text.c
+++ b/src/qemu/qemu_monitor_text.c
@@ -146,6 +146,7 @@ static char *qemuMonitorEscapeShell(const char *in)
#define DISK_ENCRYPTION_PREFIX "("
#define DISK_ENCRYPTION_POSTFIX ") is encrypted."
#define LINE_ENDING "\r\n"
+#define EVENT_PREFIX "# "
int qemuMonitorTextIOProcess(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
const char *data,
@@ -174,6 +175,25 @@ int qemuMonitorTextIOProcess(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
/*VIR_DEBUG("Process data %d byts of data [%s]", len - used, data +
used);*/
VIR_DEBUG("Process data %d byts of data", len - used);
+ while (STRPREFIX(data + used, EVENT_PREFIX)) {
+ const char *start = data + used + strlen(EVENT_PREFIX);
+ const char *end = strstr(start, LINE_ENDING);
+ int want;
+ char *event;
+
+ if (!end)
+ goto cleanup;
+
+ want = end - start;
+
+ event = strndup(start, want);
+
+ VIR_DEBUG("Woooo event [%s]", event);
+ VIR_FREE(event);
+
+ used += strlen(EVENT_PREFIX) + want + strlen(LINE_ENDING);
+ }
+
/* Look for a non-zero reply followed by prompt */
if (msg && !msg->finished) {
const char *end;
@@ -236,6 +256,7 @@ int qemuMonitorTextIOProcess(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
}
}
+cleanup:
VIR_DEBUG("Total used %d", used);
return used;
}
@@ -380,6 +401,18 @@ qemuMonitorSendDiskPassphrase(qemuMonitorPtr mon,
}
int
+qemuMonitorTextNotifyEnable(qemuMonitorPtr mon)
+{
+ char *reply;
+
+ if (qemuMonitorCommand(mon, "notify all on", &reply) < 0)
+ return -1;
+
+ VIR_FREE(reply);
+ return 0;
+}
+
+int
qemuMonitorTextStartCPUs(qemuMonitorPtr mon,
virConnectPtr conn) {
char *reply;
diff --git a/src/qemu/qemu_monitor_text.h b/src/qemu/qemu_monitor_text.h
index 6bca07a..abba90b 100644
--- a/src/qemu/qemu_monitor_text.h
+++ b/src/qemu/qemu_monitor_text.h
@@ -29,6 +29,8 @@
#include "qemu_monitor.h"
+int qemuMonitorTextNotifyEnable(qemuMonitorPtr mon);
+
int qemuMonitorTextIOProcess(qemuMonitorPtr mon,
const char *data,
size_t len,
--
1.6.2.5