[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