diff --git a/ChangeLog b/ChangeLog index 5784156b1f..ce135bcaad 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +Mon Nov 17 16:42:00 GMT 2008 Daniel Berrange + + Include an event 'detail' field providing the cause of + each emitted domain event. + * docs/ Re-generate API refernece + * examples/domain-events/events-c/event-test.c: Print out + event detail info + * include/libvirt/libvirt.h.in: Rename ADDED/REMOVED events + to DEFINED/UNDEFINED. Remove SAVED/RESTORED events replaced + by event detail info. Add enums providing details for each + domain event type. + * python/libvir.c: Pass through event detail to python layer + * qemud/remote_protocol.x: Add event detail field for domain + events. + * qemud/remote_protocol.c, qemud/remote_protocol.h: Regenerate + * qemud/remote.c: Pass event detail value onto the wire + * src/domain_event.h, src/domain_event.c: Store event detail + * src/remote_internal.c: De-serialize event detail off the + wire + * src/qemu_driver.c: Generate event detail information, and + fix migration API to honour VIR_MIGRATE_LIVE flag, pausing + the VM if it isn't set + Mon Nov 17 11:57:00 GMT 2008 Daniel Berrange Push stateful driver code into daemon binary diff --git a/docs/devhelp/libvirt-libvirt.html b/docs/devhelp/libvirt-libvirt.html index 78b2fdf08e..803fde2825 100644 --- a/docs/devhelp/libvirt-libvirt.html +++ b/docs/devhelp/libvirt-libvirt.html @@ -53,9 +53,10 @@ typedef struct _virDomainBlockStats virDoma typedef enum virDomainMigrateFlags; typedef struct _virNodeInfo virNodeInfo; typedef struct _virNetwork virNetwork; +typedef enum virDomainEventResumedDetailType; typedef virDomainBlockStatsStruct * virDomainBlockStatsPtr; typedef struct _virConnect virConnect; -typedef struct _virVcpuInfo virVcpuInfo; +typedef enum virDomainEventStartedDetailType; typedef struct _virDomainInfo virDomainInfo; typedef enum virStoragePoolDeleteFlags; typedef enum virEventHandleType; @@ -79,17 +80,22 @@ typedef struct _virStorageVol virStorageVol; typedef virStorageVolInfo * virStorageVolInfoPtr; typedef struct _virSchedParameter virSchedParameter; typedef enum virConnectFlags; +typedef enum virDomainEventDefinedDetailType; typedef enum virDomainMemoryFlags; +typedef enum virDomainEventStoppedDetailType; typedef virStorageVol * virStorageVolPtr; typedef enum virVcpuState; typedef enum virStorageVolDeleteFlags; +typedef struct _virVcpuInfo virVcpuInfo; typedef virSchedParameter * virSchedParameterPtr; typedef struct _virConnectAuth virConnectAuth; typedef struct _virConnectCredential virConnectCredential; +typedef enum virDomainEventSuspendedDetailType; typedef virVcpuInfo * virVcpuInfoPtr; typedef enum virStoragePoolBuildFlags; typedef enum virDomainXMLFlags; typedef enum virStorageVolType; +typedef enum virDomainEventUndefinedDetailType; typedef virDomain * virDomainPtr; typedef enum virConnectCredentialType; typedef enum virStoragePoolState; @@ -175,7 +181,7 @@ int virDomainPinVcpu (virDomainRestore (virConnectPtr conn,
const char * from); char * virStorageVolGetPath (virStorageVolPtr vol); virNetworkPtr virNetworkLookupByUUIDString (virConnectPtr conn,
const char * uuidstr); -typedef int virConnectDomainEventCallback (virConnectPtr conn,
virDomainPtr dom,
int event,
void * opaque); +typedef int virConnectDomainEventCallback (virConnectPtr conn,
virDomainPtr dom,
int event,
int detail,
void * opaque); virDomainPtr virDomainLookupByID (virConnectPtr conn,
int id); int virStorageVolDelete (virStorageVolPtr vol,
unsigned int flags); int virStorageVolFree (virStorageVolPtr vol); @@ -367,17 +373,61 @@ The content of this structure is not made public by the API. VIR_DOMAIN_NONE = 0 };

+ +


+

Enum virDomainEventDefinedDetailType

enum virDomainEventDefinedDetailType {
+    VIR_DOMAIN_EVENT_DEFINED_ADDED = 0 /* Newly created config file */
+    VIR_DOMAIN_EVENT_DEFINED_UPDATED = 1 /*  Changed config file */
+};
+

+

+
+

Enum virDomainEventResumedDetailType

enum virDomainEventResumedDetailType {
+    VIR_DOMAIN_EVENT_RESUMED_UNPAUSED = 0 /* Normal resume due to admin unpause */
+    VIR_DOMAIN_EVENT_RESUMED_MIGRATED = 1 /*  Resumed for completion of migration */
+};
+

+

+
+

Enum virDomainEventStartedDetailType

enum virDomainEventStartedDetailType {
+    VIR_DOMAIN_EVENT_STARTED_BOOTED = 0 /* Normal startup from boot */
+    VIR_DOMAIN_EVENT_STARTED_MIGRATED = 1 /* Incoming migration from another host */
+    VIR_DOMAIN_EVENT_STARTED_RESTORED = 2 /*  Restored from a state file */
+};
+

+

+
+

Enum virDomainEventStoppedDetailType

enum virDomainEventStoppedDetailType {
+    VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN = 0 /* Normal shutdown */
+    VIR_DOMAIN_EVENT_STOPPED_DESTROYED = 1 /* Forced poweroff from host */
+    VIR_DOMAIN_EVENT_STOPPED_CRASHED = 2 /* Guest crashed */
+    VIR_DOMAIN_EVENT_STOPPED_MIGRATED = 3 /* Migrated off to another host */
+    VIR_DOMAIN_EVENT_STOPPED_SAVED = 4 /* Saved to a state file */
+    VIR_DOMAIN_EVENT_STOPPED_FAILED = 5 /*  Host emulator/mgmt failed */
+};
+

+

+
+

Enum virDomainEventSuspendedDetailType

enum virDomainEventSuspendedDetailType {
+    VIR_DOMAIN_EVENT_SUSPENDED_PAUSED = 0 /* Normal suspend due to admin pause */
+    VIR_DOMAIN_EVENT_SUSPENDED_MIGRATED = 1 /*  Suspended for offline migration */
+};
+


+
+

Enum virDomainEventUndefinedDetailType

