mirror of https://gitee.com/openkylin/libvirt.git
event: dynamically manage server-side RPC domain events
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.
This commit is contained in:
parent
74cf8202d2
commit
047fd2e83e
|
@ -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;
|
||||
|
||||
|
|
294
daemon/remote.c
294
daemon/remote.c
|
@ -192,13 +192,15 @@ remoteRelayDomainEventLifecycle(virConnectPtr conn,
|
|||
int detail,
|
||||
void *opaque)
|
||||
{
|
||||
virNetServerClientPtr client = opaque;
|
||||
daemonClientEventCallbackPtr callback = opaque;
|
||||
remote_domain_event_lifecycle_msg data;
|
||||
|
||||
if (!client || !remoteRelayDomainEventCheckACL(client, conn, dom))
|
||||
if (callback->callbackID < 0 ||
|
||||
!remoteRelayDomainEventCheckACL(callback->client, conn, dom))
|
||||
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));
|
||||
|
@ -206,7 +208,7 @@ remoteRelayDomainEventLifecycle(virConnectPtr conn,
|
|||
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);
|
||||
|
||||
|
@ -218,19 +220,21 @@ remoteRelayDomainEventReboot(virConnectPtr conn,
|
|||
virDomainPtr dom,
|
||||
void *opaque)
|
||||
{
|
||||
virNetServerClientPtr client = opaque;
|
||||
daemonClientEventCallbackPtr callback = opaque;
|
||||
remote_domain_event_reboot_msg data;
|
||||
|
||||
if (!client || !remoteRelayDomainEventCheckACL(client, conn, dom))
|
||||
if (callback->callbackID < 0 ||
|
||||
!remoteRelayDomainEventCheckACL(callback->client, conn, dom))
|
||||
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);
|
||||
|
||||
|
@ -244,20 +248,22 @@ remoteRelayDomainEventRTCChange(virConnectPtr conn,
|
|||
long long offset,
|
||||
void *opaque)
|
||||
{
|
||||
virNetServerClientPtr client = opaque;
|
||||
daemonClientEventCallbackPtr callback = opaque;
|
||||
remote_domain_event_rtc_change_msg data;
|
||||
|
||||
if (!client || !remoteRelayDomainEventCheckACL(client, conn, dom))
|
||||
if (callback->callbackID < 0 ||
|
||||
!remoteRelayDomainEventCheckACL(callback->client, conn, dom))
|
||||
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);
|
||||
|
||||
|
@ -271,20 +277,22 @@ remoteRelayDomainEventWatchdog(virConnectPtr conn,
|
|||
int action,
|
||||
void *opaque)
|
||||
{
|
||||
virNetServerClientPtr client = opaque;
|
||||
daemonClientEventCallbackPtr callback = opaque;
|
||||
remote_domain_event_watchdog_msg data;
|
||||
|
||||
if (!client || !remoteRelayDomainEventCheckACL(client, conn, dom))
|
||||
if (callback->callbackID < 0 ||
|
||||
!remoteRelayDomainEventCheckACL(callback->client, conn, dom))
|
||||
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);
|
||||
|
||||
|
@ -300,13 +308,16 @@ remoteRelayDomainEventIOError(virConnectPtr conn,
|
|||
int action,
|
||||
void *opaque)
|
||||
{
|
||||
virNetServerClientPtr client = opaque;
|
||||
daemonClientEventCallbackPtr callback = opaque;
|
||||
remote_domain_event_io_error_msg data;
|
||||
|
||||
if (!client || !remoteRelayDomainEventCheckACL(client, conn, dom))
|
||||
if (callback->callbackID < 0 ||
|
||||
!remoteRelayDomainEventCheckACL(callback->client, conn, dom))
|
||||
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));
|
||||
|
@ -316,7 +327,7 @@ remoteRelayDomainEventIOError(virConnectPtr conn,
|
|||
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);
|
||||
|
||||
|
@ -337,14 +348,16 @@ remoteRelayDomainEventIOErrorReason(virConnectPtr conn,
|
|||
const char *reason,
|
||||
void *opaque)
|
||||
{
|
||||
virNetServerClientPtr client = opaque;
|
||||
daemonClientEventCallbackPtr callback = opaque;
|
||||
remote_domain_event_io_error_reason_msg data;
|
||||
|
||||
if (!client || !remoteRelayDomainEventCheckACL(client, conn, dom))
|
||||
if (callback->callbackID < 0 ||
|
||||
!remoteRelayDomainEventCheckACL(callback->client, conn, dom))
|
||||
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));
|
||||
|
@ -356,7 +369,7 @@ remoteRelayDomainEventIOErrorReason(virConnectPtr conn,
|
|||
|
||||
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);
|
||||
|
||||
|
@ -380,17 +393,19 @@ remoteRelayDomainEventGraphics(virConnectPtr conn,
|
|||
virDomainEventGraphicsSubjectPtr subject,
|
||||
void *opaque)
|
||||
{
|
||||
virNetServerClientPtr client = opaque;
|
||||
daemonClientEventCallbackPtr callback = opaque;
|
||||
remote_domain_event_graphics_msg data;
|
||||
size_t i;
|
||||
|
||||
if (!client || !remoteRelayDomainEventCheckACL(client, conn, dom))
|
||||
if (callback->callbackID < 0 ||
|
||||
!remoteRelayDomainEventCheckACL(callback->client, conn, dom))
|
||||
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++) {
|
||||
|
@ -420,7 +435,7 @@ remoteRelayDomainEventGraphics(virConnectPtr conn,
|
|||
}
|
||||
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);
|
||||
|
||||
|
@ -450,14 +465,15 @@ remoteRelayDomainEventBlockJob(virConnectPtr conn,
|
|||
int status,
|
||||
void *opaque)
|
||||
{
|
||||
virNetServerClientPtr client = opaque;
|
||||
daemonClientEventCallbackPtr callback = opaque;
|
||||
remote_domain_event_block_job_msg data;
|
||||
|
||||
if (!client || !remoteRelayDomainEventCheckACL(client, conn, dom))
|
||||
if (callback->callbackID < 0 ||
|
||||
!remoteRelayDomainEventCheckACL(callback->client, conn, dom))
|
||||
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));
|
||||
|
@ -467,7 +483,7 @@ remoteRelayDomainEventBlockJob(virConnectPtr conn,
|
|||
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);
|
||||
|
||||
|
@ -483,19 +499,21 @@ remoteRelayDomainEventControlError(virConnectPtr conn,
|
|||
virDomainPtr dom,
|
||||
void *opaque)
|
||||
{
|
||||
virNetServerClientPtr client = opaque;
|
||||
daemonClientEventCallbackPtr callback = opaque;
|
||||
remote_domain_event_control_error_msg data;
|
||||
|
||||
if (!client || !remoteRelayDomainEventCheckACL(client, conn, dom))
|
||||
if (callback->callbackID < 0 ||
|
||||
!remoteRelayDomainEventCheckACL(callback->client, conn, dom))
|
||||
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);
|
||||
|
||||
|
@ -512,15 +530,17 @@ remoteRelayDomainEventDiskChange(virConnectPtr conn,
|
|||
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 || !remoteRelayDomainEventCheckACL(client, conn, dom))
|
||||
if (callback->callbackID < 0 ||
|
||||
!remoteRelayDomainEventCheckACL(callback->client, conn, dom))
|
||||
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));
|
||||
|
@ -542,7 +562,7 @@ remoteRelayDomainEventDiskChange(virConnectPtr conn,
|
|||
|
||||
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);
|
||||
|
||||
|
@ -562,14 +582,15 @@ remoteRelayDomainEventTrayChange(virConnectPtr conn,
|
|||
int reason,
|
||||
void *opaque)
|
||||
{
|
||||
virNetServerClientPtr client = opaque;
|
||||
daemonClientEventCallbackPtr callback = opaque;
|
||||
remote_domain_event_tray_change_msg data;
|
||||
|
||||
if (!client || !remoteRelayDomainEventCheckACL(client, conn, dom))
|
||||
if (callback->callbackID < 0 ||
|
||||
!remoteRelayDomainEventCheckACL(callback->client, conn, dom))
|
||||
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));
|
||||
|
@ -580,7 +601,7 @@ remoteRelayDomainEventTrayChange(virConnectPtr conn,
|
|||
|
||||
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);
|
||||
|
||||
|
@ -593,19 +614,21 @@ remoteRelayDomainEventPMWakeup(virConnectPtr conn,
|
|||
int reason ATTRIBUTE_UNUSED,
|
||||
void *opaque)
|
||||
{
|
||||
virNetServerClientPtr client = opaque;
|
||||
daemonClientEventCallbackPtr callback = opaque;
|
||||
remote_domain_event_pmwakeup_msg data;
|
||||
|
||||
if (!client || !remoteRelayDomainEventCheckACL(client, conn, dom))
|
||||
if (callback->callbackID < 0 ||
|
||||
!remoteRelayDomainEventCheckACL(callback->client, conn, dom))
|
||||
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);
|
||||
|
||||
|
@ -618,19 +641,21 @@ remoteRelayDomainEventPMSuspend(virConnectPtr conn,
|
|||
int reason ATTRIBUTE_UNUSED,
|
||||
void *opaque)
|
||||
{
|
||||
virNetServerClientPtr client = opaque;
|
||||
daemonClientEventCallbackPtr callback = opaque;
|
||||
remote_domain_event_pmsuspend_msg data;
|
||||
|
||||
if (!client || !remoteRelayDomainEventCheckACL(client, conn, dom))
|
||||
if (callback->callbackID < 0 ||
|
||||
!remoteRelayDomainEventCheckACL(callback->client, conn, dom))
|
||||
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);
|
||||
|
||||
|
@ -643,20 +668,22 @@ remoteRelayDomainEventBalloonChange(virConnectPtr conn,
|
|||
unsigned long long actual,
|
||||
void *opaque)
|
||||
{
|
||||
virNetServerClientPtr client = opaque;
|
||||
daemonClientEventCallbackPtr callback = opaque;
|
||||
remote_domain_event_balloon_change_msg data;
|
||||
|
||||
if (!client || !remoteRelayDomainEventCheckACL(client, conn, dom))
|
||||
if (callback->callbackID < 0 ||
|
||||
!remoteRelayDomainEventCheckACL(callback->client, conn, dom))
|
||||
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);
|
||||
|
||||
|
@ -670,19 +697,21 @@ remoteRelayDomainEventPMSuspendDisk(virConnectPtr conn,
|
|||
int reason ATTRIBUTE_UNUSED,
|
||||
void *opaque)
|
||||
{
|
||||
virNetServerClientPtr client = opaque;
|
||||
daemonClientEventCallbackPtr callback = opaque;
|
||||
remote_domain_event_pmsuspend_disk_msg data;
|
||||
|
||||
if (!client || !remoteRelayDomainEventCheckACL(client, conn, dom))
|
||||
if (callback->callbackID < 0 ||
|
||||
!remoteRelayDomainEventCheckACL(callback->client, conn, dom))
|
||||
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);
|
||||
|
||||
|
@ -695,14 +724,15 @@ remoteRelayDomainEventDeviceRemoved(virConnectPtr conn,
|
|||
const char *devAlias,
|
||||
void *opaque)
|
||||
{
|
||||
virNetServerClientPtr client = opaque;
|
||||
daemonClientEventCallbackPtr callback = opaque;
|
||||
remote_domain_event_device_removed_msg data;
|
||||
|
||||
if (!client || !remoteRelayDomainEventCheckACL(client, conn, dom))
|
||||
if (callback->callbackID < 0 ||
|
||||
!remoteRelayDomainEventCheckACL(callback->client, conn, dom))
|
||||
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));
|
||||
|
@ -712,7 +742,7 @@ remoteRelayDomainEventDeviceRemoved(virConnectPtr conn,
|
|||
|
||||
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);
|
||||
|
@ -797,14 +827,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;
|
||||
|
@ -843,7 +878,6 @@ void *remoteClientInitHook(virNetServerClientPtr client,
|
|||
void *opaque ATTRIBUTE_UNUSED)
|
||||
{
|
||||
struct daemonClientPrivate *priv;
|
||||
size_t i;
|
||||
|
||||
if (VIR_ALLOC(priv) < 0)
|
||||
return NULL;
|
||||
|
@ -854,9 +888,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;
|
||||
}
|
||||
|
@ -3220,13 +3251,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);
|
||||
|
||||
|
@ -3237,23 +3270,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);
|
||||
|
@ -3262,12 +3313,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);
|
||||
|
||||
|
@ -3278,16 +3331,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;
|
||||
|
||||
|
@ -3409,13 +3471,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);
|
||||
|
||||
|
@ -3432,23 +3496,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);
|
||||
|
@ -3458,13 +3540,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);
|
||||
|
||||
|
@ -3481,16 +3564,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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue