82 lines
3.0 KiB
Diff
82 lines
3.0 KiB
Diff
From ffaa244c76d7baeccab1846b1cae8ca057718f03 Mon Sep 17 00:00:00 2001
|
|
From: huangkai <huangkai101@huawei.com>
|
|
Date: Sun, 14 Aug 2022 17:32:00 +0800
|
|
Subject: [PATCH 18/22] remote_daemon: Don't run virStateCleanup() if
|
|
virStateReload() is still running
|
|
|
|
When a SIGHUP is received a thread is spawned that runs
|
|
virStateReload(). However, if SIGINT is received while the former
|
|
thread is still running then we may get into problematic
|
|
situation: the cleanup code in main() sees drivers initialized
|
|
and thus calls virStateCleanup(). So now we have two threads, one
|
|
running virStateReload() the other virStateCleanup(). In this
|
|
situation it's very likely that a race condition occurs and
|
|
either of threads causes SIGSEGV.
|
|
|
|
To fix this, unmark drivers as initialized in the
|
|
virStateReload() thread for the time the function runs.
|
|
|
|
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2075837
|
|
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
|
|
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
|
|
---
|
|
src/remote/remote_daemon.c | 12 +++++++-----
|
|
1 file changed, 7 insertions(+), 5 deletions(-)
|
|
|
|
diff --git a/src/remote/remote_daemon.c b/src/remote/remote_daemon.c
|
|
index a1552800e9..cb93e39413 100644
|
|
--- a/src/remote/remote_daemon.c
|
|
+++ b/src/remote/remote_daemon.c
|
|
@@ -77,7 +77,7 @@ virNetSASLContextPtr saslCtxt = NULL;
|
|
virNetServerProgramPtr remoteProgram = NULL;
|
|
virNetServerProgramPtr qemuProgram = NULL;
|
|
|
|
-volatile bool driversInitialized = false;
|
|
+volatile gint driversInitialized = 0;
|
|
|
|
static void daemonErrorHandler(void *opaque G_GNUC_UNUSED,
|
|
virErrorPtr err G_GNUC_UNUSED)
|
|
@@ -469,7 +469,7 @@ static void daemonReloadHandler(virNetDaemonPtr dmn G_GNUC_UNUSED,
|
|
{
|
|
virThread thr;
|
|
|
|
- if (!driversInitialized) {
|
|
+ if (!g_atomic_int_compare_and_exchange(&driversInitialized, 1, 0)) {
|
|
VIR_WARN("Drivers are not initialized, reload ignored");
|
|
return;
|
|
}
|
|
@@ -480,6 +480,9 @@ static void daemonReloadHandler(virNetDaemonPtr dmn G_GNUC_UNUSED,
|
|
* Not much we can do on error here except log it.
|
|
*/
|
|
VIR_ERROR(_("Failed to create thread to handle daemon restart"));
|
|
+ /* Drivers were initialized at the beginning, otherwise we wouldn't
|
|
+ * even get here. */
|
|
+ g_atomic_int_set(&driversInitialized, 1);
|
|
}
|
|
}
|
|
|
|
@@ -606,7 +609,7 @@ static void daemonRunStateInit(void *opaque)
|
|
goto cleanup;
|
|
}
|
|
|
|
- driversInitialized = true;
|
|
+ g_atomic_int_set(&driversInitialized, 1);
|
|
|
|
#ifdef WITH_DBUS
|
|
/* Tie the non-privileged daemons to the session/shutdown lifecycle */
|
|
@@ -1206,10 +1209,9 @@ int main(int argc, char **argv) {
|
|
|
|
virNetlinkEventServiceStopAll();
|
|
|
|
- if (driversInitialized) {
|
|
+ if (g_atomic_int_compare_and_exchange(&driversInitialized, 1, 0)) {
|
|
/* NB: Possible issue with timing window between driversInitialized
|
|
* setting if virNetlinkEventServerStart fails */
|
|
- driversInitialized = false;
|
|
virStateCleanup();
|
|
}
|
|
|
|
--
|
|
2.33.0
|
|
|