• E
    event: properly filter count of remaining events · 995b2eba
    Eric Blake 提交于
    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: NEric Blake <eblake@redhat.com>
    995b2eba
object_event.c 25.1 KB