[Libvir] PATCH: Fix crash in cleanup when VM creation fails

Daniel P. Berrange berrange at redhat.com
Mon Jul 23 19:55:52 UTC 2007


If using the 'virDomainCreateLinux' call to create a VM, a so called 
'transient' domain will be created - ie one without any config file.
There is special code in the qemudShutdownVMDaemon method to cleanup
the resources associated with such domains, in particuarly free'ing 
the struct qemud_vm  object. Unfortunately in the virDomainCreateLinux
codepath this is a problem, because we still need the 'struct qemud_vm'
object in certain edge cases, and so the caller has to free it. We
currently have a double free() in that scenario. This patch removes
the call to qemudFreeVMDaemon from qemudShutdownVMDaemon. Instead it
is now always the caller's responsibility to cleanup after transient
domains.


 qemu_driver.c |   39 ++++++++++++++++++++-------------------
 1 file changed, 20 insertions(+), 19 deletions(-)


Dan.
-- 
|=- Red Hat, Engineering, Emerging Technologies, Boston.  +1 978 392 2496 -=|
|=-           Perl modules: http://search.cpan.org/~danberr/              -=|
|=-               Projects: http://freshmeat.net/~danielpb/               -=|
|=-  GnuPG: 7D3B9505   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505  -=| 
-------------- next part --------------
Index: src/qemu_driver.c
===================================================================
RCS file: /data/cvs/libvirt/src/qemu_driver.c,v
retrieving revision 1.10
diff -u -p -r1.10 qemu_driver.c
--- src/qemu_driver.c	23 Jul 2007 18:00:33 -0000	1.10
+++ src/qemu_driver.c	23 Jul 2007 19:39:07 -0000
@@ -92,9 +92,9 @@ static int qemudStartVMDaemon(virConnect
                               struct qemud_driver *driver,
                               struct qemud_vm *vm);
 
-static int qemudShutdownVMDaemon(virConnectPtr conn,
-                                 struct qemud_driver *driver,
-                                 struct qemud_vm *vm);
+static void qemudShutdownVMDaemon(virConnectPtr conn,
+                                  struct qemud_driver *driver,
+                                  struct qemud_vm *vm);
 
 static int qemudStartNetworkDaemon(virConnectPtr conn,
                                    struct qemud_driver *driver,
@@ -277,6 +277,8 @@ qemudShutdown(void) {
         struct qemud_vm *next = vm->next;
         if (qemudIsActiveVM(vm))
             qemudShutdownVMDaemon(NULL, qemu_driver, vm);
+        if (!vm->configFile[0])
+            qemudRemoveInactiveVM(qemu_driver, vm);
         vm = next;
     }
     
@@ -729,10 +731,10 @@ static int qemudVMData(struct qemud_driv
 }
 
 
-static int qemudShutdownVMDaemon(virConnectPtr conn ATTRIBUTE_UNUSED,
-                                 struct qemud_driver *driver, struct qemud_vm *vm) {
+static void qemudShutdownVMDaemon(virConnectPtr conn ATTRIBUTE_UNUSED,
+                                  struct qemud_driver *driver, struct qemud_vm *vm) {
     if (!qemudIsActiveVM(vm))
-        return 0;
+        return;
 
     qemudLog(QEMUD_INFO, "Shutting down VM '%s'", vm->def->name);
 
@@ -774,24 +776,22 @@ static int qemudShutdownVMDaemon(virConn
 
     driver->nactivevms--;
     driver->ninactivevms++;
-
-    if (!vm->configFile[0])
-        qemudRemoveInactiveVM(driver, vm);
-
-    return 0;
 }
 
 static int qemudDispatchVMLog(struct qemud_driver *driver, struct qemud_vm *vm, int fd) {
-    if (qemudVMData(driver, vm, fd) < 0)
-        if (qemudShutdownVMDaemon(NULL, driver, vm) < 0)
-            return -1;
+    if (qemudVMData(driver, vm, fd) < 0) {
+        qemudShutdownVMDaemon(NULL, driver, vm);
+        if (!vm->configFile[0])
+            qemudRemoveInactiveVM(driver, vm);
+    }
     return 0;
 }
 
 static int qemudDispatchVMFailure(struct qemud_driver *driver, struct qemud_vm *vm,
                                   int fd ATTRIBUTE_UNUSED) {
-    if (qemudShutdownVMDaemon(NULL, driver, vm) < 0)
-        return -1;
+    qemudShutdownVMDaemon(NULL, driver, vm);
+    if (!vm->configFile[0])
+        qemudRemoveInactiveVM(driver, vm);
     return 0;
 }
 
@@ -1844,7 +1844,6 @@ static int qemudDomainResume(virDomainPt
 static int qemudDomainDestroy(virDomainPtr dom) {
     struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
     struct qemud_vm *vm = qemudFindVMByID(driver, dom->id);
-    int ret;
 
     if (!vm) {
         qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
@@ -1852,9 +1851,11 @@ static int qemudDomainDestroy(virDomainP
         return -1;
     }
 
-    ret = qemudShutdownVMDaemon(dom->conn, driver, vm);
+    qemudShutdownVMDaemon(dom->conn, driver, vm);
+    if (!vm->configFile[0])
+        qemudRemoveInactiveVM(driver, vm);
     virFreeDomain(dom->conn, dom);
-    return ret;
+    return 0;
 }
 
 


More information about the libvir-list mailing list