[libvirt] [PATCHv2 2/8] Add event callbacks to libxl driver

Jim Fehlig jfehlig at novell.com
Mon Mar 28 17:32:11 UTC 2011


Markus Groß wrote:
> ---
>  src/libxl/libxl_conf.h   |    8 ++-
>  src/libxl/libxl_driver.c |  194 +++++++++++++++++++++++++++++++++++++++++++++-
>  2 files changed, 197 insertions(+), 5 deletions(-)
>
> diff --git a/src/libxl/libxl_conf.h b/src/libxl/libxl_conf.h
> index bb49d35..a86df9a 100644
> --- a/src/libxl/libxl_conf.h
> +++ b/src/libxl/libxl_conf.h
> @@ -26,6 +26,7 @@
>  
>  # include "internal.h"
>  # include "domain_conf.h"
> +# include "domain_event.h"
>  # include "capabilities.h"
>  # include "configmake.h"
>  # include "bitmap.h"
> @@ -57,6 +58,12 @@ struct _libxlDriverPrivate {
>      virBitmapPtr reservedVNCPorts;
>      virDomainObjList domains;
>  
> +    /* A list of callbacks */
> +    virDomainEventCallbackListPtr domainEventCallbacks;
> +    virDomainEventQueuePtr domainEventQueue;
> +    int domainEventTimer;
> +    int domainEventDispatching;
> +
>      char *configDir;
>      char *autostartDir;
>      char *logDir;
> @@ -87,5 +94,4 @@ int
>  libxlBuildDomainConfig(libxlDriverPrivatePtr driver,
>                         virDomainDefPtr def, libxl_domain_config *d_config);
>  
> -
>   

Spurious whitespace change, but removing this unnecessary line is fine.

>  #endif /* LIBXL_CONF_H */
> diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
> index 80a43a0..64f1505 100644
> --- a/src/libxl/libxl_driver.c
> +++ b/src/libxl/libxl_driver.c
> @@ -99,6 +99,58 @@ libxlDomainObjPrivateFree(void *data)
>      VIR_FREE(priv);
>  }
>  
> +static void
> +libxlDomainEventDispatchFunc(virConnectPtr conn, virDomainEventPtr event,
> +                             virConnectDomainEventGenericCallback cb,
> +                             void *cbopaque, void *opaque)
> +{
> +    libxlDriverPrivatePtr driver = opaque;
> +
> +    /* Drop the lock whle dispatching, for sake of re-entrancy */
> +    libxlDriverUnlock(driver);
> +    virDomainEventDispatchDefaultFunc(conn, event, cb, cbopaque, NULL);
> +    libxlDriverLock(driver);
> +}
> +
> +static void
> +libxlDomainEventFlush(int timer ATTRIBUTE_UNUSED, void *opaque)
> +{
> +    libxlDriverPrivatePtr driver = opaque;
> +    virDomainEventQueue tempQueue;
> +
> +    libxlDriverLock(driver);
> +
> +    driver->domainEventDispatching = 1;
> +
> +    /* Copy the queue, so we're reentrant safe */
> +    tempQueue.count = driver->domainEventQueue->count;
> +    tempQueue.events = driver->domainEventQueue->events;
> +    driver->domainEventQueue->count = 0;
> +    driver->domainEventQueue->events = NULL;
> +
> +    virEventUpdateTimeout(driver->domainEventTimer, -1);
> +    virDomainEventQueueDispatch(&tempQueue,
> +                                driver->domainEventCallbacks,
> +                                libxlDomainEventDispatchFunc,
> +                                driver);
> +
> +    /* Purge any deleted callbacks */
> +    virDomainEventCallbackListPurgeMarked(driver->domainEventCallbacks);
> +
> +    driver->domainEventDispatching = 0;
> +    libxlDriverUnlock(driver);
> +}
> +
> +/* driver must be locked before calling */
> +static void
> +libxlDomainEventQueue(libxlDriverPrivatePtr driver, virDomainEventPtr event)
> +{
> +    if (virDomainEventQueuePush(driver->domainEventQueue, event) < 0)
> +        virDomainEventFree(event);
> +    if (driver->domainEventQueue->count == 1)
> +        virEventUpdateTimeout(driver->domainEventTimer, 0);
> +}
> +
>  /*
>   * Remove reference to domain object.
>   */
> @@ -187,6 +239,7 @@ static void libxlEventHandler(int watch,
>      libxlDriverPrivatePtr driver = libxl_driver;
>      virDomainObjPtr vm = data;
>      libxlDomainObjPrivatePtr priv;
> +    virDomainEventPtr dom_event = NULL;
>      libxl_event event;
>      libxl_dominfo info;
>  
> @@ -225,6 +278,10 @@ static void libxlEventHandler(int watch,
>          switch (info.shutdown_reason) {
>              case SHUTDOWN_poweroff:
>              case SHUTDOWN_crash:
> +                if (info.shutdown_reason == SHUTDOWN_crash)
> +                    dom_event = virDomainEventNewFromObj(vm,
> +                                              VIR_DOMAIN_EVENT_STOPPED,
> +                                              VIR_DOMAIN_EVENT_STOPPED_CRASHED);
>                  libxlVmReap(driver, vm, 0);
>                  if (!vm->persistent) {
>                      virDomainRemoveInactive(&driver->domains, vm);
> @@ -244,6 +301,11 @@ static void libxlEventHandler(int watch,
>  cleanup:
>      if (vm)
>          virDomainObjUnlock(vm);
> +    if (dom_event) {
> +        libxlDriverLock(driver);
> +        libxlDomainEventQueue(driver, dom_event);
> +        libxlDriverUnlock(driver);
> +    }
>      libxl_free_event(&event);
>  }
>  
> @@ -303,6 +365,7 @@ libxlVmStart(libxlDriverPrivatePtr driver,
>  {
>      libxl_domain_config d_config;
>      virDomainDefPtr def = vm->def;
> +    virDomainEventPtr event = NULL;
>      int ret;
>      uint32_t domid = 0;
>      char *dom_xml = NULL;
> @@ -347,9 +410,14 @@ libxlVmStart(libxlDriverPrivatePtr driver,
>          vm->state = VIR_DOMAIN_PAUSED;
>      }
>  
> +
>   

But this one adds an unnecessary line :-).

>      if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0)
>          goto error;
>  
> +    event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_STARTED,
> +                                     VIR_DOMAIN_EVENT_STARTED_BOOTED);
> +    libxlDomainEventQueue(driver, event);
> +
>      libxl_domain_config_destroy(&d_config);
>      VIR_FREE(dom_xml);
>      return 0;
> @@ -447,6 +515,13 @@ libxlShutdown(void)
>      VIR_FREE(libxl_driver->libDir);
>      VIR_FREE(libxl_driver->saveDir);
>  
> +    /* Free domain callback list */
> +    virDomainEventCallbackListFree(libxl_driver->domainEventCallbacks);
> +    virDomainEventQueueFree(libxl_driver->domainEventQueue);
> +
> +    if (libxl_driver->domainEventTimer != -1)
> +        virEventRemoveTimeout(libxl_driver->domainEventTimer);
> +
>      libxlDriverUnlock(libxl_driver);
>      virMutexDestroy(&libxl_driver->lock);
>      VIR_FREE(libxl_driver);
> @@ -556,6 +631,16 @@ libxlStartup(int privileged) {
>      }
>      VIR_FREE(log_file);
>  
> +    /* Init callback list */
> +    if (VIR_ALLOC(libxl_driver->domainEventCallbacks) < 0)
> +        goto out_of_memory;
> +    if (!(libxl_driver->domainEventQueue = virDomainEventQueueNew()))
> +        goto out_of_memory;
> +    if ((libxl_driver->domainEventTimer =
> +         virEventAddTimeout(-1, libxlDomainEventFlush, libxl_driver, NULL)) < 0)
> +        goto error;
> +
> +
>   

Extra one here too.

>      libxl_driver->logger =
>              (xentoollog_logger *)xtl_createlogger_stdiostream(libxl_driver->logger_file, XTL_DEBUG,  0);
>      if (!libxl_driver->logger) {
> @@ -698,6 +783,11 @@ libxlOpen(virConnectPtr conn,
>  static int
>  libxlClose(virConnectPtr conn ATTRIBUTE_UNUSED)
>  {
> +    libxlDriverPrivatePtr driver = conn->privateData;
> +
> +    libxlDriverLock(driver);
> +    virDomainEventCallbackListRemoveConn(conn, driver->domainEventCallbacks);
> +    libxlDriverUnlock(driver);
>      conn->privateData = NULL;
>      return 0;
>  }
> @@ -1026,6 +1116,7 @@ libxlDomainDestroy(virDomainPtr dom)
>      virDomainObjPtr vm;
>      int ret = -1;
>      libxlDomainObjPrivatePtr priv;
> +    virDomainEventPtr event = NULL;
>  
>      libxlDriverLock(driver);
>      vm = virDomainFindByUUID(&driver->domains, dom->uuid);
> @@ -1043,6 +1134,9 @@ libxlDomainDestroy(virDomainPtr dom)
>          goto cleanup;
>      }
>  
> +    event = virDomainEventNewFromObj(vm,VIR_DOMAIN_EVENT_STOPPED,
> +                                     VIR_DOMAIN_EVENT_STOPPED_DESTROYED);
> +
>      priv = vm->privateData;
>      if (libxlVmReap(driver, vm, 1) != 0) {
>          libxlError(VIR_ERR_INTERNAL_ERROR,
> @@ -1060,6 +1154,8 @@ libxlDomainDestroy(virDomainPtr dom)
>  cleanup:
>      if (vm)
>          virDomainObjUnlock(vm);
> +    if (event)
> +        libxlDomainEventQueue(driver, event);
>      libxlDriverUnlock(driver);
>      return ret;
>  }
> @@ -1308,6 +1404,7 @@ libxlDomainDefineXML(virConnectPtr conn, const char *xml)
>      virDomainDefPtr def = NULL;
>      virDomainObjPtr vm = NULL;
>      virDomainPtr dom = NULL;
> +    virDomainEventPtr event = NULL;
>      int dupVM;
>  
>      libxlDriverLock(driver);
> @@ -1335,10 +1432,17 @@ libxlDomainDefineXML(virConnectPtr conn, const char *xml)
>      if (dom)
>          dom->id = vm->def->id;
>  
> +    event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_DEFINED,
> +                                     !dupVM ?
> +                                     VIR_DOMAIN_EVENT_DEFINED_ADDED :
> +                                     VIR_DOMAIN_EVENT_DEFINED_UPDATED);
> +
>  cleanup:
>      virDomainDefFree(def);
>      if (vm)
>          virDomainObjUnlock(vm);
> +    if (event)
> +        libxlDomainEventQueue(driver, event);
>      libxlDriverUnlock(driver);
>      return dom;
>  }
> @@ -1348,6 +1452,7 @@ libxlDomainUndefine(virDomainPtr dom)
>  {
>      libxlDriverPrivatePtr driver = dom->conn->privateData;
>      virDomainObjPtr vm;
> +    virDomainEventPtr event = NULL;
>      int ret = -1;
>  
>      libxlDriverLock(driver);
> @@ -1379,6 +1484,9 @@ libxlDomainUndefine(virDomainPtr dom)
>                                vm) < 0)
>          goto cleanup;
>  
> +    event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_UNDEFINED,
> +                                     VIR_DOMAIN_EVENT_UNDEFINED_REMOVED);
> +
>      virDomainRemoveInactive(&driver->domains, vm);
>      vm = NULL;
>      ret = 0;
> @@ -1386,6 +1494,8 @@ libxlDomainUndefine(virDomainPtr dom)
>    cleanup:
>      if (vm)
>          virDomainObjUnlock(vm);
> +    if (event)
> +        libxlDomainEventQueue(driver, event);
>      libxlDriverUnlock(driver);
>      return ret;
>  }
> @@ -1411,6 +1521,44 @@ libxlNodeGetFreeMemory(virConnectPtr conn)
>  }
>  
>  static int
> +libxlDomainEventRegister(virConnectPtr conn,
> +                         virConnectDomainEventCallback callback, void *opaque,
> +                         virFreeCallback freecb)
> +{
> +    libxlDriverPrivatePtr driver = conn->privateData;
> +    int ret;
> +
> +    libxlDriverLock(driver);
> +    ret = virDomainEventCallbackListAdd(conn, driver->domainEventCallbacks,
> +                                        callback, opaque, freecb);
> +    libxlDriverUnlock(driver);
> +
> +    return ret;
> +}
> +
> +
> +static int
> +libxlDomainEventDeregister(virConnectPtr conn,
> +                          virConnectDomainEventCallback callback)
> +{
> +    libxlDriverPrivatePtr driver = conn->privateData;
> +    int ret;
> +
> +    libxlDriverLock(driver);
> +    if (driver->domainEventDispatching)
> +        ret = virDomainEventCallbackListMarkDelete(conn,
> +                                                   driver->domainEventCallbacks,
> +                                                   callback);
> +    else
> +        ret = virDomainEventCallbackListRemove(conn,
> +                                               driver->domainEventCallbacks,
> +                                               callback);
> +    libxlDriverUnlock(driver);
> +
> +    return ret;
> +}
> +
> +static int
>  libxlDomainIsActive(virDomainPtr dom)
>  {
>      libxlDriverPrivatePtr driver = dom->conn->privateData;
> @@ -1454,6 +1602,44 @@ libxlDomainIsPersistent(virDomainPtr dom)
>      return ret;
>  }
>  
> +static int
> +libxlDomainEventRegisterAny(virConnectPtr conn, virDomainPtr dom, int eventID,
> +                            virConnectDomainEventGenericCallback callback,
> +                            void *opaque, virFreeCallback freecb)
> +{
> +    libxlDriverPrivatePtr driver = conn->privateData;
> +    int ret;
> +
> +    libxlDriverLock(driver);
> +    ret = virDomainEventCallbackListAddID(conn, driver->domainEventCallbacks,
> +                                          dom, eventID, callback, opaque,
> +                                          freecb);
> +    libxlDriverUnlock(driver);
> +
> +    return ret;
> +}
> +
> +
> +static int
> +libxlDomainEventDeregisterAny(virConnectPtr conn, int callbackID)
> +{
> +    libxlDriverPrivatePtr driver = conn->privateData;
> +    int ret;
> +
> +    libxlDriverLock(driver);
> +    if (driver->domainEventDispatching)
> +        ret = virDomainEventCallbackListMarkDeleteID(conn,
> +                                                     driver->domainEventCallbacks,
> +                                                     callbackID);
> +    else
> +        ret = virDomainEventCallbackListRemoveID(conn,
> +                                                 driver->domainEventCallbacks,
> +                                                 callbackID);
> +    libxlDriverUnlock(driver);
> +
> +    return ret;
> +}
> +
>  
>  static virDriver libxlDriver = {
>      VIR_DRV_LIBXL,
> @@ -1531,8 +1717,8 @@ static virDriver libxlDriver = {
>      NULL,                       /* domainGetBlockInfo */
>      NULL,                       /* nodeGetCellsFreeMemory */
>      libxlNodeGetFreeMemory,     /* getFreeMemory */
> -    NULL,                       /* domainEventRegister */
> -    NULL,                       /* domainEventDeregister */
> +    libxlDomainEventRegister,   /* domainEventRegister */
> +    libxlDomainEventDeregister, /* domainEventDeregister */
>      NULL,                       /* domainMigratePrepare2 */
>      NULL,                       /* domainMigrateFinish2 */
>      NULL,                       /* nodeDeviceDettach */
> @@ -1550,8 +1736,8 @@ static virDriver libxlDriver = {
>      NULL,                       /* domainAbortJob */
>      NULL,                       /* domainMigrateSetMaxDowntime */
>      NULL,                       /* domainMigrateSetMaxSpeed */
> -    NULL,                       /* domainEventRegisterAny */
> -    NULL,                       /* domainEventDeregisterAny */
> +    libxlDomainEventRegisterAny,/* domainEventRegisterAny */
> +    libxlDomainEventDeregisterAny,/* domainEventDeregisterAny */
>      NULL,                       /* domainManagedSave */
>      NULL,                       /* domainHasManagedSaveImage */
>      NULL,                       /* domainManagedSaveRemove */
>   

Other than minor whitespace nits, ACK.




More information about the libvir-list mailing list