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