[libvirt] [PATCH v2 1/1] qemu: fix concurrency crash bug in snapshot revert

Pavel Mores pmores at redhat.com
Tue Dec 10 14:36:08 UTC 2019


This commit aims to fix

https://bugzilla.redhat.com/show_bug.cgi?id=1610207

The cause was apparently incorrect handling of jobs in snapshot revert code
which allowed a thread executing snapshot delete to begin job while
snapshot revert was still running on another thread.  The snapshot delete
thread then waited on a condition variable in qemuMonitorSend() while the
revert thread finished, changing (and effectively corrupting) the
qemuMonitor structure under the delete thread which led to its crash.

The incorrect handling of jobs in revert code was due to the fact that
although qemuDomainRevertToSnapshot() correctly begins a job at the start,
the job was implicitly ended when qemuProcessStop() was called because the
job lives in the QEMU driver's private data (qemuDomainObjPrivate) that
was purged during qemuProcessStop().

This fix prevents qemuProcessStop() from clearing jobs as the idea of
qemuProcessStop() clearing jobs seems wrong in the first place.  It was
(inadvertently) introduced in commit 888aa4b6b9db65e3db273341e79846, which
is effectively reverted by the second hunk of this commit.  To preserve
the desired effects of the faulty commit, the first hunk is included as
suggested by Michal.

Signed-off-by: Pavel Mores <pmores at redhat.com>
---
 src/qemu/qemu_domain.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 6f53e17b6a..e4a1bccc18 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -403,6 +403,8 @@ qemuDomainObjRestoreJob(virDomainObjPtr obj,
 static void
 qemuDomainObjFreeJob(qemuDomainObjPrivatePtr priv)
 {
+    qemuDomainObjResetJob(priv);
+    qemuDomainObjResetAsyncJob(priv);
     VIR_FREE(priv->job.current);
     VIR_FREE(priv->job.completed);
     virCondDestroy(&priv->job.cond);
@@ -2161,9 +2163,6 @@ qemuDomainObjPrivateDataClear(qemuDomainObjPrivatePtr priv)
     virBitmapFree(priv->migrationCaps);
     priv->migrationCaps = NULL;
 
-    qemuDomainObjResetJob(priv);
-    qemuDomainObjResetAsyncJob(priv);
-
     virHashRemoveAll(priv->blockjobs);
     virHashRemoveAll(priv->dbusVMStates);
 
-- 
2.21.0




More information about the libvir-list mailing list