|
|
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 |
|