[libvirt] [PATCH 13/15] Async event handling in QEMU monitor text protocol

Daniel P. Berrange berrange at redhat.com
Tue Nov 3 19:50:07 UTC 2009


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      |    4 ++++
 src/qemu/qemu_monitor_text.c |   33 +++++++++++++++++++++++++++++++++
 src/qemu/qemu_monitor_text.h |    2 ++
 4 files changed, 42 insertions(+), 2 deletions(-)

diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index 59873d7..b01fddc 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -1885,8 +1885,9 @@ int qemudBuildCommandLine(virConnectPtr conn,
                 break;
             }
 
-            virBufferVSprintf(&opt, "file=%s", disk->src ? disk->src : "");
-            virBufferVSprintf(&opt, ",if=%s", bus);
+            if (disk->src)
+                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 3e6a490..501cb3f 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -499,6 +499,10 @@ qemuMonitorOpen(virDomainObjPtr vm,
 
     virDomainObjRef(vm);
 
+    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




More information about the libvir-list mailing list