From: ShaoHe Feng <shaohef(a)linux.vnet.ibm.com>
Signed-off-by: ShaoHe Feng <shaohef(a)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