Suppose that we have two hosts A and B, migrate VM from A to B by virDomainMigrateToURI2. 1.qemuProcessLaunch was been called on host B with VIR_QEMU_PROCESS_START_AUTODESTROY flag, and VM's object reference was been increased in virCloseCallbacksSet called by qemuProcessAutoDestroyAdd. 2. Restart host A's libvirtd service to interrupt migration job, virCloseCallbacksRun was been called on host B by qemuConnectClose, VM's virDriverCloseDef struct was been removed from connection callback list before execute qemuProcessAutoDestroy callback function. 3. Then qemuProcessAutoDestroy was been called on host B to destroy the transient VM. -->qemuProcessAutoDestroy -->qemuProcessStop -->qemuProcessAutoDestroyRemove -->virCloseCallbacksUnset At last, VM's object reference has been decreased in virCloseCallbacksUnset expectably, however VM's virDriverCloseDef struct cannot be found in callback list[2] lead to VM's object leak. Signed-off-by: Wang King <king.wang@xxxxxxxxxx> --- src/util/virclosecallbacks.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/util/virclosecallbacks.c b/src/util/virclosecallbacks.c index 1fa9596..633b22c 100644 --- a/src/util/virclosecallbacks.c +++ b/src/util/virclosecallbacks.c @@ -331,17 +331,9 @@ virCloseCallbacksRun(virCloseCallbacksPtr closeCallbacks, virObjectLock(closeCallbacks); list = virCloseCallbacksGetForConn(closeCallbacks, conn); - if (!list) { - virObjectLock(closeCallbacks); + virObjectLock(closeCallbacks); + if (!list) return; - } - - for (i = 0; i < list->nentries; i++) { - char uuidstr[VIR_UUID_STRING_BUFLEN]; - virUUIDFormat(list->entries[i].uuid, uuidstr); - virHashRemoveEntry(closeCallbacks->list, uuidstr); - } - virObjectUnlock(closeCallbacks); for (i = 0; i < list->nentries; i++) { virDomainObjPtr vm; @@ -358,6 +350,15 @@ virCloseCallbacksRun(virCloseCallbacksPtr closeCallbacks, if (vm) virObjectUnlock(vm); } + + virObjectLock(closeCallbacks); + for (i = 0; i < list->nentries; i++) { + char uuidstr[VIR_UUID_STRING_BUFLEN]; + virUUIDFormat(list->entries[i].uuid, uuidstr); + virHashRemoveEntry(closeCallbacks->list, uuidstr); + } + virObjectUnlock(closeCallbacks); + VIR_FREE(list->entries); VIR_FREE(list); } -- 2.8.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list