c401cc
From cbbb456d6f40eb025e2458463228236bdd9fe0a5 Mon Sep 17 00:00:00 2001
c401cc
Message-Id: <cbbb456d6f40eb025e2458463228236bdd9fe0a5.1386348947.git.jdenemar@redhat.com>
c401cc
From: Michal Privoznik <mprivozn@redhat.com>
c401cc
Date: Tue, 3 Dec 2013 15:31:39 +0100
c401cc
Subject: [PATCH] daemon: Run virStateCleanup conditionally
c401cc
MIME-Version: 1.0
c401cc
Content-Type: text/plain; charset=UTF-8
c401cc
Content-Transfer-Encoding: 8bit
c401cc
c401cc
https://bugzilla.redhat.com/show_bug.cgi?id=1033061
c401cc
c401cc
Currently, initialization of drivers is done in a separate thread. This
c401cc
is done for several reasons: a driver that is initialized may require
c401cc
running event loop, it may take ages to initialize driver (e.g. due to
c401cc
autostarting domains). While the thread is spawn and run, the main()
c401cc
continues its execution. However, if something goes bad, or the event
c401cc
loop is just exited (e.g. due to a --timeout or SIGINT) we try to
c401cc
cleanup all the drivers. So we have two threads running Initialize() and
c401cc
Cleanup() concurrently. This may result in accessing stale pointers -
c401cc
e.g. netcf driver will free() itself in stateCleanup callback, while the
c401cc
init thread may come, open a dummy connection in order to autostart some
c401cc
domains and voilĂ : do_open() iterates over interface drivers and
c401cc
accesses stale netcf driver.
c401cc
c401cc
The fix consists in not running stateCleanup if the init thread is still
c401cc
running.
c401cc
c401cc
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
c401cc
(cherry picked from commit a602e90bc1e0743d7e801b730e303674d24fa89f)
c401cc
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
c401cc
---
c401cc
 daemon/libvirtd.c | 7 ++++++-
c401cc
 1 file changed, 6 insertions(+), 1 deletion(-)
c401cc
c401cc
diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c
c401cc
index 808bd4b..8576bfe 100644
c401cc
--- a/daemon/libvirtd.c
c401cc
+++ b/daemon/libvirtd.c
c401cc
@@ -108,6 +108,8 @@ virNetServerProgramPtr remoteProgram = NULL;
c401cc
 virNetServerProgramPtr qemuProgram = NULL;
c401cc
 virNetServerProgramPtr lxcProgram = NULL;
c401cc
 
c401cc
+volatile bool driversInitialized = false;
c401cc
+
c401cc
 enum {
c401cc
     VIR_DAEMON_ERR_NONE = 0,
c401cc
     VIR_DAEMON_ERR_PIDFILE,
c401cc
@@ -912,6 +914,8 @@ static void daemonRunStateInit(void *opaque)
c401cc
         goto cleanup;
c401cc
     }
c401cc
 
c401cc
+    driversInitialized = true;
c401cc
+
c401cc
 #ifdef HAVE_DBUS
c401cc
     /* Tie the non-priviledged libvirtd to the session/shutdown lifecycle */
c401cc
     if (!virNetServerIsPrivileged(srv)) {
c401cc
@@ -1546,7 +1550,8 @@ cleanup:
c401cc
 
c401cc
     daemonConfigFree(config);
c401cc
 
c401cc
-    virStateCleanup();
c401cc
+    if (driversInitialized)
c401cc
+        virStateCleanup();
c401cc
 
c401cc
     return ret;
c401cc
 }
c401cc
-- 
c401cc
1.8.4.5
c401cc