[libvirt] [PATCHv2 2/3] util: fix domain object leaks on closecallbacks

Wang King king.wang at huawei.com
Tue Jan 10 06:23:50 UTC 2017


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 at huawei.com>
---
 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





More information about the libvir-list mailing list