[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCH] fix libvirtd crash in qemu driver



I noticed that the following sequence of events would crash libvirtd
when using the qemu driver:
  (1) establish a connection that successfully registers for domain  
      events (either of the event-test programs will do, though the
      python one is currently broken -- another patch on the way for 
      that)
  (2) close this connection
  (3) open another connection
  (4) do something (like start a domain) that issues a domain event

The problem is that qemudClose() isn't removing registered domain event
callbacks when the connection closes.  This patch does that, and fixes
the crash.

Dave


 domain_event.c |   38 ++++++++++++++++++++++++++++++++++++++
 domain_event.h |    3 +++
 qemu_driver.c  |    5 ++++-
 3 files changed, 45 insertions(+), 1 deletion(-)

commit d70494a2c2ebdf985943020cc84f22713904719a
Author: David Lively <dlively virtualiron com>
Date:   Thu Nov 20 16:34:32 2008 -0500

    vi-patch: qemu-driver-close-fix
    
    Fix a bug in the QEMU driver causing libvirtd crashes.  When closing
    a connection, remove the DomainEvent callbacks associated with
    the connection.

diff --git a/src/domain_event.c b/src/domain_event.c
index 85ca9b7..d5f5415 100644
--- a/src/domain_event.c
+++ b/src/domain_event.c
@@ -88,6 +88,44 @@ virDomainEventCallbackListRemove(virConnectPtr conn,
 }
 
 /**
+ * virDomainEventCallbackListRemoveConn:
+ * @conn: pointer to the connection
+ * @cbList: the list
+ *
+ * Internal function to remove all of a given connection's callback
+ * from a virDomainEventCallbackListPtr
+ */
+int
+virDomainEventCallbackListRemoveConn(virConnectPtr conn,
+                                     virDomainEventCallbackListPtr cbList)
+{
+    int old_count = cbList->count;
+    int i;
+    for (i = 0 ; i < cbList->count ; i++) {
+        if(cbList->callbacks[i]->conn == conn) {
+            virFreeCallback freecb = cbList->callbacks[i]->freecb;
+            if (freecb)
+                (*freecb)(cbList->callbacks[i]->opaque);
+            virUnrefConnect(cbList->callbacks[i]->conn);
+            VIR_FREE(cbList->callbacks[i]);
+
+            if (i < (cbList->count - 1))
+                memmove(cbList->callbacks + i,
+                        cbList->callbacks + i + 1,
+                        sizeof(*(cbList->callbacks)) *
+                                (cbList->count - (i + 1)));
+            cbList->count--;
+            i--;
+        }
+    }
+    if (cbList->count < old_count &&
+        VIR_REALLOC_N(cbList->callbacks, cbList->count) < 0) {
+        ; /* Failure to reduce memory allocation isn't fatal */
+    }
+    return 0;
+}
+
+/**
  * virDomainEventCallbackListAdd:
  * @conn: pointer to the connection
  * @cbList: the list
diff --git a/src/domain_event.h b/src/domain_event.h
index cfec1e1..454d084 100644
--- a/src/domain_event.h
+++ b/src/domain_event.h
@@ -55,6 +55,9 @@ int virDomainEventCallbackListRemove(virConnectPtr conn,
                                      virDomainEventCallbackListPtr cbList,
                                      virConnectDomainEventCallback callback);
 
+int virDomainEventCallbackListRemoveConn(virConnectPtr conn,
+					 virDomainEventCallbackListPtr cbList);
+
 /**
  * Dispatching domain events that come in while
  * in a call / response rpc
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index 5ad60f1..7bec116 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -1235,7 +1235,10 @@ static virDrvOpenStatus qemudOpen(virConnectPtr conn,
 }
 
 static int qemudClose(virConnectPtr conn) {
-    /*struct qemud_driver *driver = (struct qemud_driver *)conn->privateData;*/
+    struct qemud_driver *driver = (struct qemud_driver *)conn->privateData;
+
+    /* Get rid of callbacks registered for this conn */
+    virDomainEventCallbackListRemoveConn(conn, driver->domainEventCallbacks);
 
     conn->privateData = NULL;
 

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]