This patch continues the earlier conversion made for network
events, with a goal of introducing server-side event filtering
in a later patch. Actual behavior is unchanged without
further RPC changes.
* daemon/libvirtd.h (daemonClientPrivate): Alter the tracking of
domain events.
* daemon/remote.c (remoteClientInitHook, remoteClientFreeFunc)
(remoteRelayDomainEvent*)
(remoteDispatchConnectDomainEventRegister)
(remoteDispatchConnectDomainEventRegisterAny): Track domain
callbacks dynamically.
---
daemon/libvirtd.h | 3 +-
daemon/remote.c | 436 +++++++++++++++++++++++++++++++++---------------------
2 files changed, 266 insertions(+), 173 deletions(-)
diff --git a/daemon/libvirtd.h b/daemon/libvirtd.h
index a260ea1..c4f1f27 100644
--- a/daemon/libvirtd.h
+++ b/daemon/libvirtd.h
@@ -51,7 +51,8 @@ struct daemonClientPrivate {
/* Hold while accessing any data except conn */
virMutex lock;
- int domainEventCallbackID[VIR_DOMAIN_EVENT_ID_LAST];
+ daemonClientEventCallbackPtr *domainEventCallbacks;
+ size_t ndomainEventCallbacks;
daemonClientEventCallbackPtr *networkEventCallbacks;
size_t nnetworkEventCallbacks;
diff --git a/daemon/remote.c b/daemon/remote.c
index d2aafbe..f0b9922 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -127,19 +127,21 @@ remoteEventCallbackFree(void *opaque)
VIR_FREE(opaque);
}
-static int remoteRelayDomainEventLifecycle(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- int event,
- int detail,
- void *opaque)
+static int
+remoteRelayDomainEventLifecycle(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ int event,
+ int detail,
+ void *opaque)
{
- virNetServerClientPtr client = opaque;
+ daemonClientEventCallbackPtr callback = opaque;
remote_domain_event_lifecycle_msg data;
- if (!client)
+ if (callback->callbackID < 0)
return -1;
- VIR_DEBUG("Relaying domain lifecycle event %d %d", event, detail);
+ VIR_DEBUG("Relaying domain lifecycle event %d %d, callback %d",
+ event, detail, callback->callbackID);
/* build return data */
memset(&data, 0, sizeof(data));
@@ -147,30 +149,32 @@ static int remoteRelayDomainEventLifecycle(virConnectPtr conn
ATTRIBUTE_UNUSED,
data.event = event;
data.detail = detail;
- remoteDispatchObjectEventSend(client, remoteProgram,
+ remoteDispatchObjectEventSend(callback->client, remoteProgram,
REMOTE_PROC_DOMAIN_EVENT_LIFECYCLE,
(xdrproc_t)xdr_remote_domain_event_lifecycle_msg,
&data);
return 0;
}
-static int remoteRelayDomainEventReboot(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- void *opaque)
+static int
+remoteRelayDomainEventReboot(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ void *opaque)
{
- virNetServerClientPtr client = opaque;
+ daemonClientEventCallbackPtr callback = opaque;
remote_domain_event_reboot_msg data;
- if (!client)
+ if (callback->callbackID < 0)
return -1;
- VIR_DEBUG("Relaying domain reboot event %s %d", dom->name, dom->id);
+ VIR_DEBUG("Relaying domain reboot event %s %d, callback %d",
+ dom->name, dom->id, callback->callbackID);
/* build return data */
memset(&data, 0, sizeof(data));
make_nonnull_domain(&data.dom, dom);
- remoteDispatchObjectEventSend(client, remoteProgram,
+ remoteDispatchObjectEventSend(callback->client, remoteProgram,
REMOTE_PROC_DOMAIN_EVENT_REBOOT,
(xdrproc_t)xdr_remote_domain_event_reboot_msg,
&data);
@@ -178,25 +182,27 @@ static int remoteRelayDomainEventReboot(virConnectPtr conn
ATTRIBUTE_UNUSED,
}
-static int remoteRelayDomainEventRTCChange(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- long long offset,
- void *opaque)
+static int
+remoteRelayDomainEventRTCChange(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ long long offset,
+ void *opaque)
{
- virNetServerClientPtr client = opaque;
+ daemonClientEventCallbackPtr callback = opaque;
remote_domain_event_rtc_change_msg data;
- if (!client)
+ if (callback->callbackID < 0)
return -1;
- VIR_DEBUG("Relaying domain rtc change event %s %d %lld", dom->name,
dom->id, offset);
+ VIR_DEBUG("Relaying domain rtc change event %s %d %lld, callback %d",
+ dom->name, dom->id, offset, callback->callbackID);
/* build return data */
memset(&data, 0, sizeof(data));
make_nonnull_domain(&data.dom, dom);
data.offset = offset;
- remoteDispatchObjectEventSend(client, remoteProgram,
+ remoteDispatchObjectEventSend(callback->client, remoteProgram,
REMOTE_PROC_DOMAIN_EVENT_RTC_CHANGE,
(xdrproc_t)xdr_remote_domain_event_rtc_change_msg,
&data);
@@ -204,25 +210,27 @@ static int remoteRelayDomainEventRTCChange(virConnectPtr conn
ATTRIBUTE_UNUSED,
}
-static int remoteRelayDomainEventWatchdog(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- int action,
- void *opaque)
+static int
+remoteRelayDomainEventWatchdog(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ int action,
+ void *opaque)
{
- virNetServerClientPtr client = opaque;
+ daemonClientEventCallbackPtr callback = opaque;
remote_domain_event_watchdog_msg data;
- if (!client)
+ if (callback->callbackID < 0)
return -1;
- VIR_DEBUG("Relaying domain watchdog event %s %d %d", dom->name,
dom->id, action);
+ VIR_DEBUG("Relaying domain watchdog event %s %d %d, callback %d",
+ dom->name, dom->id, action, callback->callbackID);
/* build return data */
memset(&data, 0, sizeof(data));
make_nonnull_domain(&data.dom, dom);
data.action = action;
- remoteDispatchObjectEventSend(client, remoteProgram,
+ remoteDispatchObjectEventSend(callback->client, remoteProgram,
REMOTE_PROC_DOMAIN_EVENT_WATCHDOG,
(xdrproc_t)xdr_remote_domain_event_watchdog_msg,
&data);
@@ -230,20 +238,23 @@ static int remoteRelayDomainEventWatchdog(virConnectPtr conn
ATTRIBUTE_UNUSED,
}
-static int remoteRelayDomainEventIOError(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- const char *srcPath,
- const char *devAlias,
- int action,
- void *opaque)
+static int
+remoteRelayDomainEventIOError(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ const char *srcPath,
+ const char *devAlias,
+ int action,
+ void *opaque)
{
- virNetServerClientPtr client = opaque;
+ daemonClientEventCallbackPtr callback = opaque;
remote_domain_event_io_error_msg data;
- if (!client)
+ if (callback->callbackID < 0)
return -1;
- VIR_DEBUG("Relaying domain io error %s %d %s %s %d", dom->name,
dom->id, srcPath, devAlias, action);
+ VIR_DEBUG("Relaying domain io error %s %d %s %s %d, callback %d",
+ dom->name, dom->id, srcPath, devAlias, action,
+ callback->callbackID);
/* build return data */
memset(&data, 0, sizeof(data));
@@ -253,7 +264,7 @@ static int remoteRelayDomainEventIOError(virConnectPtr conn
ATTRIBUTE_UNUSED,
make_nonnull_domain(&data.dom, dom);
data.action = action;
- remoteDispatchObjectEventSend(client, remoteProgram,
+ remoteDispatchObjectEventSend(callback->client, remoteProgram,
REMOTE_PROC_DOMAIN_EVENT_IO_ERROR,
(xdrproc_t)xdr_remote_domain_event_io_error_msg,
&data);
@@ -265,22 +276,24 @@ error:
}
-static int remoteRelayDomainEventIOErrorReason(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- const char *srcPath,
- const char *devAlias,
- int action,
- const char *reason,
- void *opaque)
+static int
+remoteRelayDomainEventIOErrorReason(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ const char *srcPath,
+ const char *devAlias,
+ int action,
+ const char *reason,
+ void *opaque)
{
- virNetServerClientPtr client = opaque;
+ daemonClientEventCallbackPtr callback = opaque;
remote_domain_event_io_error_reason_msg data;
- if (!client)
+ if (callback->callbackID < 0)
return -1;
- VIR_DEBUG("Relaying domain io error %s %d %s %s %d %s",
- dom->name, dom->id, srcPath, devAlias, action, reason);
+ VIR_DEBUG("Relaying domain io error %s %d %s %s %d %s, callback %d",
+ dom->name, dom->id, srcPath, devAlias, action, reason,
+ callback->callbackID);
/* build return data */
memset(&data, 0, sizeof(data));
@@ -292,7 +305,7 @@ static int remoteRelayDomainEventIOErrorReason(virConnectPtr conn
ATTRIBUTE_UNUS
make_nonnull_domain(&data.dom, dom);
- remoteDispatchObjectEventSend(client, remoteProgram,
+ remoteDispatchObjectEventSend(callback->client, remoteProgram,
REMOTE_PROC_DOMAIN_EVENT_IO_ERROR_REASON,
(xdrproc_t)xdr_remote_domain_event_io_error_reason_msg,
&data);
@@ -306,26 +319,28 @@ error:
}
-static int remoteRelayDomainEventGraphics(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- int phase,
- virDomainEventGraphicsAddressPtr local,
- virDomainEventGraphicsAddressPtr remote,
- const char *authScheme,
- virDomainEventGraphicsSubjectPtr subject,
- void *opaque)
+static int
+remoteRelayDomainEventGraphics(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ int phase,
+ virDomainEventGraphicsAddressPtr local,
+ virDomainEventGraphicsAddressPtr remote,
+ const char *authScheme,
+ virDomainEventGraphicsSubjectPtr subject,
+ void *opaque)
{
- virNetServerClientPtr client = opaque;
+ daemonClientEventCallbackPtr callback = opaque;
remote_domain_event_graphics_msg data;
size_t i;
- if (!client)
+ if (callback->callbackID < 0)
return -1;
- VIR_DEBUG("Relaying domain graphics event %s %d %d - %d %s %s - %d %s %s -
%s", dom->name, dom->id, phase,
+ VIR_DEBUG("Relaying domain graphics event %s %d %d - %d %s %s - %d %s %s - %s,
callback %d",
+ dom->name, dom->id, phase,
local->family, local->service, local->node,
remote->family, remote->service, remote->node,
- authScheme);
+ authScheme, callback->callbackID);
VIR_DEBUG("Subject %d", subject->nidentity);
for (i = 0; i < subject->nidentity; i++) {
@@ -355,7 +370,7 @@ static int remoteRelayDomainEventGraphics(virConnectPtr conn
ATTRIBUTE_UNUSED,
}
make_nonnull_domain(&data.dom, dom);
- remoteDispatchObjectEventSend(client, remoteProgram,
+ remoteDispatchObjectEventSend(callback->client, remoteProgram,
REMOTE_PROC_DOMAIN_EVENT_GRAPHICS,
(xdrproc_t)xdr_remote_domain_event_graphics_msg,
&data);
@@ -377,21 +392,22 @@ error:
return -1;
}
-static int remoteRelayDomainEventBlockJob(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- const char *path,
- int type,
- int status,
- void *opaque)
+static int
+remoteRelayDomainEventBlockJob(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ const char *path,
+ int type,
+ int status,
+ void *opaque)
{
- virNetServerClientPtr client = opaque;
+ daemonClientEventCallbackPtr callback = opaque;
remote_domain_event_block_job_msg data;
- if (!client)
+ if (callback->callbackID < 0)
return -1;
- VIR_DEBUG("Relaying domain block job event %s %d %s %i, %i",
- dom->name, dom->id, path, type, status);
+ VIR_DEBUG("Relaying domain block job event %s %d %s %i, %i, callback %d",
+ dom->name, dom->id, path, type, status, callback->callbackID);
/* build return data */
memset(&data, 0, sizeof(data));
@@ -401,7 +417,7 @@ static int remoteRelayDomainEventBlockJob(virConnectPtr conn
ATTRIBUTE_UNUSED,
data.status = status;
make_nonnull_domain(&data.dom, dom);
- remoteDispatchObjectEventSend(client, remoteProgram,
+ remoteDispatchObjectEventSend(callback->client, remoteProgram,
REMOTE_PROC_DOMAIN_EVENT_BLOCK_JOB,
(xdrproc_t)xdr_remote_domain_event_block_job_msg,
&data);
@@ -412,23 +428,25 @@ error:
}
-static int remoteRelayDomainEventControlError(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- void *opaque)
+static int
+remoteRelayDomainEventControlError(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ void *opaque)
{
- virNetServerClientPtr client = opaque;
+ daemonClientEventCallbackPtr callback = opaque;
remote_domain_event_control_error_msg data;
- if (!client)
+ if (callback->callbackID < 0)
return -1;
- VIR_DEBUG("Relaying domain control error %s %d", dom->name,
dom->id);
+ VIR_DEBUG("Relaying domain control error %s %d, callback %d",
+ dom->name, dom->id, callback->callbackID);
/* build return data */
memset(&data, 0, sizeof(data));
make_nonnull_domain(&data.dom, dom);
- remoteDispatchObjectEventSend(client, remoteProgram,
+ remoteDispatchObjectEventSend(callback->client, remoteProgram,
REMOTE_PROC_DOMAIN_EVENT_CONTROL_ERROR,
(xdrproc_t)xdr_remote_domain_event_control_error_msg,
&data);
@@ -436,23 +454,25 @@ static int remoteRelayDomainEventControlError(virConnectPtr conn
ATTRIBUTE_UNUSE
}
-static int remoteRelayDomainEventDiskChange(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- const char *oldSrcPath,
- const char *newSrcPath,
- const char *devAlias,
- int reason,
- void *opaque)
+static int
+remoteRelayDomainEventDiskChange(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ const char *oldSrcPath,
+ const char *newSrcPath,
+ const char *devAlias,
+ int reason,
+ void *opaque)
{
- virNetServerClientPtr client = opaque;
+ daemonClientEventCallbackPtr callback = opaque;
remote_domain_event_disk_change_msg data;
char **oldSrcPath_p = NULL, **newSrcPath_p = NULL;
- if (!client)
+ if (callback->callbackID < 0)
return -1;
- VIR_DEBUG("Relaying domain %s %d disk change %s %s %s %d",
- dom->name, dom->id, oldSrcPath, newSrcPath, devAlias, reason);
+ VIR_DEBUG("Relaying domain %s %d disk change %s %s %s %d, callback %d",
+ dom->name, dom->id, oldSrcPath, newSrcPath, devAlias, reason,
+ callback->callbackID);
/* build return data */
memset(&data, 0, sizeof(data));
@@ -474,7 +494,7 @@ static int remoteRelayDomainEventDiskChange(virConnectPtr conn
ATTRIBUTE_UNUSED,
make_nonnull_domain(&data.dom, dom);
- remoteDispatchObjectEventSend(client, remoteProgram,
+ remoteDispatchObjectEventSend(callback->client, remoteProgram,
REMOTE_PROC_DOMAIN_EVENT_DISK_CHANGE,
(xdrproc_t)xdr_remote_domain_event_disk_change_msg,
&data);
@@ -487,19 +507,21 @@ error:
}
-static int remoteRelayDomainEventTrayChange(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- const char *devAlias,
- int reason,
- void *opaque) {
- virNetServerClientPtr client = opaque;
+static int
+remoteRelayDomainEventTrayChange(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ const char *devAlias,
+ int reason,
+ void *opaque)
+{
+ daemonClientEventCallbackPtr callback = opaque;
remote_domain_event_tray_change_msg data;
- if (!client)
+ if (callback->callbackID < 0)
return -1;
- VIR_DEBUG("Relaying domain %s %d tray change devAlias: %s reason: %d",
- dom->name, dom->id, devAlias, reason);
+ VIR_DEBUG("Relaying domain %s %d tray change devAlias: %s reason: %d, callback
%d",
+ dom->name, dom->id, devAlias, reason, callback->callbackID);
/* build return data */
memset(&data, 0, sizeof(data));
@@ -510,53 +532,59 @@ static int remoteRelayDomainEventTrayChange(virConnectPtr conn
ATTRIBUTE_UNUSED,
make_nonnull_domain(&data.dom, dom);
- remoteDispatchObjectEventSend(client, remoteProgram,
+ remoteDispatchObjectEventSend(callback->client, remoteProgram,
REMOTE_PROC_DOMAIN_EVENT_TRAY_CHANGE,
(xdrproc_t)xdr_remote_domain_event_tray_change_msg,
&data);
return 0;
}
-static int remoteRelayDomainEventPMWakeup(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- int reason ATTRIBUTE_UNUSED,
- void *opaque) {
- virNetServerClientPtr client = opaque;
+static int
+remoteRelayDomainEventPMWakeup(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ int reason ATTRIBUTE_UNUSED,
+ void *opaque)
+{
+ daemonClientEventCallbackPtr callback = opaque;
remote_domain_event_pmwakeup_msg data;
- if (!client)
+ if (callback->callbackID < 0)
return -1;
- VIR_DEBUG("Relaying domain %s %d system pmwakeup", dom->name,
dom->id);
+ VIR_DEBUG("Relaying domain %s %d system pmwakeup, callback %d",
+ dom->name, dom->id, callback->callbackID);
/* build return data */
memset(&data, 0, sizeof(data));
make_nonnull_domain(&data.dom, dom);
- remoteDispatchObjectEventSend(client, remoteProgram,
+ remoteDispatchObjectEventSend(callback->client, remoteProgram,
REMOTE_PROC_DOMAIN_EVENT_PMWAKEUP,
(xdrproc_t)xdr_remote_domain_event_pmwakeup_msg,
&data);
return 0;
}
-static int remoteRelayDomainEventPMSuspend(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- int reason ATTRIBUTE_UNUSED,
- void *opaque) {
- virNetServerClientPtr client = opaque;
+static int
+remoteRelayDomainEventPMSuspend(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ int reason ATTRIBUTE_UNUSED,
+ void *opaque)
+{
+ daemonClientEventCallbackPtr callback = opaque;
remote_domain_event_pmsuspend_msg data;
- if (!client)
+ if (callback->callbackID < 0)
return -1;
- VIR_DEBUG("Relaying domain %s %d system pmsuspend", dom->name,
dom->id);
+ VIR_DEBUG("Relaying domain %s %d system pmsuspend, callback %d",
+ dom->name, dom->id, callback->callbackID);
/* build return data */
memset(&data, 0, sizeof(data));
make_nonnull_domain(&data.dom, dom);
- remoteDispatchObjectEventSend(client, remoteProgram,
+ remoteDispatchObjectEventSend(callback->client, remoteProgram,
REMOTE_PROC_DOMAIN_EVENT_PMSUSPEND,
(xdrproc_t)xdr_remote_domain_event_pmsuspend_msg,
&data);
@@ -569,20 +597,21 @@ remoteRelayDomainEventBalloonChange(virConnectPtr conn
ATTRIBUTE_UNUSED,
unsigned long long actual,
void *opaque)
{
- virNetServerClientPtr client = opaque;
+ daemonClientEventCallbackPtr callback = opaque;
remote_domain_event_balloon_change_msg data;
- if (!client)
+ if (callback->callbackID < 0)
return -1;
- VIR_DEBUG("Relaying domain balloon change event %s %d %lld", dom->name,
dom->id, actual);
+ VIR_DEBUG("Relaying domain balloon change event %s %d %lld, callback %d",
+ dom->name, dom->id, actual, callback->callbackID);
/* build return data */
memset(&data, 0, sizeof(data));
make_nonnull_domain(&data.dom, dom);
data.actual = actual;
- remoteDispatchObjectEventSend(client, remoteProgram,
+ remoteDispatchObjectEventSend(callback->client, remoteProgram,
REMOTE_PROC_DOMAIN_EVENT_BALLOON_CHANGE,
(xdrproc_t)xdr_remote_domain_event_balloon_change_msg,
&data);
@@ -590,23 +619,26 @@ remoteRelayDomainEventBalloonChange(virConnectPtr conn
ATTRIBUTE_UNUSED,
}
-static int remoteRelayDomainEventPMSuspendDisk(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- int reason ATTRIBUTE_UNUSED,
- void *opaque) {
- virNetServerClientPtr client = opaque;
+static int
+remoteRelayDomainEventPMSuspendDisk(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ int reason ATTRIBUTE_UNUSED,
+ void *opaque)
+{
+ daemonClientEventCallbackPtr callback = opaque;
remote_domain_event_pmsuspend_disk_msg data;
- if (!client)
+ if (callback->callbackID < 0)
return -1;
- VIR_DEBUG("Relaying domain %s %d system pmsuspend-disk", dom->name,
dom->id);
+ VIR_DEBUG("Relaying domain %s %d system pmsuspend-disk, callback %d",
+ dom->name, dom->id, callback->callbackID);
/* build return data */
memset(&data, 0, sizeof(data));
make_nonnull_domain(&data.dom, dom);
- remoteDispatchObjectEventSend(client, remoteProgram,
+ remoteDispatchObjectEventSend(callback->client, remoteProgram,
REMOTE_PROC_DOMAIN_EVENT_PMSUSPEND_DISK,
(xdrproc_t)xdr_remote_domain_event_pmsuspend_disk_msg,
&data);
@@ -619,14 +651,14 @@ remoteRelayDomainEventDeviceRemoved(virConnectPtr conn
ATTRIBUTE_UNUSED,
const char *devAlias,
void *opaque)
{
- virNetServerClientPtr client = opaque;
+ daemonClientEventCallbackPtr callback = opaque;
remote_domain_event_device_removed_msg data;
- if (!client)
+ if (callback->callbackID < 0)
return -1;
- VIR_DEBUG("Relaying domain device removed event %s %d %s",
- dom->name, dom->id, devAlias);
+ VIR_DEBUG("Relaying domain device removed event %s %d %s, callback %d",
+ dom->name, dom->id, devAlias, callback->callbackID);
/* build return data */
memset(&data, 0, sizeof(data));
@@ -636,7 +668,7 @@ remoteRelayDomainEventDeviceRemoved(virConnectPtr conn
ATTRIBUTE_UNUSED,
make_nonnull_domain(&data.dom, dom);
- remoteDispatchObjectEventSend(client, remoteProgram,
+ remoteDispatchObjectEventSend(callback->client, remoteProgram,
REMOTE_PROC_DOMAIN_EVENT_DEVICE_REMOVED,
(xdrproc_t)xdr_remote_domain_event_device_removed_msg,
&data);
@@ -720,14 +752,19 @@ void remoteClientFreeFunc(void *data)
virIdentitySetCurrent(sysident);
- for (i = 0; i < VIR_DOMAIN_EVENT_ID_LAST; i++) {
- if (priv->domainEventCallbackID[i] != -1) {
- VIR_DEBUG("Deregistering to relay remote events %zu", i);
- virConnectDomainEventDeregisterAny(priv->conn,
- priv->domainEventCallbackID[i]);
+ for (i = 0; i < priv->ndomainEventCallbacks; i++) {
+ int callbackID = priv->domainEventCallbacks[i]->callbackID;
+ if (callbackID < 0) {
+ VIR_WARN("unexpected incomplete domain callback %zu", i);
+ continue;
}
- priv->domainEventCallbackID[i] = -1;
+ VIR_DEBUG("Deregistering remote domain event relay %d",
+ callbackID);
+ priv->domainEventCallbacks[i]->callbackID = -1;
+ if (virConnectDomainEventDeregisterAny(priv->conn, callbackID) < 0)
+ VIR_WARN("unexpected domain event deregister failure");
}
+ VIR_FREE(priv->domainEventCallbacks);
for (i = 0; i < priv->nnetworkEventCallbacks; i++) {
int callbackID = priv->networkEventCallbacks[i]->callbackID;
@@ -766,7 +803,6 @@ void *remoteClientInitHook(virNetServerClientPtr client,
void *opaque ATTRIBUTE_UNUSED)
{
struct daemonClientPrivate *priv;
- size_t i;
if (VIR_ALLOC(priv) < 0)
return NULL;
@@ -777,9 +813,6 @@ void *remoteClientInitHook(virNetServerClientPtr client,
return NULL;
}
- for (i = 0; i < VIR_DOMAIN_EVENT_ID_LAST; i++)
- priv->domainEventCallbackID[i] = -1;
-
virNetServerClientSetCloseHook(client, remoteClientCloseFunc);
return priv;
}
@@ -3143,13 +3176,15 @@ cleanup:
***************************/
static int
remoteDispatchConnectDomainEventRegister(virNetServerPtr server ATTRIBUTE_UNUSED,
- virNetServerClientPtr client ATTRIBUTE_UNUSED,
+ virNetServerClientPtr client,
virNetMessagePtr msg ATTRIBUTE_UNUSED,
virNetMessageErrorPtr rerr ATTRIBUTE_UNUSED,
remote_connect_domain_event_register_ret *ret
ATTRIBUTE_UNUSED)
{
int callbackID;
int rv = -1;
+ daemonClientEventCallbackPtr callback = NULL;
+ daemonClientEventCallbackPtr ref;
struct daemonClientPrivate *priv =
virNetServerClientGetPrivateData(client);
@@ -3160,23 +3195,41 @@ remoteDispatchConnectDomainEventRegister(virNetServerPtr server
ATTRIBUTE_UNUSED
virMutexLock(&priv->lock);
- if (priv->domainEventCallbackID[VIR_DOMAIN_EVENT_ID_LIFECYCLE] != -1) {
- virReportError(VIR_ERR_INTERNAL_ERROR, _("domain event %d already
registered"), VIR_DOMAIN_EVENT_ID_LIFECYCLE);
+ /* If we call register first, we could append a complete callback
+ * to our array, but on OOM append failure, we'd have to then hope
+ * deregister works to undo our register. So instead we append an
+ * incomplete callback to our array, then register, then fix up
+ * our callback; but since VIR_APPEND_ELEMENT clears 'callback' on
+ * success, we use 'ref' to save a copy of the pointer. */
+ if (VIR_ALLOC(callback) < 0)
+ goto cleanup;
+ callback->client = client;
+ callback->eventID = VIR_DOMAIN_EVENT_ID_LIFECYCLE;
+ callback->callbackID = -1;
+ ref = callback;
+ if (VIR_APPEND_ELEMENT(priv->domainEventCallbacks,
+ priv->ndomainEventCallbacks,
+ callback) < 0)
goto cleanup;
- }
if ((callbackID = virConnectDomainEventRegisterAny(priv->conn,
NULL,
VIR_DOMAIN_EVENT_ID_LIFECYCLE,
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventLifecycle),
- client, NULL)) < 0)
+ ref,
+ remoteEventCallbackFree)) < 0)
{
+ VIR_SHRINK_N(priv->domainEventCallbacks,
+ priv->ndomainEventCallbacks, 1);
+ callback = ref;
goto cleanup;
+ }
- priv->domainEventCallbackID[VIR_DOMAIN_EVENT_ID_LIFECYCLE] = callbackID;
+ ref->callbackID = callbackID;
rv = 0;
cleanup:
+ VIR_FREE(callback);
if (rv < 0)
virNetMessageSaveError(rerr);
virMutexUnlock(&priv->lock);
@@ -3185,12 +3238,14 @@ cleanup:
static int
remoteDispatchConnectDomainEventDeregister(virNetServerPtr server ATTRIBUTE_UNUSED,
- virNetServerClientPtr client
ATTRIBUTE_UNUSED,
+ virNetServerClientPtr client,
virNetMessagePtr msg ATTRIBUTE_UNUSED,
virNetMessageErrorPtr rerr ATTRIBUTE_UNUSED,
remote_connect_domain_event_deregister_ret
*ret ATTRIBUTE_UNUSED)
{
+ int callbackID = -1;
int rv = -1;
+ size_t i;
struct daemonClientPrivate *priv =
virNetServerClientGetPrivateData(client);
@@ -3201,16 +3256,25 @@ remoteDispatchConnectDomainEventDeregister(virNetServerPtr server
ATTRIBUTE_UNUS
virMutexLock(&priv->lock);
- if (priv->domainEventCallbackID[VIR_DOMAIN_EVENT_ID_LIFECYCLE] < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR, _("domain event %d not
registered"), VIR_DOMAIN_EVENT_ID_LIFECYCLE);
+ for (i = 0; i < priv->ndomainEventCallbacks; i++) {
+ if (priv->domainEventCallbacks[i]->eventID ==
VIR_DOMAIN_EVENT_ID_LIFECYCLE) {
+ callbackID = priv->domainEventCallbacks[i]->callbackID;
+ break;
+ }
+ }
+
+ if (callbackID < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("domain event %d not registered"),
+ VIR_DOMAIN_EVENT_ID_LIFECYCLE);
goto cleanup;
}
- if (virConnectDomainEventDeregisterAny(priv->conn,
-
priv->domainEventCallbackID[VIR_DOMAIN_EVENT_ID_LIFECYCLE]) < 0)
+ if (virConnectDomainEventDeregisterAny(priv->conn, callbackID) < 0)
goto cleanup;
- priv->domainEventCallbackID[VIR_DOMAIN_EVENT_ID_LIFECYCLE] = -1;
+ VIR_DELETE_ELEMENT(priv->domainEventCallbacks, i,
+ priv->ndomainEventCallbacks);
rv = 0;
@@ -3332,13 +3396,15 @@ cleanup:
static int
remoteDispatchConnectDomainEventRegisterAny(virNetServerPtr server ATTRIBUTE_UNUSED,
- virNetServerClientPtr client
ATTRIBUTE_UNUSED,
+ virNetServerClientPtr client,
virNetMessagePtr msg ATTRIBUTE_UNUSED,
virNetMessageErrorPtr rerr ATTRIBUTE_UNUSED,
remote_connect_domain_event_register_any_args
*args)
{
int callbackID;
int rv = -1;
+ daemonClientEventCallbackPtr callback = NULL;
+ daemonClientEventCallbackPtr ref;
struct daemonClientPrivate *priv =
virNetServerClientGetPrivateData(client);
@@ -3355,23 +3421,41 @@ remoteDispatchConnectDomainEventRegisterAny(virNetServerPtr server
ATTRIBUTE_UNU
goto cleanup;
}
- if (priv->domainEventCallbackID[args->eventID] != -1) {
- virReportError(VIR_ERR_INTERNAL_ERROR, _("domain event %d already
registered"), args->eventID);
+ /* If we call register first, we could append a complete callback
+ * to our array, but on OOM append failure, we'd have to then hope
+ * deregister works to undo our register. So instead we append an
+ * incomplete callback to our array, then register, then fix up
+ * our callback; but since VIR_APPEND_ELEMENT clears 'callback' on
+ * success, we use 'ref' to save a copy of the pointer. */
+ if (VIR_ALLOC(callback) < 0)
+ goto cleanup;
+ callback->client = client;
+ callback->eventID = args->eventID;
+ callback->callbackID = -1;
+ ref = callback;
+ if (VIR_APPEND_ELEMENT(priv->domainEventCallbacks,
+ priv->ndomainEventCallbacks,
+ callback) < 0)
goto cleanup;
- }
if ((callbackID = virConnectDomainEventRegisterAny(priv->conn,
NULL,
args->eventID,
domainEventCallbacks[args->eventID],
- client, NULL)) < 0)
+ ref,
+ remoteEventCallbackFree)) < 0)
{
+ VIR_SHRINK_N(priv->domainEventCallbacks,
+ priv->ndomainEventCallbacks, 1);
+ callback = ref;
goto cleanup;
+ }
- priv->domainEventCallbackID[args->eventID] = callbackID;
+ ref->callbackID = callbackID;
rv = 0;
cleanup:
+ VIR_FREE(callback);
if (rv < 0)
virNetMessageSaveError(rerr);
virMutexUnlock(&priv->lock);
@@ -3381,13 +3465,14 @@ cleanup:
static int
remoteDispatchConnectDomainEventDeregisterAny(virNetServerPtr server ATTRIBUTE_UNUSED,
- virNetServerClientPtr client
ATTRIBUTE_UNUSED,
+ virNetServerClientPtr client,
virNetMessagePtr msg ATTRIBUTE_UNUSED,
virNetMessageErrorPtr rerr
ATTRIBUTE_UNUSED,
remote_connect_domain_event_deregister_any_args *args)
{
int callbackID = -1;
int rv = -1;
+ size_t i;
struct daemonClientPrivate *priv =
virNetServerClientGetPrivateData(client);
@@ -3404,16 +3489,23 @@ remoteDispatchConnectDomainEventDeregisterAny(virNetServerPtr
server ATTRIBUTE_U
goto cleanup;
}
- callbackID = priv->domainEventCallbackID[args->eventID];
+ for (i = 0; i < priv->ndomainEventCallbacks; i++) {
+ if (priv->domainEventCallbacks[i]->eventID == args->eventID) {
+ callbackID = priv->domainEventCallbacks[i]->callbackID;
+ break;
+ }
+ }
if (callbackID < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR, _("domain event %d not
registered"), args->eventID);
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("domain event %d not registered"), args->eventID);
goto cleanup;
}
if (virConnectDomainEventDeregisterAny(priv->conn, callbackID) < 0)
goto cleanup;
- priv->domainEventCallbackID[args->eventID] = -1;
+ VIR_DELETE_ELEMENT(priv->domainEventCallbacks, i,
+ priv->ndomainEventCallbacks);
rv = 0;
--
1.8.4.2