File 3c89868c-libxl-lock-after-ListRemove.patch of Package libvirt.8367

commit 3c89868c5fef3d0cfbc40d0185447d13a6242620
Author: Jim Fehlig <jfehlig@suse.com>
Date:   Fri Mar 16 15:15:07 2018 -0600

    libxl: lock virDomainObj after ListRemove
    
    Most libxl driver API use the pattern of lock and add a ref to
    virDomainObj, perform API, then decrement ref and unlock in
    virDomainEndAPI. In some cases the API may call
    virDomainObjListRemove, which unlocks the virDomainObj. Relock
    the object in such cases so EndAPI is called with a locked object.
    
    Signed-off-by: Jim Fehlig <jfehlig@suse.com>
    Reviewed-by: John Ferlan <jferlan@redhat.com>

Index: libvirt-4.0.0/src/libxl/libxl_driver.c
===================================================================
--- libvirt-4.0.0.orig/src/libxl/libxl_driver.c
+++ libvirt-4.0.0/src/libxl/libxl_driver.c
@@ -1058,7 +1058,7 @@ libxlDomainCreateXML(virConnectPtr conn,
     if (libxlDomainObjBeginJob(driver, vm, LIBXL_JOB_MODIFY) < 0) {
         if (!vm->persistent) {
             virDomainObjListRemove(driver->domains, vm);
-            vm = NULL;
+            virObjectLock(vm);
         }
         goto cleanup;
     }
@@ -1067,7 +1067,7 @@ libxlDomainCreateXML(virConnectPtr conn,
                          (flags & VIR_DOMAIN_START_PAUSED) != 0) < 0) {
         if (!vm->persistent) {
             virDomainObjListRemove(driver->domains, vm);
-            vm = NULL;
+            virObjectLock(vm);
             goto cleanup;
         }
         goto endjob;
@@ -1419,8 +1419,10 @@ libxlDomainDestroyFlags(virDomainPtr dom
                                      VIR_DOMAIN_EVENT_STOPPED_DESTROYED);
 
     libxlDomainCleanup(driver, vm);
-    if (!vm->persistent)
+    if (!vm->persistent) {
         virDomainObjListRemove(driver->domains, vm);
+        virObjectLock(vm);
+    }
 
     ret = 0;
 
@@ -1824,7 +1826,7 @@ libxlDomainSaveFlags(virDomainPtr dom, c
  cleanup:
     if (remove_dom && vm) {
         virDomainObjListRemove(driver->domains, vm);
-        vm = NULL;
+        virObjectLock(vm);
     }
     virDomainObjEndAPI(&vm);
     return ret;
@@ -1879,7 +1881,7 @@ libxlDomainRestoreFlags(virConnectPtr co
     if (libxlDomainObjBeginJob(driver, vm, LIBXL_JOB_MODIFY) < 0) {
         if (!vm->persistent) {
             virDomainObjListRemove(driver->domains, vm);
-            vm = NULL;
+            virObjectLock(vm);
         }
         goto cleanup;
     }
@@ -1887,8 +1889,10 @@ libxlDomainRestoreFlags(virConnectPtr co
     ret = libxlDomainStartRestore(driver, vm,
                                   (flags & VIR_DOMAIN_SAVE_PAUSED) != 0,
                                   fd, hdr.version);
-    if (ret < 0 && !vm->persistent)
+    if (ret < 0 && !vm->persistent) {
         virDomainObjListRemove(driver->domains, vm);
+        virObjectLock(vm);
+    }
 
     libxlDomainObjEndJob(driver, vm);
 
@@ -1997,7 +2001,7 @@ libxlDomainCoreDump(virDomainPtr dom, co
  cleanup:
     if (remove_dom && vm) {
         virDomainObjListRemove(driver->domains, vm);
-        vm = NULL;
+        virObjectLock(vm);
     }
     virDomainObjEndAPI(&vm);
     if (event)
@@ -2058,7 +2062,7 @@ libxlDomainManagedSave(virDomainPtr dom,
  cleanup:
     if (remove_dom && vm) {
         virDomainObjListRemove(driver->domains, vm);
-        vm = NULL;
+        virObjectLock(vm);
     }
     virDomainObjEndAPI(&vm);
     VIR_FREE(name);
@@ -2882,7 +2886,7 @@ libxlDomainUndefineFlags(virDomainPtr do
         vm->persistent = 0;
     } else {
         virDomainObjListRemove(driver->domains, vm);
-        vm = NULL;
+        virObjectLock(vm);
     }
 
     ret = 0;
Index: libvirt-4.0.0/src/libxl/libxl_migration.c
===================================================================
--- libvirt-4.0.0.orig/src/libxl/libxl_migration.c
+++ libvirt-4.0.0/src/libxl/libxl_migration.c
@@ -299,7 +299,7 @@ libxlDoMigrateReceive(void *opaque)
  cleanup:
     if (remove_dom) {
         virDomainObjListRemove(driver->domains, vm);
-        vm = NULL;
+        virObjectLock(vm);
     }
     virDomainObjEndAPI(&vm);
 }
@@ -1336,8 +1336,11 @@ libxlDomainMigrationFinish(virConnectPtr
                              VIR_DOMAIN_SHUTOFF_FAILED);
         event = virDomainEventLifecycleNewFromObj(vm, VIR_DOMAIN_EVENT_STOPPED,
                                          VIR_DOMAIN_EVENT_STOPPED_FAILED);
-        if (!vm->persistent)
+        if (!vm->persistent) {
             virDomainObjListRemove(driver->domains, vm);
+            /* Caller passed a locked vm and expects the same on return */
+            virObjectLock(vm);
+        }
     }
 
     if (event)