mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-24 22:55:23 +00:00
Add event callbacks to libxl driver
* src/libxl/libxl_conf.h: add the necessary fields to the driver private structure * src/libxl/libxl_driver.c: add lifecycle event support and entry points for event(de)register(any)
This commit is contained in:
parent
6d60ca5d58
commit
68e1032378
@ -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);
|
||||
|
||||
|
||||
#endif /* LIBXL_CONF_H */
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
@ -1410,6 +1520,44 @@ libxlNodeGetFreeMemory(virConnectPtr conn)
|
||||
return phy_info.free_pages * ver_info->pagesize;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user