]> git.ipfire.org Git - thirdparty/libvirt.git/commit
event: properly filter count of remaining events
authorEric Blake <eblake@redhat.com>
Fri, 3 Jan 2014 21:50:15 +0000 (14:50 -0700)
committerEric Blake <eblake@redhat.com>
Tue, 7 Jan 2014 17:53:24 +0000 (10:53 -0700)
commit995b2ebab625a6b5b2efb17576530cc79f24055f
tree91d9cbf23eaf9c9ca3412b466a50ab37f9fa4b82
parent538daf7f3a7090d6a7ec94d11c17e509eceb642c
event: properly filter count of remaining events

On the surface, this sequence of API calls should succeed:

id1 = virConnectDomainEventRegisterAny(..., VIR_DOMAIN_EVENT_ID_LIFECYCLE,...);
id2 = virConnectDomainEventRegisterAny(..., VIR_DOMAIN_EVENT_ID_RTC_CHANGE,...);
virConnectDomainEventDeregisterAny(id1);
id1 = virConnectDomainEventRegisterAny(..., VIR_DOMAIN_EVENT_ID_LIFECYCLE,...);

And for test:///default, it does.  But for qemu:///system, it fails:
libvirt: XML-RPC error : internal error: domain event 0 already registered

Looking closer, the bug is caused by miscommunication between
the object event engine and the client side of the remote driver.
In our implementation, we set up a single server-side event per
eventID, then the client side replicates that one event to all
callbacks that have been registered client side.  To know when
to turn the server side eventID on or off, the client side must
track how many events for the same eventID have been registered.
But while our code was filtering by eventID on event registration,
it did not filter on event deregistration.  So the above API calls
resulted in the deregister returning 1 instead of 0, so no RPC
deregister was issued, and the final register detects on the
server side that the server is already handling eventID 0.

Unfortunately, since the problem is only observable on remote
connections, it's not possible to enhance objecteventtest to
expose the semantics using only public API entry points.

* src/conf/object_event.c (virObjectEventCallbackListCount): New
function.
(virObjectEventCallbackListAddID)
(virObjectEventCallbackListRemoveID)
(virObjectEventCallbackListMarkDeleteID): Use it.

Signed-off-by: Eric Blake <eblake@redhat.com>
src/conf/object_event.c