Iotest 30 accidentally fails due to interleaving of mirror and stream
graph-modifying procedures. Protect these things by global co-mutex.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsement...@virtuozzo.com>
---
 include/block/block.h | 2 ++
 block.c               | 2 ++
 block/mirror.c        | 4 ++++
 block/stream.c        | 4 ++++
 4 files changed, 12 insertions(+)

diff --git a/include/block/block.h b/include/block/block.h
index c9d7c58765..a92756cbfc 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -20,6 +20,8 @@
  */
 #define generated_co_wrapper
 
+extern CoMutex graph_modify_mutex;
+
 /* block.c */
 typedef struct BlockDriver BlockDriver;
 typedef struct BdrvChild BdrvChild;
diff --git a/block.c b/block.c
index 5e8dd98cec..eb82b1ca1e 100644
--- a/block.c
+++ b/block.c
@@ -86,6 +86,8 @@ static int use_bdrv_whitelist;
 
 bool abort_on_set_to_true = false;
 
+CoMutex graph_modify_mutex;
+
 #ifdef _WIN32
 static int is_windows_drive_prefix(const char *filename)
 {
diff --git a/block/mirror.c b/block/mirror.c
index 91e98b2349..16c3e0b0cb 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -628,6 +628,8 @@ static void coroutine_fn 
mirror_wait_for_all_io(MirrorBlockJob *s)
  */
 int coroutine_fn mirror_co_exit_common(Job *job)
 {
+    QEMU_LOCK_GUARD(&graph_modify_mutex);
+
     MirrorBlockJob *s = container_of(job, MirrorBlockJob, common.job);
     BlockJob *bjob = &s->common;
     MirrorBDSOpaque *bs_opaque;
@@ -1106,6 +1108,8 @@ immediate_exit:
 
 void coroutine_fn mirror_co_complete(Job *job, Error **errp)
 {
+    QEMU_LOCK_GUARD(&graph_modify_mutex);
+
     MirrorBlockJob *s = container_of(job, MirrorBlockJob, common.job);
     BlockDriverState *target;
 
diff --git a/block/stream.c b/block/stream.c
index 8a4b88b223..13eba00ce8 100644
--- a/block/stream.c
+++ b/block/stream.c
@@ -61,6 +61,8 @@ static void stream_abort(Job *job)
 
 int coroutine_fn stream_co_prepare(Job *job)
 {
+    QEMU_LOCK_GUARD(&graph_modify_mutex);
+
     StreamBlockJob *s = container_of(job, StreamBlockJob, common.job);
     BlockJob *bjob = &s->common;
     BlockDriverState *bs = blk_bs(bjob->blk);
@@ -93,6 +95,8 @@ int coroutine_fn stream_co_prepare(Job *job)
 
 void coroutine_fn stream_co_clean(Job *job)
 {
+    QEMU_LOCK_GUARD(&graph_modify_mutex);
+
     StreamBlockJob *s = container_of(job, StreamBlockJob, common.job);
     BlockJob *bjob = &s->common;
     BlockDriverState *bs = blk_bs(bjob->blk);
-- 
2.21.3


Reply via email to