]> git.ipfire.org Git - thirdparty/libvirt.git/commit
util: Fix domain object leaks on closecallbacks
authorJohn Ferlan <jferlan@redhat.com>
Sat, 21 Jan 2017 17:59:14 +0000 (12:59 -0500)
committerJohn Ferlan <jferlan@redhat.com>
Sat, 4 Feb 2017 00:38:39 +0000 (19:38 -0500)
commit48ad600916bc239fcb549b3d5dc4a1a7d49ba6c3
treef13aa33a294cdfd3db832ba85101761328cf5d76
parentaed0850e394150737902fa6d30bdfbe0ad324e08
util: Fix domain object leaks on closecallbacks

Originally/discovered proposed by "Wang King <king.wang@huawei.com>"

When the virCloseCallbacksSet is first called, it increments the refcnt
on the domain object to ensure it doesn't get deleted before the callback
is called. The refcnt would be decremented in virCloseCallbacksUnset once
the entry is removed from the closeCallbacks has table.

When (mostly) normal shutdown occurs, the qemuProcessStop will end up
calling qemuProcessAutoDestroyRemove and will remove the callback from
the list and hash table normally and decrement the refcnt.

However, when qemuConnectClose calls virCloseCallbacksRun, it will scan
the (locked) closeCallbacks list for matching domain and callback function.
If an entry is found, it will be removed from the closeCallbacks list and
placed into a lookaside list to be processed when the closeCallbacks lock
is dropped. The callback function (e.g. qemuProcessAutoDestroy) is called
and will run qemuProcessStop. That code will fail to find the callback
in the list when qemuProcessAutoDestroyRemove is called and thus not decrement
the domain refcnt. Instead since the entry isn't found the code will just
return (mostly) harmlessly.

This patch will resolve the issue by taking another ref during the
search UUID process during virCloseCallackRun, decrementing the refcnt
taken by virCloseCallbacksSet, calling the callback routine and returning
overwriting the vm (since it could return NULL). Finally, it will call the
virDomainObjEndAPI to lower the refcnt and remove the lock taken during
the search UUID processing. This may cause the vm to be destroyed.
src/util/virclosecallbacks.c