[libvirt] [PATCH 3/4] add a qemu-specific event register API supported in qemu driver

shaohef at linux.vnet.ibm.com shaohef at linux.vnet.ibm.com
Fri Dec 16 16:59:00 UTC 2011


From: ShaoHe Feng <shaohef at linux.vnet.ibm.com>


Signed-off-by: ShaoHe Feng <shaohef at linux.vnet.ibm.com>
---
 src/qemu/qemu_driver.c       |   42 ++++++++++++++++++++++++++++++++++++++++++
 src/qemu/qemu_monitor.c      |   10 ++++++++++
 src/qemu/qemu_monitor.h      |    8 ++++++++
 src/qemu/qemu_monitor_json.c |   35 +++++++++++++++++++++++++++++++++++
 src/qemu/qemu_process.c      |   24 ++++++++++++++++++++++++
 5 files changed, 119 insertions(+), 0 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 725b593..b9f1ec4 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -8015,6 +8015,46 @@ qemuDomainEventDeregisterAny(virConnectPtr conn,
 }
 
 
+static int
+qemuDomainQemuEventRegister(virConnectPtr conn,
+                            virDomainPtr dom,
+                            const char *eventName,
+                            virConnectDomainEventGenericCallback callback,
+                            void *opaque,
+                            virFreeCallback freecb)
+{
+    struct qemud_driver *driver = conn->privateData;
+    int ret;
+
+    qemuDriverLock(driver);
+    ret = virDomainEventCallbackListAddName(conn,
+                                            driver->domainEventState->callbacks,
+                                            dom, eventName,
+                                            VIR_QEMU_DOMAIN_EVENT_ID_UNKNOWN,
+                                            callback, opaque, freecb);
+    qemuDriverUnlock(driver);
+
+    return ret;
+}
+
+
+static int
+qemuDomainQemuEventDeregister(virConnectPtr conn,
+                              int callbackID)
+{
+    struct qemud_driver *driver = conn->privateData;
+    int ret;
+
+    qemuDriverLock(driver);
+    ret = virDomainQemuEventStateDeregister(conn,
+                                            driver->domainEventState,
+                                            callbackID);
+    qemuDriverUnlock(driver);
+
+    return ret;
+}
+
+
 /*******************************************************************
  * Migration Protocol Version 2
  *******************************************************************/
@@ -11320,6 +11360,8 @@ static virDriver qemuDriver = {
     .domainMigrateGetMaxSpeed = qemuDomainMigrateGetMaxSpeed, /* 0.9.5 */
     .domainEventRegisterAny = qemuDomainEventRegisterAny, /* 0.8.0 */
     .domainEventDeregisterAny = qemuDomainEventDeregisterAny, /* 0.8.0 */
+    .qemuDomainQemuEventRegister = qemuDomainQemuEventRegister, /* 0.9.9 */
+    .qemuDomainQemuEventDeregister = qemuDomainQemuEventDeregister, /* 0.9.9 */
     .domainManagedSave = qemuDomainManagedSave, /* 0.8.0 */
     .domainHasManagedSaveImage = qemuDomainHasManagedSaveImage, /* 0.8.0 */
     .domainManagedSaveRemove = qemuDomainManagedSaveRemove, /* 0.8.0 */
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index ad7e2a5..ab090b9 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -980,6 +980,16 @@ int qemuMonitorEmitBlockJob(qemuMonitorPtr mon,
     return ret;
 }
 
+int qemuMonitorEmitUnknownEvent(qemuMonitorPtr mon,
+                                const char *eventName,
+                                const char *eventArgs)
+{
+    int ret = -1;
+    VIR_DEBUG("mon=%p", mon);
+    QEMU_MONITOR_CALLBACK(mon, ret, domainUnknownEvent, mon->vm,
+                          eventName, eventArgs);
+    return ret;
+}
 
 
 int qemuMonitorSetCapabilities(qemuMonitorPtr mon)
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 15acf8b..d3685b4 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -123,6 +123,10 @@ struct _qemuMonitorCallbacks {
                           const char *diskAlias,
                           int type,
                           int status);
+    int (*domainUnknownEvent)(qemuMonitorPtr mon,
+                              virDomainObjPtr vm,
+                              const char *eventName,
+                              const char *eventArgs);
 };
 
 
@@ -193,6 +197,10 @@ int qemuMonitorEmitBlockJob(qemuMonitorPtr mon,
                             int type,
                             int status);
 
