mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-11 07:17:44 +00:00
Convert Xen & VBox drivers to use virDomainEventState
The Xen & VBox drivers deal with callbacks & dispatching of events directly. All the other drivers use a timer to dispatch events from a clean stack state, rather than deep inside the drivers. Convert Xen & VBox over to virDomainEventState so that they match behaviour of other drivers * src/conf/domain_event.c: Return count of remaining callbacks when unregistering event callback * src/vbox/vbox_tmpl.c, src/xen/xen_driver.c, src/xen/xen_driver.h: Convert to virDomainEventState
This commit is contained in:
parent
b4d579de1e
commit
a86bbc6003
@ -133,6 +133,7 @@ virDomainEventCallbackListRemove(virConnectPtr conn,
|
|||||||
virDomainEventCallbackListPtr cbList,
|
virDomainEventCallbackListPtr cbList,
|
||||||
virConnectDomainEventCallback callback)
|
virConnectDomainEventCallback callback)
|
||||||
{
|
{
|
||||||
|
int ret = 0;
|
||||||
int i;
|
int i;
|
||||||
for (i = 0 ; i < cbList->count ; i++) {
|
for (i = 0 ; i < cbList->count ; i++) {
|
||||||
if (cbList->callbacks[i]->cb == VIR_DOMAIN_EVENT_CALLBACK(callback) &&
|
if (cbList->callbacks[i]->cb == VIR_DOMAIN_EVENT_CALLBACK(callback) &&
|
||||||
@ -156,7 +157,11 @@ virDomainEventCallbackListRemove(virConnectPtr conn,
|
|||||||
}
|
}
|
||||||
cbList->count--;
|
cbList->count--;
|
||||||
|
|
||||||
return 0;
|
for (i = 0 ; i < cbList->count ; i++) {
|
||||||
|
if (!cbList->callbacks[i]->deleted)
|
||||||
|
ret++;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,6 +184,7 @@ virDomainEventCallbackListRemoveID(virConnectPtr conn,
|
|||||||
virDomainEventCallbackListPtr cbList,
|
virDomainEventCallbackListPtr cbList,
|
||||||
int callbackID)
|
int callbackID)
|
||||||
{
|
{
|
||||||
|
int ret = 0;
|
||||||
int i;
|
int i;
|
||||||
for (i = 0 ; i < cbList->count ; i++) {
|
for (i = 0 ; i < cbList->count ; i++) {
|
||||||
if (cbList->callbacks[i]->callbackID == callbackID &&
|
if (cbList->callbacks[i]->callbackID == callbackID &&
|
||||||
@ -201,7 +207,11 @@ virDomainEventCallbackListRemoveID(virConnectPtr conn,
|
|||||||
}
|
}
|
||||||
cbList->count--;
|
cbList->count--;
|
||||||
|
|
||||||
return 0;
|
for (i = 0 ; i < cbList->count ; i++) {
|
||||||
|
if (!cbList->callbacks[i]->deleted)
|
||||||
|
ret++;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,13 +264,18 @@ int virDomainEventCallbackListMarkDelete(virConnectPtr conn,
|
|||||||
virDomainEventCallbackListPtr cbList,
|
virDomainEventCallbackListPtr cbList,
|
||||||
virConnectDomainEventCallback callback)
|
virConnectDomainEventCallback callback)
|
||||||
{
|
{
|
||||||
|
int ret = 0;
|
||||||
int i;
|
int i;
|
||||||
for (i = 0 ; i < cbList->count ; i++) {
|
for (i = 0 ; i < cbList->count ; i++) {
|
||||||
if (cbList->callbacks[i]->cb == VIR_DOMAIN_EVENT_CALLBACK(callback) &&
|
if (cbList->callbacks[i]->cb == VIR_DOMAIN_EVENT_CALLBACK(callback) &&
|
||||||
cbList->callbacks[i]->eventID == VIR_DOMAIN_EVENT_ID_LIFECYCLE &&
|
cbList->callbacks[i]->eventID == VIR_DOMAIN_EVENT_ID_LIFECYCLE &&
|
||||||
cbList->callbacks[i]->conn == conn) {
|
cbList->callbacks[i]->conn == conn) {
|
||||||
cbList->callbacks[i]->deleted = 1;
|
cbList->callbacks[i]->deleted = 1;
|
||||||
return 0;
|
for (i = 0 ; i < cbList->count ; i++) {
|
||||||
|
if (!cbList->callbacks[i]->deleted)
|
||||||
|
ret++;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -274,12 +289,17 @@ int virDomainEventCallbackListMarkDeleteID(virConnectPtr conn,
|
|||||||
virDomainEventCallbackListPtr cbList,
|
virDomainEventCallbackListPtr cbList,
|
||||||
int callbackID)
|
int callbackID)
|
||||||
{
|
{
|
||||||
|
int ret = 0;
|
||||||
int i;
|
int i;
|
||||||
for (i = 0 ; i < cbList->count ; i++) {
|
for (i = 0 ; i < cbList->count ; i++) {
|
||||||
if (cbList->callbacks[i]->callbackID == callbackID &&
|
if (cbList->callbacks[i]->callbackID == callbackID &&
|
||||||
cbList->callbacks[i]->conn == conn) {
|
cbList->callbacks[i]->conn == conn) {
|
||||||
cbList->callbacks[i]->deleted = 1;
|
cbList->callbacks[i]->deleted = 1;
|
||||||
return 0;
|
for (i = 0 ; i < cbList->count ; i++) {
|
||||||
|
if (!cbList->callbacks[i]->deleted)
|
||||||
|
ret++;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1307,6 +1327,18 @@ virDomainEventStateFlush(virDomainEventStatePtr state,
|
|||||||
virDomainEventStateUnlock(state);
|
virDomainEventStateUnlock(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virDomainEventStateDeregister:
|
||||||
|
* @state: domain event state
|
||||||
|
* @conn: connection to associate with callback
|
||||||
|
* @callback: function to remove from event
|
||||||
|
*
|
||||||
|
* Unregister the function @callback with connection @conn,
|
||||||
|
* from @state, for lifecycle events.
|
||||||
|
*
|
||||||
|
* Returns: the number of lifecycle callbacks still registered, or -1 on error
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
virDomainEventStateDeregister(virConnectPtr conn,
|
virDomainEventStateDeregister(virConnectPtr conn,
|
||||||
virDomainEventStatePtr state,
|
virDomainEventStatePtr state,
|
||||||
@ -1324,6 +1356,18 @@ virDomainEventStateDeregister(virConnectPtr conn,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virDomainEventStateDeregisterAny:
|
||||||
|
* @state: domain event state
|
||||||
|
* @conn: connection to associate with callback
|
||||||
|
* @callbackID: ID of the function to remove from event
|
||||||
|
*
|
||||||
|
* Unregister the function @callbackID with connection @conn,
|
||||||
|
* from @state, for lifecycle events.
|
||||||
|
*
|
||||||
|
* Returns: the number of lifecycle callbacks still registered, or -1 on error
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
virDomainEventStateDeregisterAny(virConnectPtr conn,
|
virDomainEventStateDeregisterAny(virConnectPtr conn,
|
||||||
virDomainEventStatePtr state,
|
virDomainEventStatePtr state,
|
||||||
|
@ -188,11 +188,9 @@ typedef struct {
|
|||||||
|
|
||||||
#else /* !(VBOX_API_VERSION == 2002) */
|
#else /* !(VBOX_API_VERSION == 2002) */
|
||||||
|
|
||||||
/* An array of callbacks */
|
/* Async event handling */
|
||||||
virDomainEventCallbackListPtr domainEventCallbacks;
|
virDomainEventStatePtr domainEvents;
|
||||||
|
|
||||||
int fdWatch;
|
int fdWatch;
|
||||||
int domainEventDispatching;
|
|
||||||
|
|
||||||
# if VBOX_API_VERSION <= 3002
|
# if VBOX_API_VERSION <= 3002
|
||||||
/* IVirtualBoxCallback is used in VirtualBox 3.x only */
|
/* IVirtualBoxCallback is used in VirtualBox 3.x only */
|
||||||
@ -966,11 +964,52 @@ static void vboxUninitialize(vboxGlobalData *data) {
|
|||||||
#if VBOX_API_VERSION == 2002
|
#if VBOX_API_VERSION == 2002
|
||||||
/* No domainEventCallbacks in 2.2.* version */
|
/* No domainEventCallbacks in 2.2.* version */
|
||||||
#else /* !(VBOX_API_VERSION == 2002) */
|
#else /* !(VBOX_API_VERSION == 2002) */
|
||||||
VIR_FREE(data->domainEventCallbacks);
|
virDomainEventStateFree(data->domainEvents);
|
||||||
#endif /* !(VBOX_API_VERSION == 2002) */
|
#endif /* !(VBOX_API_VERSION == 2002) */
|
||||||
VIR_FREE(data);
|
VIR_FREE(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if VBOX_API_VERSION == 2002
|
||||||
|
/* No domainEventCallbacks in 2.2.* version */
|
||||||
|
#else /* !(VBOX_API_VERSION == 2002) */
|
||||||
|
|
||||||
|
static void
|
||||||
|
vboxDomainEventDispatchFunc(virConnectPtr conn,
|
||||||
|
virDomainEventPtr event,
|
||||||
|
virConnectDomainEventGenericCallback cb,
|
||||||
|
void *cbopaque,
|
||||||
|
void *opaque)
|
||||||
|
{
|
||||||
|
vboxGlobalData *data = opaque;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Release the lock while the callback is running so that
|
||||||
|
* we're re-entrant safe for callback work - the callback
|
||||||
|
* may want to invoke other virt functions & we have already
|
||||||
|
* protected the one piece of state we have - the callback
|
||||||
|
* list
|
||||||
|
*/
|
||||||
|
vboxDriverUnlock(data);
|
||||||
|
virDomainEventDispatchDefaultFunc(conn, event, cb, cbopaque, NULL);
|
||||||
|
vboxDriverLock(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void vboxDomainEventFlush(int timer ATTRIBUTE_UNUSED, void *opaque)
|
||||||
|
{
|
||||||
|
virConnectPtr conn = opaque;
|
||||||
|
vboxGlobalData *data = conn->privateData;
|
||||||
|
|
||||||
|
vboxDriverLock(data);
|
||||||
|
virDomainEventStateFlush(data->domainEvents,
|
||||||
|
vboxDomainEventDispatchFunc,
|
||||||
|
data);
|
||||||
|
vboxDriverUnlock(data);
|
||||||
|
}
|
||||||
|
#endif /* !(VBOX_API_VERSION == 2002) */
|
||||||
|
|
||||||
|
|
||||||
static virDrvOpenStatus vboxOpen(virConnectPtr conn,
|
static virDrvOpenStatus vboxOpen(virConnectPtr conn,
|
||||||
virConnectAuthPtr auth ATTRIBUTE_UNUSED,
|
virConnectAuthPtr auth ATTRIBUTE_UNUSED,
|
||||||
unsigned int flags)
|
unsigned int flags)
|
||||||
@ -1035,8 +1074,11 @@ static virDrvOpenStatus vboxOpen(virConnectPtr conn,
|
|||||||
|
|
||||||
#else /* !(VBOX_API_VERSION == 2002) */
|
#else /* !(VBOX_API_VERSION == 2002) */
|
||||||
|
|
||||||
if (VIR_ALLOC(data->domainEventCallbacks) < 0) {
|
if (!(data->domainEvents = virDomainEventStateNew(vboxDomainEventFlush,
|
||||||
virReportOOMError();
|
data,
|
||||||
|
NULL,
|
||||||
|
true))) {
|
||||||
|
vboxUninitialize(data);
|
||||||
return VIR_DRV_OPEN_ERROR;
|
return VIR_DRV_OPEN_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6770,7 +6812,6 @@ vboxCallbackOnMachineStateChange(IVirtualBoxCallback *pThis ATTRIBUTE_UNUSED,
|
|||||||
int event = 0;
|
int event = 0;
|
||||||
int detail = 0;
|
int detail = 0;
|
||||||
|
|
||||||
g_pVBoxGlobalData->domainEventDispatching = 1;
|
|
||||||
vboxDriverLock(g_pVBoxGlobalData);
|
vboxDriverLock(g_pVBoxGlobalData);
|
||||||
|
|
||||||
VIR_DEBUG("IVirtualBoxCallback: %p, State: %d", pThis, state);
|
VIR_DEBUG("IVirtualBoxCallback: %p, State: %d", pThis, state);
|
||||||
@ -6818,20 +6859,12 @@ vboxCallbackOnMachineStateChange(IVirtualBoxCallback *pThis ATTRIBUTE_UNUSED,
|
|||||||
|
|
||||||
ev = virDomainEventNewFromDom(dom, event, detail);
|
ev = virDomainEventNewFromDom(dom, event, detail);
|
||||||
|
|
||||||
if (ev) {
|
if (ev)
|
||||||
virDomainEventDispatch(ev,
|
virDomainEventStateQueue(g_pVBoxGlobalData->domainEvents, ev);
|
||||||
g_pVBoxGlobalData->domainEventCallbacks,
|
|
||||||
virDomainEventDispatchDefaultFunc,
|
|
||||||
NULL);
|
|
||||||
virDomainEventFree(ev);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virDomainEventCallbackListPurgeMarked(g_pVBoxGlobalData->domainEventCallbacks);
|
|
||||||
|
|
||||||
vboxDriverUnlock(g_pVBoxGlobalData);
|
vboxDriverUnlock(g_pVBoxGlobalData);
|
||||||
g_pVBoxGlobalData->domainEventDispatching = 0;
|
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
@ -6898,7 +6931,6 @@ vboxCallbackOnMachineRegistered(IVirtualBoxCallback *pThis ATTRIBUTE_UNUSED,
|
|||||||
int event = 0;
|
int event = 0;
|
||||||
int detail = 0;
|
int detail = 0;
|
||||||
|
|
||||||
g_pVBoxGlobalData->domainEventDispatching = 1;
|
|
||||||
vboxDriverLock(g_pVBoxGlobalData);
|
vboxDriverLock(g_pVBoxGlobalData);
|
||||||
|
|
||||||
VIR_DEBUG("IVirtualBoxCallback: %p, registered: %s", pThis, registered ? "true" : "false");
|
VIR_DEBUG("IVirtualBoxCallback: %p, registered: %s", pThis, registered ? "true" : "false");
|
||||||
@ -6931,20 +6963,12 @@ vboxCallbackOnMachineRegistered(IVirtualBoxCallback *pThis ATTRIBUTE_UNUSED,
|
|||||||
|
|
||||||
ev = virDomainEventNewFromDom(dom, event, detail);
|
ev = virDomainEventNewFromDom(dom, event, detail);
|
||||||
|
|
||||||
if (ev) {
|
if (ev)
|
||||||
virDomainEventDispatch(ev,
|
virDomainEventStateQueue(g_pVBoxGlobalData->domainEvents, ev);
|
||||||
g_pVBoxGlobalData->domainEventCallbacks,
|
|
||||||
virDomainEventDispatchDefaultFunc,
|
|
||||||
NULL);
|
|
||||||
virDomainEventFree(ev);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virDomainEventCallbackListPurgeMarked(g_pVBoxGlobalData->domainEventCallbacks);
|
|
||||||
|
|
||||||
vboxDriverUnlock(g_pVBoxGlobalData);
|
vboxDriverUnlock(g_pVBoxGlobalData);
|
||||||
g_pVBoxGlobalData->domainEventDispatching = 0;
|
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
@ -7164,11 +7188,11 @@ static int vboxDomainEventRegister (virConnectPtr conn,
|
|||||||
* later you can iterate over them
|
* later you can iterate over them
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ret = virDomainEventCallbackListAdd(conn, data->domainEventCallbacks,
|
ret = virDomainEventCallbackListAdd(conn, data->domainEvents->callbacks,
|
||||||
callback, opaque, freecb);
|
callback, opaque, freecb);
|
||||||
VIR_DEBUG("virDomainEventCallbackListAdd (ret = %d) ( conn: %p, "
|
VIR_DEBUG("virDomainEventCallbackListAdd (ret = %d) ( conn: %p, "
|
||||||
"data->domainEventCallbacks: %p, callback: %p, opaque: %p, "
|
"data->domainEvents->callbacks: %p, callback: %p, opaque: %p, "
|
||||||
"freecb: %p )", ret, conn, data->domainEventCallbacks, callback,
|
"freecb: %p )", ret, conn, data->domainEvents->callbacks, callback,
|
||||||
opaque, freecb);
|
opaque, freecb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -7188,31 +7212,23 @@ static int vboxDomainEventRegister (virConnectPtr conn,
|
|||||||
static int vboxDomainEventDeregister (virConnectPtr conn,
|
static int vboxDomainEventDeregister (virConnectPtr conn,
|
||||||
virConnectDomainEventCallback callback) {
|
virConnectDomainEventCallback callback) {
|
||||||
VBOX_OBJECT_CHECK(conn, int, -1);
|
VBOX_OBJECT_CHECK(conn, int, -1);
|
||||||
|
int cnt;
|
||||||
|
|
||||||
/* Locking has to be there as callbacks are not
|
/* Locking has to be there as callbacks are not
|
||||||
* really fully thread safe
|
* really fully thread safe
|
||||||
*/
|
*/
|
||||||
vboxDriverLock(data);
|
vboxDriverLock(data);
|
||||||
|
|
||||||
if (data->domainEventDispatching)
|
cnt = virDomainEventStateDeregister(conn, data->domainEvents,
|
||||||
ret = virDomainEventCallbackListMarkDelete(conn, data->domainEventCallbacks,
|
callback);
|
||||||
callback);
|
|
||||||
else
|
|
||||||
ret = virDomainEventCallbackListRemove(conn, data->domainEventCallbacks,
|
|
||||||
callback);
|
|
||||||
|
|
||||||
if (data->vboxCallback) {
|
if (data->vboxCallback && cnt == 0) {
|
||||||
/* check count here of how many times register was called
|
data->vboxObj->vtbl->UnregisterCallback(data->vboxObj, data->vboxCallback);
|
||||||
* and only on the last de-register do the un-register call
|
VBOX_RELEASE(data->vboxCallback);
|
||||||
*/
|
|
||||||
if (data->domainEventCallbacks && virDomainEventCallbackListCount(data->domainEventCallbacks) == 0) {
|
|
||||||
data->vboxObj->vtbl->UnregisterCallback(data->vboxObj, data->vboxCallback);
|
|
||||||
VBOX_RELEASE(data->vboxCallback);
|
|
||||||
|
|
||||||
/* Remove the Event file handle on which we are listening as well */
|
/* Remove the Event file handle on which we are listening as well */
|
||||||
virEventRemoveHandle(data->fdWatch);
|
virEventRemoveHandle(data->fdWatch);
|
||||||
data->fdWatch = -1;
|
data->fdWatch = -1;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vboxDriverUnlock(data);
|
vboxDriverUnlock(data);
|
||||||
@ -7264,12 +7280,12 @@ static int vboxDomainEventRegisterAny(virConnectPtr conn,
|
|||||||
* later you can iterate over them
|
* later you can iterate over them
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ret = virDomainEventCallbackListAddID(conn, data->domainEventCallbacks,
|
ret = virDomainEventCallbackListAddID(conn, data->domainEvents->callbacks,
|
||||||
dom, eventID,
|
dom, eventID,
|
||||||
callback, opaque, freecb);
|
callback, opaque, freecb);
|
||||||
VIR_DEBUG("virDomainEventCallbackListAddID (ret = %d) ( conn: %p, "
|
VIR_DEBUG("virDomainEventCallbackListAddID (ret = %d) ( conn: %p, "
|
||||||
"data->domainEventCallbacks: %p, callback: %p, opaque: %p, "
|
"data->domainEvents->callbacks: %p, callback: %p, opaque: %p, "
|
||||||
"freecb: %p )", ret, conn, data->domainEventCallbacks, callback,
|
"freecb: %p )", ret, conn, data->domainEvents->callbacks, callback,
|
||||||
opaque, freecb);
|
opaque, freecb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -7289,31 +7305,23 @@ static int vboxDomainEventRegisterAny(virConnectPtr conn,
|
|||||||
static int vboxDomainEventDeregisterAny(virConnectPtr conn,
|
static int vboxDomainEventDeregisterAny(virConnectPtr conn,
|
||||||
int callbackID) {
|
int callbackID) {
|
||||||
VBOX_OBJECT_CHECK(conn, int, -1);
|
VBOX_OBJECT_CHECK(conn, int, -1);
|
||||||
|
int cnt;
|
||||||
|
|
||||||
/* Locking has to be there as callbacks are not
|
/* Locking has to be there as callbacks are not
|
||||||
* really fully thread safe
|
* really fully thread safe
|
||||||
*/
|
*/
|
||||||
vboxDriverLock(data);
|
vboxDriverLock(data);
|
||||||
|
|
||||||
if (data->domainEventDispatching)
|
cnt = virDomainEventStateDeregisterAny(conn, data->domainEvents,
|
||||||
ret = virDomainEventCallbackListMarkDeleteID(conn, data->domainEventCallbacks,
|
callbackID);
|
||||||
callbackID);
|
|
||||||
else
|
|
||||||
ret = virDomainEventCallbackListRemoveID(conn, data->domainEventCallbacks,
|
|
||||||
callbackID);
|
|
||||||
|
|
||||||
if (data->vboxCallback) {
|
if (data->vboxCallback && cnt == 0) {
|
||||||
/* check count here of how many times register was called
|
data->vboxObj->vtbl->UnregisterCallback(data->vboxObj, data->vboxCallback);
|
||||||
* and only on the last de-register do the un-register call
|
VBOX_RELEASE(data->vboxCallback);
|
||||||
*/
|
|
||||||
if (data->domainEventCallbacks && virDomainEventCallbackListCount(data->domainEventCallbacks) == 0) {
|
|
||||||
data->vboxObj->vtbl->UnregisterCallback(data->vboxObj, data->vboxCallback);
|
|
||||||
VBOX_RELEASE(data->vboxCallback);
|
|
||||||
|
|
||||||
/* Remove the Event file handle on which we are listening as well */
|
/* Remove the Event file handle on which we are listening as well */
|
||||||
virEventRemoveHandle(data->fdWatch);
|
virEventRemoveHandle(data->fdWatch);
|
||||||
data->fdWatch = -1;
|
data->fdWatch = -1;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vboxDriverUnlock(data);
|
vboxDriverUnlock(data);
|
||||||
|
@ -63,6 +63,8 @@ static int
|
|||||||
xenUnifiedDomainGetVcpus (virDomainPtr dom,
|
xenUnifiedDomainGetVcpus (virDomainPtr dom,
|
||||||
virVcpuInfoPtr info, int maxinfo,
|
virVcpuInfoPtr info, int maxinfo,
|
||||||
unsigned char *cpumaps, int maplen);
|
unsigned char *cpumaps, int maplen);
|
||||||
|
static void xenDomainEventFlush(int timer ATTRIBUTE_UNUSED, void *opaque);
|
||||||
|
|
||||||
|
|
||||||
/* The five Xen drivers below us. */
|
/* The five Xen drivers below us. */
|
||||||
static struct xenUnifiedDriver const * const drivers[XEN_UNIFIED_NR_DRIVERS] = {
|
static struct xenUnifiedDriver const * const drivers[XEN_UNIFIED_NR_DRIVERS] = {
|
||||||
@ -248,12 +250,13 @@ xenUnifiedXendProbe (void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static virDrvOpenStatus
|
static virDrvOpenStatus
|
||||||
xenUnifiedOpen (virConnectPtr conn, virConnectAuthPtr auth, unsigned int flags)
|
xenUnifiedOpen (virConnectPtr conn, virConnectAuthPtr auth, unsigned int flags)
|
||||||
{
|
{
|
||||||
int i, ret = VIR_DRV_OPEN_DECLINED;
|
int i, ret = VIR_DRV_OPEN_DECLINED;
|
||||||
xenUnifiedPrivatePtr priv;
|
xenUnifiedPrivatePtr priv;
|
||||||
virDomainEventCallbackListPtr cbList;
|
|
||||||
|
|
||||||
#ifdef __sun
|
#ifdef __sun
|
||||||
/*
|
/*
|
||||||
@ -323,17 +326,16 @@ xenUnifiedOpen (virConnectPtr conn, virConnectAuthPtr auth, unsigned int flags)
|
|||||||
return VIR_DRV_OPEN_ERROR;
|
return VIR_DRV_OPEN_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate callback list */
|
if (!(priv->domainEvents = virDomainEventStateNew(xenDomainEventFlush,
|
||||||
if (VIR_ALLOC(cbList) < 0) {
|
priv,
|
||||||
virReportOOMError();
|
NULL,
|
||||||
|
false))) {
|
||||||
virMutexDestroy(&priv->lock);
|
virMutexDestroy(&priv->lock);
|
||||||
VIR_FREE(priv);
|
VIR_FREE(priv);
|
||||||
return VIR_DRV_OPEN_ERROR;
|
return VIR_DRV_OPEN_ERROR;
|
||||||
}
|
}
|
||||||
conn->privateData = priv;
|
conn->privateData = priv;
|
||||||
|
|
||||||
priv->domainEventCallbacks = cbList;
|
|
||||||
|
|
||||||
priv->handle = -1;
|
priv->handle = -1;
|
||||||
priv->xendConfigVersion = -1;
|
priv->xendConfigVersion = -1;
|
||||||
priv->xshandle = NULL;
|
priv->xshandle = NULL;
|
||||||
@ -423,7 +425,7 @@ xenUnifiedClose (virConnectPtr conn)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
virCapabilitiesFree(priv->caps);
|
virCapabilitiesFree(priv->caps);
|
||||||
virDomainEventCallbackListFree(priv->domainEventCallbacks);
|
virDomainEventStateFree(priv->domainEvents);
|
||||||
|
|
||||||
for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
|
for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
|
||||||
if (priv->opened[i])
|
if (priv->opened[i])
|
||||||
@ -1845,7 +1847,7 @@ xenUnifiedDomainEventRegister(virConnectPtr conn,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = virDomainEventCallbackListAdd(conn, priv->domainEventCallbacks,
|
ret = virDomainEventCallbackListAdd(conn, priv->domainEvents->callbacks,
|
||||||
callback, opaque, freefunc);
|
callback, opaque, freefunc);
|
||||||
|
|
||||||
xenUnifiedUnlock(priv);
|
xenUnifiedUnlock(priv);
|
||||||
@ -1867,12 +1869,9 @@ xenUnifiedDomainEventDeregister(virConnectPtr conn,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priv->domainEventDispatching)
|
ret = virDomainEventStateDeregister(conn,
|
||||||
ret = virDomainEventCallbackListMarkDelete(conn, priv->domainEventCallbacks,
|
priv->domainEvents,
|
||||||
callback);
|
callback);
|
||||||
else
|
|
||||||
ret = virDomainEventCallbackListRemove(conn, priv->domainEventCallbacks,
|
|
||||||
callback);
|
|
||||||
|
|
||||||
xenUnifiedUnlock(priv);
|
xenUnifiedUnlock(priv);
|
||||||
return ret;
|
return ret;
|
||||||
@ -1898,7 +1897,7 @@ xenUnifiedDomainEventRegisterAny(virConnectPtr conn,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = virDomainEventCallbackListAddID(conn, priv->domainEventCallbacks,
|
ret = virDomainEventCallbackListAddID(conn, priv->domainEvents->callbacks,
|
||||||
dom, eventID,
|
dom, eventID,
|
||||||
callback, opaque, freefunc);
|
callback, opaque, freefunc);
|
||||||
|
|
||||||
@ -1920,12 +1919,9 @@ xenUnifiedDomainEventDeregisterAny(virConnectPtr conn,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priv->domainEventDispatching)
|
ret = virDomainEventStateDeregisterAny(conn,
|
||||||
ret = virDomainEventCallbackListMarkDeleteID(conn, priv->domainEventCallbacks,
|
priv->domainEvents,
|
||||||
callbackID);
|
callbackID);
|
||||||
else
|
|
||||||
ret = virDomainEventCallbackListRemoveID(conn, priv->domainEventCallbacks,
|
|
||||||
callbackID);
|
|
||||||
|
|
||||||
xenUnifiedUnlock(priv);
|
xenUnifiedUnlock(priv);
|
||||||
return ret;
|
return ret;
|
||||||
@ -2390,6 +2386,7 @@ xenUnifiedRemoveDomainInfo(xenUnifiedDomainInfoListPtr list,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
xenUnifiedDomainEventDispatchFunc(virConnectPtr conn,
|
xenUnifiedDomainEventDispatchFunc(virConnectPtr conn,
|
||||||
virDomainEventPtr event,
|
virDomainEventPtr event,
|
||||||
@ -2411,6 +2408,19 @@ xenUnifiedDomainEventDispatchFunc(virConnectPtr conn,
|
|||||||
xenUnifiedLock(priv);
|
xenUnifiedLock(priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void xenDomainEventFlush(int timer ATTRIBUTE_UNUSED, void *opaque)
|
||||||
|
{
|
||||||
|
virConnectPtr conn = opaque;
|
||||||
|
xenUnifiedPrivatePtr priv = conn->privateData;
|
||||||
|
|
||||||
|
xenUnifiedLock(priv);
|
||||||
|
virDomainEventStateFlush(priv->domainEvents,
|
||||||
|
xenUnifiedDomainEventDispatchFunc,
|
||||||
|
priv);
|
||||||
|
xenUnifiedUnlock(priv);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xenUnifiedDomainEventDispatch:
|
* xenUnifiedDomainEventDispatch:
|
||||||
* @priv: the connection to dispatch events on
|
* @priv: the connection to dispatch events on
|
||||||
@ -2427,21 +2437,7 @@ void xenUnifiedDomainEventDispatch (xenUnifiedPrivatePtr priv,
|
|||||||
if (!priv)
|
if (!priv)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
priv->domainEventDispatching = 1;
|
virDomainEventStateQueue(priv->domainEvents, event);
|
||||||
|
|
||||||
if (priv->domainEventCallbacks) {
|
|
||||||
virDomainEventDispatch(event,
|
|
||||||
priv->domainEventCallbacks,
|
|
||||||
xenUnifiedDomainEventDispatchFunc,
|
|
||||||
priv);
|
|
||||||
|
|
||||||
/* Purge any deleted callbacks */
|
|
||||||
virDomainEventCallbackListPurgeMarked(priv->domainEventCallbacks);
|
|
||||||
}
|
|
||||||
|
|
||||||
virDomainEventFree(event);
|
|
||||||
|
|
||||||
priv->domainEventDispatching = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void xenUnifiedLock(xenUnifiedPrivatePtr priv)
|
void xenUnifiedLock(xenUnifiedPrivatePtr priv)
|
||||||
|
@ -183,9 +183,7 @@ struct _xenUnifiedPrivate {
|
|||||||
int nbNodeCells;
|
int nbNodeCells;
|
||||||
int nbNodeCpus;
|
int nbNodeCpus;
|
||||||
|
|
||||||
/* An list of callbacks */
|
virDomainEventStatePtr domainEvents;
|
||||||
virDomainEventCallbackListPtr domainEventCallbacks;
|
|
||||||
int domainEventDispatching;
|
|
||||||
|
|
||||||
/* Location of config files, either /etc
|
/* Location of config files, either /etc
|
||||||
* or /var/lib/xen */
|
* or /var/lib/xen */
|
||||||
|
Loading…
Reference in New Issue
Block a user