On 03/04/2011 06:03 PM, Eric Blake wrote:
I think the real reason for the deadlock is that:
qemudDomainSaveFlag holds the domain lock while it calls
qemuDomainEventQueue, which requests the event loop lock
the event loop thread holds the event loop lock, and can make several
different callbacks that can result in requesting a domain lock
I counted 29 callers of qemuDomainEventQueue; the majority of those were
in situations where the domain lock had already been dropped (in fact,
it makes sense to generate the event while you own the domain, but wait
to fire it off until after you are done with the domain).
But the rest could probably use a helper
method that increases the vm ref count, unlocks the domain lock, fires
the event, grabs the domain lock, reduces the vm ref count, and checks
that the domain is still active.
Or better yet, a helper function qemuDomainEventQueueLocked, which takes
a locked vm as an additional parameter, and which stashes the event in
the domain object, then teach virDomainObjUnlock that if an event is
stashed in the domain, to call virDomainEventQueuePush then (that is,
instead of worrying about unlocking and relocking in place, we instead
delay firing the event until the point where we know there is no longer
a domain lock).
--
Eric Blake eblake(a)redhat.com +1-801-349-2682
Libvirt virtualization library
http://libvirt.org