enum virDomainEventUndefinedDetailType {
+    VIR_DOMAIN_EVENT_UNDEFINED_REMOVED = 0 /*  Deleted the config file */
 };
 

@@ -614,9 +664,9 @@ The content of this structure is not made public by the API.

cred:
ncred:
cbdata:
Returns:

-

Function type virConnectDomainEventCallback

int	virConnectDomainEventCallback	(virConnectPtr conn, 
virDomainPtr dom,
int event,
void * opaque)
+

Function type virConnectDomainEventCallback

int	virConnectDomainEventCallback	(virConnectPtr conn, 
virDomainPtr dom,
int event,
int detail,
void * opaque)

A callback function to be registered, and called when a domain event occurs

-
conn:virConnect connection
dom:The domain on which the event occured
event:The specfic virDomainEventType which occured
opaque:opaque user data
Returns:
+
conn:virConnect connection
dom:The domain on which the event occured
event:The specfic virDomainEventType which occured
detail:event specific detail information
opaque:opaque user data
Returns:

Function type virEventAddHandleFunc

int	virEventAddHandleFunc		(int fd, 
int event,
virEventHandleCallback cb,
void * opaque)

Part of the EventImpl, this callback Adds a file handle callback to listen for specific events

diff --git a/docs/html/libvirt-libvirt.html b/docs/html/libvirt-libvirt.html index 67deef92f8..eaf9e8b1f5 100644 --- a/docs/html/libvirt-libvirt.html +++ b/docs/html/libvirt-libvirt.html @@ -26,7 +26,13 @@ typedef struct _virDomain virDomain typedef virDomainBlockStatsStruct * virDomainBlockStatsPtr typedef struct _virDomainBlockStats virDomainBlockStatsStruct typedef enum virDomainCreateFlags +typedef enum virDomainEventDefinedDetailType +typedef enum virDomainEventResumedDetailType +typedef enum virDomainEventStartedDetailType +typedef enum virDomainEventStoppedDetailType +typedef enum virDomainEventSuspendedDetailType typedef enum virDomainEventType +typedef enum virDomainEventUndefinedDetailType typedef struct _virDomainInfo virDomainInfo typedef virDomainInfo * virDomainInfoPtr typedef virDomainInterfaceStatsStruct * virDomainInterfaceStatsPtr @@ -65,7 +71,7 @@ int virConnectAuthCallbackPtr (virConnectClose (virConnectPtr conn) typedef virConnectDomainEventCallback -int virConnectDomainEventCallback (virConnectPtr conn,
virDomainPtr dom,
int event,
void * opaque) +int virConnectDomainEventCallback (virConnectPtr conn,
virDomainPtr dom,
int event,
int detail,
void * opaque) int virConnectDomainEventDeregister (virConnectPtr conn,
virConnectDomainEventCallback cb) int virConnectDomainEventRegister (virConnectPtr conn,
virConnectDomainEventCallback cb,
void * opaque) @@ -239,8 +245,20 @@ char * virStorageVolGetXMLDesc (

virDomainCreateFlags

enum virDomainCreateFlags {
 
VIR_DOMAIN_NONE = 0
}
+

virDomainEventDefinedDetailType

enum virDomainEventDefinedDetailType {
+
VIR_DOMAIN_EVENT_DEFINED_ADDED = 0 : Newly created config file
VIR_DOMAIN_EVENT_DEFINED_UPDATED = 1 : Changed config file
}
+

virDomainEventResumedDetailType

enum virDomainEventResumedDetailType {
+
VIR_DOMAIN_EVENT_RESUMED_UNPAUSED = 0 : Normal resume due to admin unpause
VIR_DOMAIN_EVENT_RESUMED_MIGRATED = 1 : Resumed for completion of migration
}
+

virDomainEventStartedDetailType

enum virDomainEventStartedDetailType {
+
VIR_DOMAIN_EVENT_STARTED_BOOTED = 0 : Normal startup from boot
VIR_DOMAIN_EVENT_STARTED_MIGRATED = 1 : Incoming migration from another host
VIR_DOMAIN_EVENT_STARTED_RESTORED = 2 : Restored from a state file
}
+

virDomainEventStoppedDetailType

enum virDomainEventStoppedDetailType {
+
VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN = 0 : Normal shutdown
VIR_DOMAIN_EVENT_STOPPED_DESTROYED = 1 : Forced poweroff from host
VIR_DOMAIN_EVENT_STOPPED_CRASHED = 2 : Guest crashed
VIR_DOMAIN_EVENT_STOPPED_MIGRATED = 3 : Migrated off to another host
VIR_DOMAIN_EVENT_STOPPED_SAVED = 4 : Saved to a state file
VIR_DOMAIN_EVENT_STOPPED_FAILED = 5 : Host emulator/mgmt failed
}
+

virDomainEventSuspendedDetailType

enum virDomainEventSuspendedDetailType {
+
VIR_DOMAIN_EVENT_SUSPENDED_PAUSED = 0 : Normal suspend due to admin pause
VIR_DOMAIN_EVENT_SUSPENDED_MIGRATED = 1 : Suspended for offline migration
}
 

virDomainEventType

virDomainEventUndefinedDetailType

enum virDomainEventUndefinedDetailType {
+
VIR_DOMAIN_EVENT_UNDEFINED_REMOVED = 0 : Deleted the config file
}
 

virDomainInfo

struct virDomainInfo{
 
unsigned charstate : the running state, one of virDomainState
unsigned longmaxMem : the maximum memory in KBytes allowed
unsigned longmemory : the memory in KBytes used by the domain
unsigned shortnrVirtCpu : the number of virtual CPUs for the domain
unsigned long longcpuTime : the CPU time used in nanoseconds
 }
@@ -297,8 +315,8 @@ char *	virStorageVolGetXMLDesc		(
VIR_VCPU_OFFLINE = 0 : the virtual CPU is offline
VIR_VCPU_RUNNING = 1 : the virtual CPU is running
VIR_VCPU_BLOCKED = 2 : the virtual CPU is blocked on resource
}
 

Functions

virConnectAuthCallbackPtr

typedef int	(*virConnectAuthCallbackPtr)	(virConnectCredentialPtr cred, 
unsigned int ncred,
void * cbdata)

cred:
ncred:
cbdata:
Returns:

virConnectClose

int	virConnectClose			(virConnectPtr conn)
-

This function closes the connection to the Hypervisor. This should not be called if further interaction with the Hypervisor are needed especially if there is running domain which need further monitoring by the application.

conn:pointer to the hypervisor connection
Returns:0 in case of success or -1 in case of error.

virConnectDomainEventCallback

typedef int	(*virConnectDomainEventCallback)	(virConnectPtr conn, 
virDomainPtr dom,
int event,
void * opaque) -

A callback function to be registered, and called when a domain event occurs

conn:virConnect connection
dom:The domain on which the event occured
event:The specfic virDomainEventType which occured
opaque:opaque user data
Returns:

virConnectDomainEventDeregister

int	virConnectDomainEventDeregister	(virConnectPtr conn, 
virConnectDomainEventCallback cb)
+

This function closes the connection to the Hypervisor. This should not be called if further interaction with the Hypervisor are needed especially if there is running domain which need further monitoring by the application.

conn:pointer to the hypervisor connection
Returns:0 in case of success or -1 in case of error.

virConnectDomainEventCallback

typedef int	(*virConnectDomainEventCallback)	(virConnectPtr conn, 
virDomainPtr dom,
int event,
int detail,
void * opaque) +

A callback function to be registered, and called when a domain event occurs

conn:virConnect connection
dom:The domain on which the event occured
event:The specfic virDomainEventType which occured
detail:event specific detail information
opaque:opaque user data
Returns:

virConnectDomainEventDeregister

int	virConnectDomainEventDeregister	(virConnectPtr conn, 
virConnectDomainEventCallback cb)

Removes a Domain Event Callback. De-registering for a domain callback will disable delivery of this event type

conn:pointer to the connection
cb:callback to the function handling domain events
Returns:0 on success, -1 on failure

virConnectDomainEventRegister

int	virConnectDomainEventRegister	(virConnectPtr conn, 
virConnectDomainEventCallback cb,
void * opaque)

Adds a Domain Event Callback. Registering for a domain callback will enable delivery of the events

conn:pointer to the connection
cb:callback to the function handling domain events
opaque:opaque data to pass on to the callback
Returns:0 on success, -1 on failure

virConnectFindStoragePoolSources

char *	virConnectFindStoragePoolSources	(virConnectPtr conn, 
const char * type,
const char * srcSpec,
unsigned int flags)

Talks to a storage backend and attempts to auto-discover the set of available storage pool sources. e.g. For iSCSI this would be a set of iSCSI targets. For NFS this would be a list of exported paths. The srcSpec (optional for some storage pool types, e.g. local ones) is an instance of the storage pool's source element specifying where to look for the pools. srcSpec is not required for some types (e.g., those querying local storage resources only)

conn:pointer to hypervisor connection
type:type of storage pool sources to discover
srcSpec:XML document specifying discovery source
flags:flags for discovery (unused, pass 0)
Returns:an xml document consisting of a SourceList element containing a source document appropriate to the given pool type for each discovered source.

virConnectGetCapabilities

char *	virConnectGetCapabilities	(virConnectPtr conn)
diff --git a/docs/libvirt-api.xml b/docs/libvirt-api.xml index b27e5674ca..3f10d28b48 100644 --- a/docs/libvirt-api.xml +++ b/docs/libvirt-api.xml @@ -16,69 +16,84 @@ - + - + - - + + - + + - + - - + + + - + + - + + + + + + + + + + - - - - + + + + + + + - + @@ -102,17 +117,22 @@ + + + + + @@ -429,14 +449,28 @@ - - - + + + - + + + + + + + + + + + + + + + @@ -582,7 +616,13 @@ + + + + + + @@ -736,6 +776,7 @@ see note above'/> + diff --git a/docs/libvirt-refs.xml b/docs/libvirt-refs.xml index 7f987702a7..48b917055c 100644 --- a/docs/libvirt-refs.xml +++ b/docs/libvirt-refs.xml @@ -17,14 +17,28 @@ - - - + + + - + + + + + + + + + + + + + + + @@ -210,7 +224,13 @@ + + + + + + @@ -376,14 +396,28 @@ - - - + + + - + + + + + + + + + + + + + + + @@ -573,7 +607,13 @@ + + + + + + @@ -1089,14 +1129,28 @@ - - - + + + - + + + + + + + + + + + + + + + @@ -1200,7 +1254,13 @@ + + + + + + @@ -2917,6 +2977,9 @@ + + + @@ -3578,6 +3641,7 @@ + @@ -4898,6 +4962,7 @@ + diff --git a/examples/domain-events/events-c/event-test.c b/examples/domain-events/events-c/event-test.c index 47b5fd69fe..0a741ea38a 100644 --- a/examples/domain-events/events-c/event-test.c +++ b/examples/domain-events/events-c/event-test.c @@ -35,9 +35,9 @@ void *t_opaque = NULL; /* Prototypes */ const char *eventToString(int event); int myDomainEventCallback1 (virConnectPtr conn, virDomainPtr dom, - int event, void *opaque); + int event, int detail, void *opaque); int myDomainEventCallback2 (virConnectPtr conn, virDomainPtr dom, - int event, void *opaque); + int event, int detail, void *opaque); int myEventAddHandleFunc (int fd, int event, virEventHandleCallback cb, void *opaque); void myEventUpdateHandleFunc(int fd, int event); @@ -56,13 +56,13 @@ void usage(const char *pname); /* Callback functions */ const char *eventToString(int event) { - const char *ret = NULL; + const char *ret = ""; switch(event) { - case VIR_DOMAIN_EVENT_ADDED: - ret ="Added"; + case VIR_DOMAIN_EVENT_DEFINED: + ret ="Defined"; break; - case VIR_DOMAIN_EVENT_REMOVED: - ret ="Removed"; + case VIR_DOMAIN_EVENT_UNDEFINED: + ret ="Undefined"; break; case VIR_DOMAIN_EVENT_STARTED: ret ="Started"; @@ -76,14 +76,70 @@ const char *eventToString(int event) { case VIR_DOMAIN_EVENT_STOPPED: ret ="Stopped"; break; - case VIR_DOMAIN_EVENT_SAVED: - ret ="Saved"; + } + return ret; +} + +static const char *eventDetailToString(int event, int detail) { + const char *ret = ""; + switch(event) { + case VIR_DOMAIN_EVENT_DEFINED: + if (detail == VIR_DOMAIN_EVENT_DEFINED_ADDED) + ret = "Added"; + else if (detail == VIR_DOMAIN_EVENT_DEFINED_UPDATED) + ret = "Updated"; break; - case VIR_DOMAIN_EVENT_RESTORED: - ret ="Restored"; + case VIR_DOMAIN_EVENT_UNDEFINED: + if (detail == VIR_DOMAIN_EVENT_UNDEFINED_REMOVED) + ret = "Removed"; + break; + case VIR_DOMAIN_EVENT_STARTED: + switch (detail) { + case VIR_DOMAIN_EVENT_STARTED_BOOTED: + ret = "Booted"; + break; + case VIR_DOMAIN_EVENT_STARTED_MIGRATED: + ret = "Migrated"; + break; + case VIR_DOMAIN_EVENT_STARTED_RESTORED: + ret = "Restored"; + break; + } + break; + case VIR_DOMAIN_EVENT_SUSPENDED: + if (detail == VIR_DOMAIN_EVENT_SUSPENDED_PAUSED) + ret = "Unpaused"; + else if (detail == VIR_DOMAIN_EVENT_SUSPENDED_MIGRATED) + ret = "Migrated"; + break; + case VIR_DOMAIN_EVENT_RESUMED: + if (detail == VIR_DOMAIN_EVENT_RESUMED_UNPAUSED) + ret = "Unpaused"; + else if (detail == VIR_DOMAIN_EVENT_RESUMED_MIGRATED) + ret = "Migrated"; + break; + case VIR_DOMAIN_EVENT_STOPPED: + switch (detail) { + case VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN: + ret = "Shutdown"; + break; + case VIR_DOMAIN_EVENT_STOPPED_DESTROYED: + ret = "Destroyed"; + break; + case VIR_DOMAIN_EVENT_STOPPED_CRASHED: + ret = "Crashed"; + break; + case VIR_DOMAIN_EVENT_STOPPED_MIGRATED: + ret = "Migrated"; + break; + case VIR_DOMAIN_EVENT_STOPPED_SAVED: + ret = "Failed"; + break; + case VIR_DOMAIN_EVENT_STOPPED_FAILED: + ret = "Failed"; + break; + } break; - default: - ret ="Unknown Event"; } return ret; } @@ -91,20 +147,24 @@ const char *eventToString(int event) { int myDomainEventCallback1 (virConnectPtr conn ATTRIBUTE_UNUSED, virDomainPtr dom, int event, + int detail, void *opaque ATTRIBUTE_UNUSED) { - printf("%s EVENT: Domain %s(%d) %s\n", __FUNCTION__, virDomainGetName(dom), - virDomainGetID(dom), eventToString(event)); + printf("%s EVENT: Domain %s(%d) %s %s\n", __FUNCTION__, virDomainGetName(dom), + virDomainGetID(dom), eventToString(event), + eventDetailToString(event, detail)); return 0; } int myDomainEventCallback2 (virConnectPtr conn ATTRIBUTE_UNUSED, virDomainPtr dom, int event, + int detail, void *opaque ATTRIBUTE_UNUSED) { - printf("%s EVENT: Domain %s(%d) %s\n", __FUNCTION__, virDomainGetName(dom), - virDomainGetID(dom), eventToString(event)); + printf("%s EVENT: Domain %s(%d) %s %s\n", __FUNCTION__, virDomainGetName(dom), + virDomainGetID(dom), eventToString(event), + eventDetailToString(event, detail)); return 0; } diff --git a/examples/domain-events/events-python/event-test.py b/examples/domain-events/events-python/event-test.py index 7082db00a4..d78ff60b05 100644 --- a/examples/domain-events/events-python/event-test.py +++ b/examples/domain-events/events-python/event-test.py @@ -32,11 +32,11 @@ def eventToString(event): "Restored" ); return eventStrings[event]; -def myDomainEventCallback1 (conn, dom, event, opaque): - print "myDomainEventCallback1 EVENT: Domain %s(%s) %s" % (dom.name(), dom.ID(), eventToString(event)) +def myDomainEventCallback1 (conn, dom, event, detail, opaque): + print "myDomainEventCallback1 EVENT: Domain %s(%s) %s %d" % (dom.name(), dom.ID(), eventToString(event), detail) -def myDomainEventCallback2 (conn, dom, event, opaque): - print "myDomainEventCallback2 EVENT: Domain %s(%s) %s" % (dom.name(), dom.ID(), eventToString(event)) +def myDomainEventCallback2 (conn, dom, event, detail, opaque): + print "myDomainEventCallback2 EVENT: Domain %s(%s) %s %d" % (dom.name(), dom.ID(), eventToString(event), detail) ##################################################### # EventImpl Functions diff --git a/include/libvirt/libvirt.h b/include/libvirt/libvirt.h index 077b9f3b67..d1bb154ebf 100644 --- a/include/libvirt/libvirt.h +++ b/include/libvirt/libvirt.h @@ -1004,21 +1004,85 @@ virDomainPtr virDomainCreateLinux (virConnectPtr conn, * a virDomainEventType is emitted during domain lifecycle events */ typedef enum { - VIR_DOMAIN_EVENT_ADDED = 0, - VIR_DOMAIN_EVENT_REMOVED = 1, + VIR_DOMAIN_EVENT_DEFINED = 0, + VIR_DOMAIN_EVENT_UNDEFINED = 1, VIR_DOMAIN_EVENT_STARTED = 2, VIR_DOMAIN_EVENT_SUSPENDED = 3, VIR_DOMAIN_EVENT_RESUMED = 4, VIR_DOMAIN_EVENT_STOPPED = 5, - VIR_DOMAIN_EVENT_SAVED = 6, - VIR_DOMAIN_EVENT_RESTORED = 7, } virDomainEventType; +/** + * virDomainEventDefinedDetailType: + * + * Details on the caused of the 'defined' lifecycle event + */ +typedef enum { + VIR_DOMAIN_EVENT_DEFINED_ADDED = 0, /* Newly created config file */ + VIR_DOMAIN_EVENT_DEFINED_UPDATED = 1, /* Changed config file */ +} virDomainEventDefinedDetailType; + +/** + * virDomainEventUndefinedDetailType: + * + * Details on the caused of the 'undefined' lifecycle event + */ +typedef enum { + VIR_DOMAIN_EVENT_UNDEFINED_REMOVED = 0, /* Deleted the config file */ +} virDomainEventUndefinedDetailType; + +/** + * virDomainEventStartedDetailType: + * + * Details on the caused of the 'started' lifecycle event + */ +typedef enum { + VIR_DOMAIN_EVENT_STARTED_BOOTED = 0, /* Normal startup from boot */ + VIR_DOMAIN_EVENT_STARTED_MIGRATED = 1, /* Incoming migration from another host */ + VIR_DOMAIN_EVENT_STARTED_RESTORED = 2, /* Restored from a state file */ +} virDomainEventStartedDetailType; + +/** + * virDomainEventSuspendedDetailType: + * + * Details on the caused of the 'suspended' lifecycle event + */ +typedef enum { + VIR_DOMAIN_EVENT_SUSPENDED_PAUSED = 0, /* Normal suspend due to admin pause */ + VIR_DOMAIN_EVENT_SUSPENDED_MIGRATED = 1, /* Suspended for offline migration */ +} virDomainEventSuspendedDetailType; + +/** + * virDomainEventResumedDetailType: + * + * Details on the caused of the 'resumed' lifecycle event + */ +typedef enum { + VIR_DOMAIN_EVENT_RESUMED_UNPAUSED = 0, /* Normal resume due to admin unpause */ + VIR_DOMAIN_EVENT_RESUMED_MIGRATED = 1, /* Resumed for completion of migration */ +} virDomainEventResumedDetailType; + +/** + * virDomainEventStoppedDetailType: + * + * Details on the caused of the 'stopped' lifecycle event + */ +typedef enum { + VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN = 0, /* Normal shutdown */ + VIR_DOMAIN_EVENT_STOPPED_DESTROYED = 1, /* Forced poweroff from host */ + VIR_DOMAIN_EVENT_STOPPED_CRASHED = 2, /* Guest crashed */ + VIR_DOMAIN_EVENT_STOPPED_MIGRATED = 3, /* Migrated off to another host */ + VIR_DOMAIN_EVENT_STOPPED_SAVED = 4, /* Saved to a state file */ + VIR_DOMAIN_EVENT_STOPPED_FAILED = 5, /* Host emulator/mgmt failed */ +} virDomainEventStoppedDetailType; + + /** * virConnectDomainEventCallback: * @conn: virConnect connection * @dom: The domain on which the event occured * @event: The specfic virDomainEventType which occured + * @detail: event specific detail information * @opaque: opaque user data * * A callback function to be registered, and called when a domain event occurs @@ -1026,6 +1090,7 @@ typedef enum { typedef int (*virConnectDomainEventCallback)(virConnectPtr conn, virDomainPtr dom, int event, + int detail, void *opaque); int virConnectDomainEventRegister(virConnectPtr conn, diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index fafc1443db..0ee657a215 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -1004,21 +1004,85 @@ virDomainPtr virDomainCreateLinux (virConnectPtr conn, * a virDomainEventType is emitted during domain lifecycle events */ typedef enum { - VIR_DOMAIN_EVENT_ADDED = 0, - VIR_DOMAIN_EVENT_REMOVED = 1, + VIR_DOMAIN_EVENT_DEFINED = 0, + VIR_DOMAIN_EVENT_UNDEFINED = 1, VIR_DOMAIN_EVENT_STARTED = 2, VIR_DOMAIN_EVENT_SUSPENDED = 3, VIR_DOMAIN_EVENT_RESUMED = 4, VIR_DOMAIN_EVENT_STOPPED = 5, - VIR_DOMAIN_EVENT_SAVED = 6, - VIR_DOMAIN_EVENT_RESTORED = 7, } virDomainEventType; +/** + * virDomainEventDefinedDetailType: + * + * Details on the caused of the 'defined' lifecycle event + */ +typedef enum { + VIR_DOMAIN_EVENT_DEFINED_ADDED = 0, /* Newly created config file */ + VIR_DOMAIN_EVENT_DEFINED_UPDATED = 1, /* Changed config file */ +} virDomainEventDefinedDetailType; + +/** + * virDomainEventUndefinedDetailType: + * + * Details on the caused of the 'undefined' lifecycle event + */ +typedef enum { + VIR_DOMAIN_EVENT_UNDEFINED_REMOVED = 0, /* Deleted the config file */ +} virDomainEventUndefinedDetailType; + +/** + * virDomainEventStartedDetailType: + * + * Details on the caused of the 'started' lifecycle event + */ +typedef enum { + VIR_DOMAIN_EVENT_STARTED_BOOTED = 0, /* Normal startup from boot */ + VIR_DOMAIN_EVENT_STARTED_MIGRATED = 1, /* Incoming migration from another host */ + VIR_DOMAIN_EVENT_STARTED_RESTORED = 2, /* Restored from a state file */ +} virDomainEventStartedDetailType; + +/** + * virDomainEventSuspendedDetailType: + * + * Details on the caused of the 'suspended' lifecycle event + */ +typedef enum { + VIR_DOMAIN_EVENT_SUSPENDED_PAUSED = 0, /* Normal suspend due to admin pause */ + VIR_DOMAIN_EVENT_SUSPENDED_MIGRATED = 1, /* Suspended for offline migration */ +} virDomainEventSuspendedDetailType; + +/** + * virDomainEventResumedDetailType: + * + * Details on the caused of the 'resumed' lifecycle event + */ +typedef enum { + VIR_DOMAIN_EVENT_RESUMED_UNPAUSED = 0, /* Normal resume due to admin unpause */ + VIR_DOMAIN_EVENT_RESUMED_MIGRATED = 1, /* Resumed for completion of migration */ +} virDomainEventResumedDetailType; + +/** + * virDomainEventStoppedDetailType: + * + * Details on the caused of the 'stopped' lifecycle event + */ +typedef enum { + VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN = 0, /* Normal shutdown */ + VIR_DOMAIN_EVENT_STOPPED_DESTROYED = 1, /* Forced poweroff from host */ + VIR_DOMAIN_EVENT_STOPPED_CRASHED = 2, /* Guest crashed */ + VIR_DOMAIN_EVENT_STOPPED_MIGRATED = 3, /* Migrated off to another host */ + VIR_DOMAIN_EVENT_STOPPED_SAVED = 4, /* Saved to a state file */ + VIR_DOMAIN_EVENT_STOPPED_FAILED = 5, /* Host emulator/mgmt failed */ +} virDomainEventStoppedDetailType; + + /** * virConnectDomainEventCallback: * @conn: virConnect connection * @dom: The domain on which the event occured * @event: The specfic virDomainEventType which occured + * @detail: event specific detail information * @opaque: opaque user data * * A callback function to be registered, and called when a domain event occurs @@ -1026,6 +1090,7 @@ typedef enum { typedef int (*virConnectDomainEventCallback)(virConnectPtr conn, virDomainPtr dom, int event, + int detail, void *opaque); int virConnectDomainEventRegister(virConnectPtr conn, diff --git a/python/libvir.c b/python/libvir.c index 7da3d2c7ce..96ccb28650 100644 --- a/python/libvir.c +++ b/python/libvir.c @@ -1538,6 +1538,7 @@ static int libvirt_virConnectDomainEventCallback(virConnectPtr conn ATTRIBUTE_UNUSED, virDomainPtr dom, int event, + int detail, void *opaque) { PyObject *pyobj_ret; @@ -1595,9 +1596,10 @@ libvirt_virConnectDomainEventCallback(virConnectPtr conn ATTRIBUTE_UNUSED, /* Call the Callback Dispatcher */ pyobj_ret = PyObject_CallMethod(pyobj_conn_inst, (char*)"dispatchDomainEventCallbacks", - (char*)"Oi", + (char*)"Oii", pyobj_dom_inst, - event); + event, + detail); Py_DECREF(pyobj_dom_inst); diff --git a/qemud/qemud.h b/qemud/qemud.h index 822ed939c1..700d2ee046 100644 --- a/qemud/qemud.h +++ b/qemud/qemud.h @@ -190,6 +190,7 @@ int qemudGetSocketIdentity(int fd, uid_t *uid, pid_t *pid); int remoteRelayDomainEvent (virConnectPtr conn ATTRIBUTE_UNUSED, virDomainPtr dom, int event, + int detail, void *opaque); #endif diff --git a/qemud/remote.c b/qemud/remote.c index 035c9e2314..e9b2387e72 100644 --- a/qemud/remote.c +++ b/qemud/remote.c @@ -80,7 +80,8 @@ typedef int (*dispatch_fn) (struct qemud_server *server, static void remoteDispatchDomainEventSend (struct qemud_client *client, virDomainPtr dom, - virDomainEventType event); + int event, + int detail); /* This function gets called from qemud when it detects an incoming * remote protocol message. At this point, client->buffer contains @@ -413,15 +414,16 @@ remoteDispatchError (struct qemud_client *client, } int remoteRelayDomainEvent (virConnectPtr conn ATTRIBUTE_UNUSED, - virDomainPtr dom, - int event, - void *opaque) + virDomainPtr dom, + int event, + int detail, + void *opaque) { struct qemud_client *client = opaque; - REMOTE_DEBUG("Relaying domain event %d", event); + REMOTE_DEBUG("Relaying domain event %d %d", event, detail); if(client) { - remoteDispatchDomainEventSend (client, dom, event); + remoteDispatchDomainEventSend (client, dom, event, detail); qemudDispatchClientWrite(client->server,client); } return 0; @@ -3779,8 +3781,9 @@ remoteDispatchDomainEventsDeregister (struct qemud_server *server ATTRIBUTE_UNUS static void remoteDispatchDomainEventSend (struct qemud_client *client, - virDomainPtr dom, - virDomainEventType event) + virDomainPtr dom, + int event, + int detail) { remote_message_header rep; XDR xdr; @@ -3816,7 +3819,8 @@ remoteDispatchDomainEventSend (struct qemud_client *client, /* build return data */ make_nonnull_domain (&data.dom, dom); - data.event = (int) event; + data.event = event; + data.detail = detail; if (!xdr_remote_domain_event_ret(&xdr, &data)) { remoteDispatchError (client, NULL, "%s", _("serialise return struct")); diff --git a/qemud/remote_protocol.c b/qemud/remote_protocol.c index 5e573fe878..0994e046e5 100644 --- a/qemud/remote_protocol.c +++ b/qemud/remote_protocol.c @@ -2033,6 +2033,8 @@ xdr_remote_domain_event_ret (XDR *xdrs, remote_domain_event_ret *objp) return FALSE; if (!xdr_int (xdrs, &objp->event)) return FALSE; + if (!xdr_int (xdrs, &objp->detail)) + return FALSE; return TRUE; } diff --git a/qemud/remote_protocol.h b/qemud/remote_protocol.h index a0e8a9df56..89bd2ea03a 100644 --- a/qemud/remote_protocol.h +++ b/qemud/remote_protocol.h @@ -1135,6 +1135,7 @@ typedef struct remote_domain_events_deregister_ret remote_domain_events_deregist struct remote_domain_event_ret { remote_nonnull_domain dom; int event; + int detail; }; typedef struct remote_domain_event_ret remote_domain_event_ret; #define REMOTE_PROGRAM 0x20008086 diff --git a/qemud/remote_protocol.x b/qemud/remote_protocol.x index e337944a34..e97375284b 100644 --- a/qemud/remote_protocol.x +++ b/qemud/remote_protocol.x @@ -1011,6 +1011,7 @@ struct remote_domain_events_deregister_ret { struct remote_domain_event_ret { remote_nonnull_domain dom; int event; + int detail; }; /*----- Protocol. -----*/ diff --git a/src/domain_event.c b/src/domain_event.c index a74ae5dd05..2d159366a0 100644 --- a/src/domain_event.c +++ b/src/domain_event.c @@ -198,7 +198,8 @@ virDomainEventCallbackQueuePop(virDomainEventQueuePtr evtQueue) int virDomainEventCallbackQueuePush(virDomainEventQueuePtr evtQueue, virDomainPtr dom, - virDomainEventType event) + int event, + int detail) { virDomainEventPtr domEvent; @@ -214,6 +215,7 @@ virDomainEventCallbackQueuePush(virDomainEventQueuePtr evtQueue, } domEvent->dom = dom; domEvent->event = event; + domEvent->detail = detail; /* Make space on queue */ if (VIR_REALLOC_N(evtQueue->events, diff --git a/src/domain_event.h b/src/domain_event.h index 6b0eeb4f8b..c26ec3b39a 100644 --- a/src/domain_event.h +++ b/src/domain_event.h @@ -58,7 +58,8 @@ int virDomainEventCallbackListRemove(virConnectPtr conn, */ struct _virDomainEvent { virDomainPtr dom; - virDomainEventType event; + int event; + int detail; }; typedef struct _virDomainEvent virDomainEvent; typedef virDomainEvent *virDomainEventPtr; @@ -72,7 +73,8 @@ typedef virDomainEventQueue *virDomainEventQueuePtr; int virDomainEventCallbackQueuePush(virDomainEventQueuePtr evtQueue, virDomainPtr dom, - virDomainEventType event); + int event, + int detail); virDomainEventPtr virDomainEventCallbackQueuePop(virDomainEventQueuePtr evtQueue); diff --git a/src/qemu_driver.c b/src/qemu_driver.c index 9cf625d263..3ad6a557c6 100644 --- a/src/qemu_driver.c +++ b/src/qemu_driver.c @@ -107,7 +107,8 @@ static int qemudSetNonBlock(int fd) { static void qemudDomainEventDispatch (struct qemud_driver *driver, virDomainObjPtr vm, - virDomainEventType evt); + int event, + int detail); static void qemudDispatchVMEvent(int fd, int events, @@ -137,13 +138,19 @@ qemudAutostartConfigs(struct qemud_driver *driver) { unsigned int i; for (i = 0 ; i < driver->domains.count ; i++) { - if (driver->domains.objs[i]->autostart && - !virDomainIsActive(driver->domains.objs[i]) && - qemudStartVMDaemon(NULL, driver, driver->domains.objs[i], NULL) < 0) { - virErrorPtr err = virGetLastError(); - qemudLog(QEMUD_ERR, _("Failed to autostart VM '%s': %s\n"), - driver->domains.objs[i]->def->name, - err ? err->message : NULL); + virDomainObjPtr vm = driver->domains.objs[i]; + if (vm->autostart && + !virDomainIsActive(vm)) { + int ret = qemudStartVMDaemon(NULL, driver, vm, NULL); + if (ret < 0) { + virErrorPtr err = virGetLastError(); + qemudLog(QEMUD_ERR, _("Failed to autostart VM '%s': %s\n"), + vm->def->name, + err ? err->message : NULL); + } else { + qemudDomainEventDispatch(driver, vm, VIR_DOMAIN_EVENT_STARTED, + VIR_DOMAIN_EVENT_STARTED_BOOTED); + } } } } @@ -945,7 +952,6 @@ static int qemudStartVMDaemon(virConnectPtr conn, qemudShutdownVMDaemon(conn, driver, vm); return -1; } - qemudDomainEventDispatch(driver, vm, VIR_DOMAIN_EVENT_STARTED); } return ret; @@ -1030,6 +1036,9 @@ static void qemudShutdownVMDaemon(virConnectPtr conn ATTRIBUTE_UNUSED, static int qemudDispatchVMLog(struct qemud_driver *driver, virDomainObjPtr vm, int fd) { if (qemudVMData(driver, vm, fd) < 0) { qemudShutdownVMDaemon(NULL, driver, vm); + qemudDomainEventDispatch(driver, vm, + VIR_DOMAIN_EVENT_STOPPED, + VIR_DOMAIN_EVENT_STOPPED_FAILED); if (!vm->persistent) virDomainRemoveInactive(&driver->domains, vm); @@ -1040,7 +1049,9 @@ static int qemudDispatchVMLog(struct qemud_driver *driver, virDomainObjPtr vm, i static int qemudDispatchVMFailure(struct qemud_driver *driver, virDomainObjPtr vm, int fd ATTRIBUTE_UNUSED) { qemudShutdownVMDaemon(NULL, driver, vm); - qemudDomainEventDispatch(driver, vm, VIR_DOMAIN_EVENT_STOPPED); + qemudDomainEventDispatch(driver, vm, + VIR_DOMAIN_EVENT_STOPPED, + VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN); if (!vm->persistent) virDomainRemoveInactive(&driver->domains, vm); @@ -1518,6 +1529,9 @@ static virDomainPtr qemudDomainCreate(virConnectPtr conn, const char *xml, vm); return NULL; } + qemudDomainEventDispatch(driver, vm, + VIR_DOMAIN_EVENT_STARTED, + VIR_DOMAIN_EVENT_STARTED_BOOTED); dom = virGetDomain(conn, vm->def->name, vm->def->uuid); if (dom) dom->id = vm->def->id; @@ -1548,7 +1562,9 @@ static int qemudDomainSuspend(virDomainPtr dom) { } vm->state = VIR_DOMAIN_PAUSED; qemudDebug("Reply %s", info); - qemudDomainEventDispatch(driver, vm, VIR_DOMAIN_EVENT_SUSPENDED); + qemudDomainEventDispatch(driver, vm, + VIR_DOMAIN_EVENT_SUSPENDED, + VIR_DOMAIN_EVENT_SUSPENDED_PAUSED); VIR_FREE(info); return 0; } @@ -1577,7 +1593,9 @@ static int qemudDomainResume(virDomainPtr dom) { } vm->state = VIR_DOMAIN_RUNNING; qemudDebug("Reply %s", info); - qemudDomainEventDispatch(driver, vm, VIR_DOMAIN_EVENT_RESUMED); + qemudDomainEventDispatch(driver, vm, + VIR_DOMAIN_EVENT_RESUMED, + VIR_DOMAIN_EVENT_RESUMED_UNPAUSED); VIR_FREE(info); return 0; } @@ -1616,7 +1634,9 @@ static int qemudDomainDestroy(virDomainPtr dom) { } qemudShutdownVMDaemon(dom->conn, driver, vm); - qemudDomainEventDispatch(driver, vm, VIR_DOMAIN_EVENT_STOPPED); + qemudDomainEventDispatch(driver, vm, + VIR_DOMAIN_EVENT_STOPPED, + VIR_DOMAIN_EVENT_STOPPED_DESTROYED); if (!vm->persistent) virDomainRemoveInactive(&driver->domains, vm); @@ -1947,10 +1967,12 @@ static int qemudDomainSave(virDomainPtr dom, /* Shut it down */ qemudShutdownVMDaemon(dom->conn, driver, vm); + qemudDomainEventDispatch(driver, vm, + VIR_DOMAIN_EVENT_STOPPED, + VIR_DOMAIN_EVENT_STOPPED_SAVED); if (!vm->persistent) virDomainRemoveInactive(&driver->domains, vm); - qemudDomainEventDispatch(driver, vm, VIR_DOMAIN_EVENT_SAVED); return 0; } @@ -2245,6 +2267,10 @@ static int qemudDomainRestore(virConnectPtr conn, return -1; } + qemudDomainEventDispatch(driver, vm, + VIR_DOMAIN_EVENT_STARTED, + VIR_DOMAIN_EVENT_STARTED_RESTORED); + /* If it was running before, resume it now. */ if (header.was_running) { char *info; @@ -2257,7 +2283,6 @@ static int qemudDomainRestore(virConnectPtr conn, vm->state = VIR_DOMAIN_RUNNING; } - qemudDomainEventDispatch(driver, vm, VIR_DOMAIN_EVENT_RESTORED); return 0; } @@ -2317,6 +2342,7 @@ static int qemudNumDefinedDomains(virConnectPtr conn) { static int qemudDomainStart(virDomainPtr dom) { struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData; virDomainObjPtr vm = virDomainFindByUUID(&driver->domains, dom->uuid); + int ret; if (!vm) { qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN, @@ -2324,7 +2350,13 @@ static int qemudDomainStart(virDomainPtr dom) { return -1; } - return qemudStartVMDaemon(dom->conn, driver, vm, NULL); + ret = qemudStartVMDaemon(dom->conn, driver, vm, NULL); + if (ret < 0) + return ret; + qemudDomainEventDispatch(driver, vm, + VIR_DOMAIN_EVENT_STARTED, + VIR_DOMAIN_EVENT_STARTED_BOOTED); + return 0; } @@ -3345,7 +3377,8 @@ qemudDomainEventDeregister (virConnectPtr conn, static void qemudDomainEventDispatch (struct qemud_driver *driver, virDomainObjPtr vm, - virDomainEventType evt) + int event, + int detail) { int i; virDomainEventCallbackListPtr cbList; @@ -3359,11 +3392,11 @@ static void qemudDomainEventDispatch (struct qemud_driver *driver, vm->def->uuid); if (dom) { dom->id = virDomainIsActive(vm) ? vm->def->id : -1; - DEBUG("Dispatching callback %p %p event %d", - cbList->callbacks[i], - cbList->callbacks[i]->cb, evt); + DEBUG("Dispatching callback %p %p event %d detail %d", + cbList->callbacks[i], + cbList->callbacks[i]->cb, event, detail); cbList->callbacks[i]->cb(cbList->callbacks[i]->conn, - dom, evt, + dom, event, detail, cbList->callbacks[i]->opaque); virDomainFree(dom); } @@ -3512,6 +3545,9 @@ qemudDomainMigratePrepare2 (virConnectPtr dconn, return -1; } + qemudDomainEventDispatch(driver, vm, + VIR_DOMAIN_EVENT_STARTED, + VIR_DOMAIN_EVENT_STARTED_MIGRATED); return 0; } @@ -3544,6 +3580,18 @@ qemudDomainMigratePerform (virDomainPtr dom, return -1; } + if (!(flags & VIR_MIGRATE_LIVE)) { + /* Pause domain for non-live migration */ + snprintf(cmd, sizeof cmd, "%s", "stop"); + qemudMonitorCommand (driver, vm, cmd, &info); + DEBUG ("stop reply: %s", info); + VIR_FREE(info); + + qemudDomainEventDispatch(driver, vm, + VIR_DOMAIN_EVENT_SUSPENDED, + VIR_DOMAIN_EVENT_SUSPENDED_MIGRATED); + } + if (resource > 0) { /* Issue migrate_set_speed command. Don't worry if it fails. */ snprintf (cmd, sizeof cmd, "migrate_set_speed %lum", resource); @@ -3583,6 +3631,9 @@ qemudDomainMigratePerform (virDomainPtr dom, /* Clean up the source domain. */ qemudShutdownVMDaemon (dom->conn, driver, vm); + qemudDomainEventDispatch(driver, vm, + VIR_DOMAIN_EVENT_STOPPED, + VIR_DOMAIN_EVENT_STOPPED_MIGRATED); if (!vm->persistent) virDomainRemoveInactive(&driver->domains, vm); @@ -3617,9 +3668,15 @@ qemudDomainMigrateFinish2 (virConnectPtr dconn, dom = virGetDomain (dconn, vm->def->name, vm->def->uuid); VIR_FREE(info); vm->state = VIR_DOMAIN_RUNNING; + qemudDomainEventDispatch(driver, vm, + VIR_DOMAIN_EVENT_RESUMED, + VIR_DOMAIN_EVENT_RESUMED_MIGRATED); return dom; } else { qemudShutdownVMDaemon (dconn, driver, vm); + qemudDomainEventDispatch(driver, vm, + VIR_DOMAIN_EVENT_STOPPED, + VIR_DOMAIN_EVENT_STOPPED_FAILED); if (!vm->persistent) virDomainRemoveInactive(&driver->domains, vm); return NULL; diff --git a/src/remote_internal.c b/src/remote_internal.c index 9b85242c4a..2ca79301cd 100644 --- a/src/remote_internal.c +++ b/src/remote_internal.c @@ -5206,7 +5206,7 @@ remoteRegister (void) */ static int remoteDomainReadEvent(virConnectPtr conn, XDR *xdr, - virDomainPtr *dom, int *event) + virDomainPtr *dom, int *event, int *detail) { remote_domain_event_ret ret; memset (&ret, 0, sizeof ret); @@ -5220,6 +5220,7 @@ remoteDomainReadEvent(virConnectPtr conn, XDR *xdr, *dom = get_nonnull_domain(conn,ret.dom); *event = ret.event; + *detail = ret.detail; return 0; } @@ -5228,15 +5229,16 @@ static void remoteDomainProcessEvent(virConnectPtr conn, XDR *xdr) { virDomainPtr dom; - int event,i; + int event, detail, i; struct private_data *priv = conn->privateData; - if(!remoteDomainReadEvent(conn, xdr, &dom, &event)) { + if(!remoteDomainReadEvent(conn, xdr, &dom, &event, &detail)) { DEBUG0("Calling domain event callbacks (no queue)"); for(i=0 ; i < priv->callbackList->count ; i++) { - if( priv->callbackList->callbacks[i] ) - priv->callbackList->callbacks[i]->cb(conn, dom, event, - priv->callbackList->callbacks[i]->opaque); + if (priv->callbackList->callbacks[i] ) + priv->callbackList->callbacks[i]->cb( + conn, dom, event, detail, + priv->callbackList->callbacks[i]->opaque); } } } @@ -5245,13 +5247,13 @@ static void remoteDomainQueueEvent(virConnectPtr conn, XDR *xdr) { virDomainPtr dom; - int event; + int event, detail; struct private_data *priv = conn->privateData; - if(!remoteDomainReadEvent(conn, xdr, &dom, &event)) + if(!remoteDomainReadEvent(conn, xdr, &dom, &event, &detail)) { if( virDomainEventCallbackQueuePush(priv->domainEvents, - dom, event) < 0 ) { + dom, event, detail) < 0 ) { DEBUG("%s", "Error adding event to queue"); } } @@ -5344,6 +5346,7 @@ remoteDomainEventQueueFlush(int timer ATTRIBUTE_UNUSED, void *opaque) priv->callbackList->callbacks[i]->cb(domEvent->dom->conn, domEvent->dom, domEvent->event, + domEvent->detail, user_data); } }