mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-26 15:45:28 +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 "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 {
|
|||||||
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
|
|||||||
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)
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
{
|
{
|
||||||
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,
|
|||||||
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)
|
|||||||
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) {
|
|||||||
}
|
}
|
||||||
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,
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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 = {
|
|||||||
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 = {
|
|||||||
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 */
|
||||||
|
Loading…
Reference in New Issue
Block a user