提交 68e10323 编写于 作者: M Markus Groß 提交者: Daniel Veillard

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)
上级 6d60ca5d
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
# include "internal.h" # include "internal.h"
# include "domain_conf.h" # include "domain_conf.h"
# include "domain_event.h"
# include "capabilities.h" # include "capabilities.h"
# include "configmake.h" # include "configmake.h"
# include "bitmap.h" # include "bitmap.h"
...@@ -57,6 +58,12 @@ struct _libxlDriverPrivate { ...@@ -57,6 +58,12 @@ struct _libxlDriverPrivate {
virBitmapPtr reservedVNCPorts; virBitmapPtr reservedVNCPorts;
virDomainObjList domains; virDomainObjList domains;
/* A list of callbacks */
virDomainEventCallbackListPtr domainEventCallbacks;
virDomainEventQueuePtr domainEventQueue;
int domainEventTimer;
int domainEventDispatching;
char *configDir; char *configDir;
char *autostartDir; char *autostartDir;
char *logDir; char *logDir;
...@@ -87,5 +94,4 @@ int ...@@ -87,5 +94,4 @@ int
libxlBuildDomainConfig(libxlDriverPrivatePtr driver, libxlBuildDomainConfig(libxlDriverPrivatePtr driver,
virDomainDefPtr def, libxl_domain_config *d_config); virDomainDefPtr def, libxl_domain_config *d_config);
#endif /* LIBXL_CONF_H */ #endif /* LIBXL_CONF_H */
...@@ -99,6 +99,58 @@ libxlDomainObjPrivateFree(void *data) ...@@ -99,6 +99,58 @@ libxlDomainObjPrivateFree(void *data)
VIR_FREE(priv); 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. * Remove reference to domain object.
*/ */
...@@ -187,6 +239,7 @@ static void libxlEventHandler(int watch, ...@@ -187,6 +239,7 @@ static void libxlEventHandler(int watch,
libxlDriverPrivatePtr driver = libxl_driver; libxlDriverPrivatePtr driver = libxl_driver;
virDomainObjPtr vm = data; virDomainObjPtr vm = data;
libxlDomainObjPrivatePtr priv; libxlDomainObjPrivatePtr priv;
virDomainEventPtr dom_event = NULL;
libxl_event event; libxl_event event;
libxl_dominfo info; libxl_dominfo info;
...@@ -225,6 +278,10 @@ static void libxlEventHandler(int watch, ...@@ -225,6 +278,10 @@ static void libxlEventHandler(int watch,
switch (info.shutdown_reason) { switch (info.shutdown_reason) {
case SHUTDOWN_poweroff: case SHUTDOWN_poweroff:
case SHUTDOWN_crash: 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); libxlVmReap(driver, vm, 0);
if (!vm->persistent) { if (!vm->persistent) {
virDomainRemoveInactive(&driver->domains, vm); virDomainRemoveInactive(&driver->domains, vm);
...@@ -244,6 +301,11 @@ static void libxlEventHandler(int watch, ...@@ -244,6 +301,11 @@ static void libxlEventHandler(int watch,
cleanup: cleanup:
if (vm) if (vm)
virDomainObjUnlock(vm); virDomainObjUnlock(vm);
if (dom_event) {
libxlDriverLock(driver);
libxlDomainEventQueue(driver, dom_event);
libxlDriverUnlock(driver);
}
libxl_free_event(&event); libxl_free_event(&event);
} }
...@@ -303,6 +365,7 @@ libxlVmStart(libxlDriverPrivatePtr driver, ...@@ -303,6 +365,7 @@ libxlVmStart(libxlDriverPrivatePtr driver,
{ {
libxl_domain_config d_config; libxl_domain_config d_config;
virDomainDefPtr def = vm->def; virDomainDefPtr def = vm->def;
virDomainEventPtr event = NULL;
int ret; int ret;
uint32_t domid = 0; uint32_t domid = 0;
char *dom_xml = NULL; char *dom_xml = NULL;
...@@ -347,9 +410,14 @@ libxlVmStart(libxlDriverPrivatePtr driver, ...@@ -347,9 +410,14 @@ libxlVmStart(libxlDriverPrivatePtr driver,
vm->state = VIR_DOMAIN_PAUSED; vm->state = VIR_DOMAIN_PAUSED;
} }
if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0) if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0)
goto error; goto error;
event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_STARTED,
VIR_DOMAIN_EVENT_STARTED_BOOTED);
libxlDomainEventQueue(driver, event);
libxl_domain_config_destroy(&d_config); libxl_domain_config_destroy(&d_config);
VIR_FREE(dom_xml); VIR_FREE(dom_xml);
return 0; return 0;
...@@ -447,6 +515,13 @@ libxlShutdown(void) ...@@ -447,6 +515,13 @@ libxlShutdown(void)
VIR_FREE(libxl_driver->libDir); VIR_FREE(libxl_driver->libDir);
VIR_FREE(libxl_driver->saveDir); 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); libxlDriverUnlock(libxl_driver);
virMutexDestroy(&libxl_driver->lock); virMutexDestroy(&libxl_driver->lock);
VIR_FREE(libxl_driver); VIR_FREE(libxl_driver);
...@@ -556,6 +631,16 @@ libxlStartup(int privileged) { ...@@ -556,6 +631,16 @@ libxlStartup(int privileged) {
} }
VIR_FREE(log_file); 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 = libxl_driver->logger =
(xentoollog_logger *)xtl_createlogger_stdiostream(libxl_driver->logger_file, XTL_DEBUG, 0); (xentoollog_logger *)xtl_createlogger_stdiostream(libxl_driver->logger_file, XTL_DEBUG, 0);
if (!libxl_driver->logger) { if (!libxl_driver->logger) {
...@@ -698,6 +783,11 @@ libxlOpen(virConnectPtr conn, ...@@ -698,6 +783,11 @@ libxlOpen(virConnectPtr conn,
static int static int
libxlClose(virConnectPtr conn ATTRIBUTE_UNUSED) libxlClose(virConnectPtr conn ATTRIBUTE_UNUSED)
{ {
libxlDriverPrivatePtr driver = conn->privateData;
libxlDriverLock(driver);
virDomainEventCallbackListRemoveConn(conn, driver->domainEventCallbacks);
libxlDriverUnlock(driver);
conn->privateData = NULL; conn->privateData = NULL;
return 0; return 0;
} }
...@@ -1026,6 +1116,7 @@ libxlDomainDestroy(virDomainPtr dom) ...@@ -1026,6 +1116,7 @@ libxlDomainDestroy(virDomainPtr dom)
virDomainObjPtr vm; virDomainObjPtr vm;
int ret = -1; int ret = -1;
libxlDomainObjPrivatePtr priv; libxlDomainObjPrivatePtr priv;
virDomainEventPtr event = NULL;
libxlDriverLock(driver); libxlDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid); vm = virDomainFindByUUID(&driver->domains, dom->uuid);
...@@ -1043,6 +1134,9 @@ libxlDomainDestroy(virDomainPtr dom) ...@@ -1043,6 +1134,9 @@ libxlDomainDestroy(virDomainPtr dom)
goto cleanup; goto cleanup;
} }
event = virDomainEventNewFromObj(vm,VIR_DOMAIN_EVENT_STOPPED,
VIR_DOMAIN_EVENT_STOPPED_DESTROYED);
priv = vm->privateData; priv = vm->privateData;
if (libxlVmReap(driver, vm, 1) != 0) { if (libxlVmReap(driver, vm, 1) != 0) {
libxlError(VIR_ERR_INTERNAL_ERROR, libxlError(VIR_ERR_INTERNAL_ERROR,
...@@ -1060,6 +1154,8 @@ libxlDomainDestroy(virDomainPtr dom) ...@@ -1060,6 +1154,8 @@ libxlDomainDestroy(virDomainPtr dom)
cleanup: cleanup:
if (vm) if (vm)
virDomainObjUnlock(vm); virDomainObjUnlock(vm);
if (event)
libxlDomainEventQueue(driver, event);
libxlDriverUnlock(driver); libxlDriverUnlock(driver);
return ret; return ret;
} }
...@@ -1308,6 +1404,7 @@ libxlDomainDefineXML(virConnectPtr conn, const char *xml) ...@@ -1308,6 +1404,7 @@ libxlDomainDefineXML(virConnectPtr conn, const char *xml)
virDomainDefPtr def = NULL; virDomainDefPtr def = NULL;
virDomainObjPtr vm = NULL; virDomainObjPtr vm = NULL;
virDomainPtr dom = NULL; virDomainPtr dom = NULL;
virDomainEventPtr event = NULL;
int dupVM; int dupVM;
libxlDriverLock(driver); libxlDriverLock(driver);
...@@ -1335,10 +1432,17 @@ libxlDomainDefineXML(virConnectPtr conn, const char *xml) ...@@ -1335,10 +1432,17 @@ libxlDomainDefineXML(virConnectPtr conn, const char *xml)
if (dom) if (dom)
dom->id = vm->def->id; dom->id = vm->def->id;
event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_DEFINED,
!dupVM ?
VIR_DOMAIN_EVENT_DEFINED_ADDED :
VIR_DOMAIN_EVENT_DEFINED_UPDATED);
cleanup: cleanup:
virDomainDefFree(def); virDomainDefFree(def);
if (vm) if (vm)
virDomainObjUnlock(vm); virDomainObjUnlock(vm);
if (event)
libxlDomainEventQueue(driver, event);
libxlDriverUnlock(driver); libxlDriverUnlock(driver);
return dom; return dom;
} }
...@@ -1348,6 +1452,7 @@ libxlDomainUndefine(virDomainPtr dom) ...@@ -1348,6 +1452,7 @@ libxlDomainUndefine(virDomainPtr dom)
{ {
libxlDriverPrivatePtr driver = dom->conn->privateData; libxlDriverPrivatePtr driver = dom->conn->privateData;
virDomainObjPtr vm; virDomainObjPtr vm;
virDomainEventPtr event = NULL;
int ret = -1; int ret = -1;
libxlDriverLock(driver); libxlDriverLock(driver);
...@@ -1379,6 +1484,9 @@ libxlDomainUndefine(virDomainPtr dom) ...@@ -1379,6 +1484,9 @@ libxlDomainUndefine(virDomainPtr dom)
vm) < 0) vm) < 0)
goto cleanup; goto cleanup;
event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_UNDEFINED,
VIR_DOMAIN_EVENT_UNDEFINED_REMOVED);
virDomainRemoveInactive(&driver->domains, vm); virDomainRemoveInactive(&driver->domains, vm);
vm = NULL; vm = NULL;
ret = 0; ret = 0;
...@@ -1386,6 +1494,8 @@ libxlDomainUndefine(virDomainPtr dom) ...@@ -1386,6 +1494,8 @@ libxlDomainUndefine(virDomainPtr dom)
cleanup: cleanup:
if (vm) if (vm)
virDomainObjUnlock(vm); virDomainObjUnlock(vm);
if (event)
libxlDomainEventQueue(driver, event);
libxlDriverUnlock(driver); libxlDriverUnlock(driver);
return ret; return ret;
} }
...@@ -1410,6 +1520,44 @@ libxlNodeGetFreeMemory(virConnectPtr conn) ...@@ -1410,6 +1520,44 @@ libxlNodeGetFreeMemory(virConnectPtr conn)
return phy_info.free_pages * ver_info->pagesize; 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 static int
libxlDomainIsActive(virDomainPtr dom) libxlDomainIsActive(virDomainPtr dom)
{ {
...@@ -1454,6 +1602,44 @@ libxlDomainIsPersistent(virDomainPtr dom) ...@@ -1454,6 +1602,44 @@ libxlDomainIsPersistent(virDomainPtr dom)
return ret; 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 = { static virDriver libxlDriver = {
VIR_DRV_LIBXL, VIR_DRV_LIBXL,
...@@ -1531,8 +1717,8 @@ static virDriver libxlDriver = { ...@@ -1531,8 +1717,8 @@ static virDriver libxlDriver = {
NULL, /* domainGetBlockInfo */ NULL, /* domainGetBlockInfo */
NULL, /* nodeGetCellsFreeMemory */ NULL, /* nodeGetCellsFreeMemory */
libxlNodeGetFreeMemory, /* getFreeMemory */ libxlNodeGetFreeMemory, /* getFreeMemory */
NULL, /* domainEventRegister */ libxlDomainEventRegister, /* domainEventRegister */
NULL, /* domainEventDeregister */ libxlDomainEventDeregister, /* domainEventDeregister */
NULL, /* domainMigratePrepare2 */ NULL, /* domainMigratePrepare2 */
NULL, /* domainMigrateFinish2 */ NULL, /* domainMigrateFinish2 */
NULL, /* nodeDeviceDettach */ NULL, /* nodeDeviceDettach */
...@@ -1550,8 +1736,8 @@ static virDriver libxlDriver = { ...@@ -1550,8 +1736,8 @@ static virDriver libxlDriver = {
NULL, /* domainAbortJob */ NULL, /* domainAbortJob */
NULL, /* domainMigrateSetMaxDowntime */ NULL, /* domainMigrateSetMaxDowntime */
NULL, /* domainMigrateSetMaxSpeed */ NULL, /* domainMigrateSetMaxSpeed */
NULL, /* domainEventRegisterAny */ libxlDomainEventRegisterAny,/* domainEventRegisterAny */
NULL, /* domainEventDeregisterAny */ libxlDomainEventDeregisterAny,/* domainEventDeregisterAny */
NULL, /* domainManagedSave */ NULL, /* domainManagedSave */
NULL, /* domainHasManagedSaveImage */ NULL, /* domainHasManagedSaveImage */
NULL, /* domainManagedSaveRemove */ NULL, /* domainManagedSaveRemove */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册