+int qemuMonitorEmitUnknownEvent(qemuMonitorPtr mon,
+                                const char *eventName,
+                                const char *eventArgs);
+
 
 
 int qemuMonitorStartCPUs(qemuMonitorPtr mon,
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 1ef3e84..8931332 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -58,6 +58,7 @@ static void qemuMonitorJSONHandleVNCConnect(qemuMonitorPtr mon, virJSONValuePtr
 static void qemuMonitorJSONHandleVNCInitialize(qemuMonitorPtr mon, virJSONValuePtr data);
 static void qemuMonitorJSONHandleVNCDisconnect(qemuMonitorPtr mon, virJSONValuePtr data);
 static void qemuMonitorJSONHandleBlockJob(qemuMonitorPtr mon, virJSONValuePtr data);
+static void qemuMonitorJSONHandleUnmatchedEvent(qemuMonitorPtr mon, virJSONValuePtr obj);
 
 struct {
     const char *type;
@@ -74,6 +75,7 @@ struct {
     { "VNC_INITIALIZED", qemuMonitorJSONHandleVNCInitialize, },
     { "VNC_DISCONNECTED", qemuMonitorJSONHandleVNCDisconnect, },
     { "BLOCK_JOB_COMPLETED", qemuMonitorJSONHandleBlockJob, },
+    { "DEFAULT_UNKNOW_EVENT", qemuMonitorJSONHandleUnmatchedEvent, },
 };
 
 
@@ -83,6 +85,7 @@ qemuMonitorJSONIOProcessEvent(qemuMonitorPtr mon,
 {
     const char *type;
     int i;
+    int findEventFlag = -1;
     VIR_DEBUG("mon=%p obj=%p", mon, obj);
 
     type = virJSONValueObjectGetString(obj, "event");
@@ -98,9 +101,24 @@ qemuMonitorJSONIOProcessEvent(qemuMonitorPtr mon,
             VIR_DEBUG("handle %s handler=%p data=%p", type,
                       eventHandlers[i].handler, data);
             (eventHandlers[i].handler)(mon, data);
+            findEventFlag = 0;
             break;
         }
     }
+    if (findEventFlag != 0) {
+        if (!STREQ(eventHandlers[ARRAY_CARDINALITY(eventHandlers)-1].type, "DEFAULT_UNKNOW_EVENT")) {
+            VIR_ERROR(_("the last element is not the default event handler"));
+        }
+        else {
+            char *event = NULL;
+            event = virJSONValueToString(obj);
+            if (event != NULL) {
+                VIR_DEBUG("Unknow event,call default event handler %s",event);
+                free(event);
+            }
+            (eventHandlers[ARRAY_CARDINALITY(eventHandlers)-1].handler)(mon, obj);
+        }
+    }
     return 0;
 }
 
@@ -724,6 +742,23 @@ out:
 }
 
 
+static void
+qemuMonitorJSONHandleUnmatchedEvent(qemuMonitorPtr mon, virJSONValuePtr obj)
+{
+    const char *eventArgsStr = NULL;
+    const char *type = NULL;
+    virJSONValuePtr data = NULL;
+    type = virJSONValueObjectGetString(obj, "event");
+    data  = virJSONValueObjectGet(obj, "data");
+    if (data) {
+        eventArgsStr = virJSONValueToString(data);
+        if (eventArgsStr == NULL)
+            VIR_ERROR(_("no data string from JSONValue"));
+    }
+    qemuMonitorEmitUnknownEvent(mon, type, eventArgsStr);
+}
+
+
 int
 qemuMonitorJSONHumanCommandWithFd(qemuMonitorPtr mon,
                                   const char *cmd_str,
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 9123f4c..55e5464 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -755,6 +755,29 @@ qemuProcessHandleBlockJob(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
 }
 
 static int
+qemuProcessHandleUnknownEvent(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
+                              virDomainObjPtr vm,
+                              const char *eventName,
+                              const char *eventArgs)
+{
+    struct qemud_driver *driver = qemu_driver;
+    virDomainEventPtr event = NULL;
+
+    virDomainObjLock(vm);
+    event = virDomainEventUnknownNewFromObj(vm, eventName, eventArgs);
+
+    virDomainObjUnlock(vm);
+
+    if (event) {
+        qemuDriverLock(driver);
+        qemuDomainEventQueue(driver, event);
+        qemuDriverUnlock(driver);
+    }
+
+    return 0;
+}
+
+static int
 qemuProcessHandleGraphics(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                           virDomainObjPtr vm,
                           int phase,
@@ -871,6 +894,7 @@ static qemuMonitorCallbacks monitorCallbacks = {
     .domainIOError = qemuProcessHandleIOError,
     .domainGraphics = qemuProcessHandleGraphics,
     .domainBlockJob = qemuProcessHandleBlockJob,
+    .domainUnknownEvent = qemuProcessHandleUnknownEvent,
 };
 
 static int
-- 
1.7.5.4




More information about the libvir-list mailing list