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); > } > } > > -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list