[libvirt] PATCH: Add domain event "detail" information
Ben Guthro
bguthro at virtualiron.com
Fri Nov 14 17:52:40 UTC 2008
Looks pretty much exactly how I pictured it
+1
Daniel P. Berrange wrote on 11/14/2008 12:44 PM:
> As per our earlier discussion today, this patch expands the callback for
> domain events so that it also gets a event type specific 'detail' field.
> This is also kept as an int, and we define enumerations for the possible
> values associated with each type. If a event type has no detail, 0 is
> passed.
>
> The RESTORED and SAVED event types disappear in this patch and just become
> another piece of 'detail' to the STOPPED and STARTED events. I have also
> renamed ADDED & REMOVED to DEFINED and UNDEFINED to match terminology we
> have elsewhere & because the names were confusing me
>
> Easiest to just look at the final set:
>
> typedef enum {
> 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,
> } virDomainEventType;
>
> 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;
>
> 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;
>
> typedef enum {
> VIR_DOMAIN_EVENT_DEFINED_ADDED = 0, /* Newly created config file */
> VIR_DOMAIN_EVENT_DEFINED_UPDATED = 1, /* Changed config file */
> } virDomainEventDefinedDetailType;
>
> I don't make use of 'CRASHED' in QEMU driver yet. It might be useful in
> Xen though - when a PV guest crashes, Xen stops the domain running, but
> leaves it there in a shutoff state, but marked as crashed.
>
> Now using the C event-test program you can see the effects:
>
> myDomainEventCallback1 EVENT: Domain F9x86_64(2) Started Booted
> myDomainEventCallback2 EVENT: Domain F9x86_64(2) Started Booted
> myDomainEventCallback1 EVENT: Domain F9x86_64(-1) Stopped Destroyed
> myDomainEventCallback2 EVENT: Domain F9x86_64(-1) Stopped Destroyed
> myDomainEventCallback1 EVENT: Domain F9x86_64(3) Started Booted
> myDomainEventCallback2 EVENT: Domain F9x86_64(3) Started Booted
> myDomainEventCallback1 EVENT: Domain F9x86_64(3) Suspended
> myDomainEventCallback2 EVENT: Domain F9x86_64(3) Suspended
> myDomainEventCallback1 EVENT: Domain F9x86_64(3) Resumed
> myDomainEventCallback2 EVENT: Domain F9x86_64(3) Resumed
> myDomainEventCallback1 EVENT: Domain F9x86_64(-1) Stopped Shutdown
> myDomainEventCallback2 EVENT: Domain F9x86_64(-1) Stopped Shutdown
>
> Of the following sequence of actions
>
> virsh start F9x86_64
> virsh destroy F9x86_64
> virsh start F9x86_64
> virsh suspend F9x86_64
> virsh resume F9x86_64
> virsh shutdown F9x86_64
>
> For the last 'shutdown' operation, you'll see the same if you just run
> a graceful shutdown inside the guest itself.
>
> NB, I've not tested saved/restored because my install of KVM is not new
> enough to support that correctly, but I expect it to work without trouble.
> Likewise for migration.
>
> A word about migration...
>
> - The destination host first gets a STARTED event, with detail MIGRATED
> when it starts running
> - The source host then gets a STOPPED event with detail MIGRATED when
> it completes
> - The destination host then gets a RESUMED event, on success, and
> a STOPPED event with detail FAILED if migration aborts.
>
> Daniel
>
> examples/domain-events/events-c/event-test.c | 78 +++++++++++++++----
> examples/domain-events/events-python/event-test.py | 8 +-
> include/libvirt/libvirt.h | 29 ++++++-
> include/libvirt/libvirt.h.in | 29 ++++++-
> python/libvir.c | 6 +
> qemud/qemud.h | 1
> qemud/remote.c | 22 +++--
> qemud/remote_protocol.c | 2
> qemud/remote_protocol.h | 1
> qemud/remote_protocol.x | 1
> src/domain_event.c | 4 -
> src/domain_event.h | 6 +
> src/qemu_driver.c | 82 +++++++++++++++------
> src/remote_internal.c | 29 ++++---
> 18 files changed, 366 insertions(+), 118 deletions(-)
>
>
>
> diff --git a/examples/domain-events/events-c/event-test.c b/examples/domain-events/events-c/event-test.c
> --- 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);
> @@ -58,11 +58,11 @@ const char *eventToString(int event) {
> const char *eventToString(int event) {
> const char *ret = NULL;
> 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,56 @@ const char *eventToString(int event) {
> case VIR_DOMAIN_EVENT_STOPPED:
> ret ="Stopped";
> break;
> - case VIR_DOMAIN_EVENT_SAVED:
> - ret ="Saved";
> - break;
> - case VIR_DOMAIN_EVENT_RESTORED:
> - ret ="Restored";
> - break;
> default:
> ret ="Unknown Event";
> + }
> + 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_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_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;
> }
> return ret;
> }
> @@ -91,20 +133,24 @@ int myDomainEventCallback1 (virConnectPt
> 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
> --- 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
> --- a/include/libvirt/libvirt.h
> +++ b/include/libvirt/libvirt.h
> @@ -1004,21 +1004,41 @@ virDomainPtr virDomainCreateL
> * 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;
> +
> +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;
> +
> +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;
> +
> +typedef enum {
> + VIR_DOMAIN_EVENT_DEFINED_ADDED = 0, /* Newly created config file */
> + VIR_DOMAIN_EVENT_DEFINED_UPDATED = 1, /* Changed config file */
> +} virDomainEventDefinedDetailType;
> +
>
> /**
> * 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 +1046,7 @@ typedef int (*virConnectDomainEventCallb
> 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
> --- a/include/libvirt/libvirt.h.in
> +++ b/include/libvirt/libvirt.h.in
> @@ -1004,21 +1004,41 @@ virDomainPtr virDomainCreateL
> * 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;
> +
> +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;
> +
> +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;
> +
> +typedef enum {
> + VIR_DOMAIN_EVENT_DEFINED_ADDED = 0, /* Newly created config file */
> + VIR_DOMAIN_EVENT_DEFINED_UPDATED = 1, /* Changed config file */
> +} virDomainEventDefinedDetailType;
> +
>
> /**
> * 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 +1046,7 @@ typedef int (*virConnectDomainEventCallb
> 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
> --- a/python/libvir.c
> +++ b/python/libvir.c
> @@ -1538,6 +1538,7 @@ libvirt_virConnectDomainEventCallback(vi
> libvirt_virConnectDomainEventCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
> virDomainPtr dom,
> int event,
> + int detail,
> void *opaque)
> {
> PyObject *pyobj_ret;
> @@ -1595,9 +1596,10 @@ libvirt_virConnectDomainEventCallback(vi
> /* 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
> --- a/qemud/qemud.h
> +++ b/qemud/qemud.h
> @@ -190,6 +190,7 @@ int remoteRelayDomainEvent (virConnectPt
> 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
> --- a/qemud/remote.c
> +++ b/qemud/remote.c
> @@ -80,7 +80,8 @@ static void
> 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
> }
>
> 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;
> @@ -3762,8 +3764,9 @@ remoteDispatchDomainEventsDeregister (st
>
> static void
> remoteDispatchDomainEventSend (struct qemud_client *client,
> - virDomainPtr dom,
> - virDomainEventType event)
> + virDomainPtr dom,
> + int event,
> + int detail)
> {
> remote_message_header rep;
> XDR xdr;
> @@ -3799,7 +3802,8 @@ remoteDispatchDomainEventSend (struct qe
>
> /* 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
> --- a/qemud/remote_protocol.c
> +++ b/qemud/remote_protocol.c
> @@ -2024,6 +2024,8 @@ xdr_remote_domain_event_ret (XDR *xdrs,
> 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
> --- a/qemud/remote_protocol.h
> +++ b/qemud/remote_protocol.h
> @@ -1130,6 +1130,7 @@ struct remote_domain_event_ret {
> 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
> --- a/qemud/remote_protocol.x
> +++ b/qemud/remote_protocol.x
> @@ -1007,6 +1007,7 @@ struct remote_domain_event_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
> --- a/src/domain_event.c
> +++ b/src/domain_event.c
> @@ -198,7 +198,8 @@ int
> int
> virDomainEventCallbackQueuePush(virDomainEventQueuePtr evtQueue,
> virDomainPtr dom,
> - virDomainEventType event)
> + int event,
> + int detail)
> {
> virDomainEventPtr domEvent;
>
> @@ -214,6 +215,7 @@ virDomainEventCallbackQueuePush(virDomai
> }
> 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
> --- a/src/domain_event.h
> +++ b/src/domain_event.h
> @@ -58,7 +58,8 @@ int virDomainEventCallbackListRemove(vir
> */
> struct _virDomainEvent {
> virDomainPtr dom;
> - virDomainEventType event;
> + int event;
> + int detail;
> };
> typedef struct _virDomainEvent virDomainEvent;
> typedef virDomainEvent *virDomainEventPtr;
> @@ -72,7 +73,8 @@ typedef virDomainEventQueue *virDomainEv
>
> 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
> --- 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_drive
> 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(virConnect
> qemudShutdownVMDaemon(conn, driver, vm);
> return -1;
> }
> - qemudDomainEventDispatch(driver, vm, VIR_DOMAIN_EVENT_STARTED);
> }
>
> return ret;
> @@ -1030,6 +1036,9 @@ static int qemudDispatchVMLog(struct qem
> 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 qemudDispatchVMFailure(struct
> 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);
> @@ -1513,6 +1524,9 @@ static virDomainPtr qemudDomainCreate(vi
> 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;
> @@ -1543,7 +1557,7 @@ static int qemudDomainSuspend(virDomainP
> }
> vm->state = VIR_DOMAIN_PAUSED;
> qemudDebug("Reply %s", info);
> - qemudDomainEventDispatch(driver, vm, VIR_DOMAIN_EVENT_SUSPENDED);
> + qemudDomainEventDispatch(driver, vm, VIR_DOMAIN_EVENT_SUSPENDED, 0);
> VIR_FREE(info);
> return 0;
> }
> @@ -1572,7 +1586,7 @@ static int qemudDomainResume(virDomainPt
> }
> vm->state = VIR_DOMAIN_RUNNING;
> qemudDebug("Reply %s", info);
> - qemudDomainEventDispatch(driver, vm, VIR_DOMAIN_EVENT_RESUMED);
> + qemudDomainEventDispatch(driver, vm, VIR_DOMAIN_EVENT_RESUMED, 0);
> VIR_FREE(info);
> return 0;
> }
> @@ -1611,7 +1625,9 @@ static int qemudDomainDestroy(virDomainP
> }
>
> 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);
> @@ -1942,10 +1958,12 @@ static int qemudDomainSave(virDomainPtr
>
> /* 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;
> }
>
> @@ -2240,6 +2258,10 @@ static int qemudDomainRestore(virConnect
> 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;
> @@ -2252,7 +2274,6 @@ static int qemudDomainRestore(virConnect
> vm->state = VIR_DOMAIN_RUNNING;
> }
>
> - qemudDomainEventDispatch(driver, vm, VIR_DOMAIN_EVENT_RESTORED);
> return 0;
> }
>
> @@ -2312,6 +2333,7 @@ static int qemudDomainStart(virDomainPtr
> 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,
> @@ -2319,7 +2341,13 @@ static int qemudDomainStart(virDomainPtr
> 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;
> }
>
>
> @@ -3340,7 +3368,8 @@ qemudDomainEventDeregister (virConnectPt
>
> static void qemudDomainEventDispatch (struct qemud_driver *driver,
> virDomainObjPtr vm,
> - virDomainEventType evt)
> + int event,
> + int detail)
> {
> int i;
> virDomainEventCallbackListPtr cbList;
> @@ -3354,11 +3383,11 @@ static void qemudDomainEventDispatch (st
> 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);
> }
> @@ -3507,6 +3536,9 @@ qemudDomainMigratePrepare2 (virConnectPt
>
> return -1;
> }
> + qemudDomainEventDispatch(driver, vm,
> + VIR_DOMAIN_EVENT_STARTED,
> + VIR_DOMAIN_EVENT_STARTED_MIGRATED);
>
> return 0;
> }
> @@ -3578,6 +3610,9 @@ qemudDomainMigratePerform (virDomainPtr
>
> /* 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);
>
> @@ -3612,9 +3647,14 @@ qemudDomainMigrateFinish2 (virConnectPtr
> dom = virGetDomain (dconn, vm->def->name, vm->def->uuid);
> VIR_FREE(info);
> vm->state = VIR_DOMAIN_RUNNING;
> + qemudDomainEventDispatch(driver, vm,
> + VIR_DOMAIN_EVENT_RESUMED, 0);
> 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
> --- a/src/remote_internal.c
> +++ b/src/remote_internal.c
> @@ -5154,7 +5154,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);
> @@ -5168,6 +5168,7 @@ remoteDomainReadEvent(virConnectPtr conn
>
> *dom = get_nonnull_domain(conn,ret.dom);
> *event = ret.event;
> + *detail = ret.detail;
>
> return 0;
> }
> @@ -5176,15 +5177,16 @@ remoteDomainProcessEvent(virConnectPtr c
> remoteDomainProcessEvent(virConnectPtr conn, XDR *xdr)
> {
> virDomainPtr dom;
> - int event,i;
> - struct private_data *priv = conn->privateData;
> -
> - if(!remoteDomainReadEvent(conn, xdr, &dom, &event)) {
> + int event, detail, i;
> + struct private_data *priv = conn->privateData;
> +
> + 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);
> }
> }
> }
> @@ -5193,13 +5195,13 @@ remoteDomainQueueEvent(virConnectPtr con
> remoteDomainQueueEvent(virConnectPtr conn, XDR *xdr)
> {
> virDomainPtr dom;
> - int event;
> - struct private_data *priv = conn->privateData;
> -
> - if(!remoteDomainReadEvent(conn, xdr, &dom, &event))
> + int event, detail;
> + struct private_data *priv = conn->privateData;
> +
> + 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");
> }
> }
> @@ -5292,6 +5294,7 @@ remoteDomainEventQueueFlush(int timer AT
> priv->callbackList->callbacks[i]->cb(domEvent->dom->conn,
> domEvent->dom,
> domEvent->event,
> + domEvent->detail,
> user_data);
> }
> }
>
>
More information about the libvir-list
mailing list