26ba25
From 7ec94ee16262eb0da7fb7788347a65162845b1c2 Mon Sep 17 00:00:00 2001
26ba25
From: Kevin Wolf <kwolf@redhat.com>
26ba25
Date: Wed, 10 Oct 2018 13:19:57 +0100
26ba25
Subject: [PATCH 3/5] mirror: Fail gracefully for source == target
26ba25
26ba25
RH-Author: Kevin Wolf <kwolf@redhat.com>
26ba25
Message-id: <20181010131957.23198-2-kwolf@redhat.com>
26ba25
Patchwork-id: 82564
26ba25
O-Subject: [RHEL-8 qemu-kvm PATCH 1/1] mirror: Fail gracefully for source == target
26ba25
Bugzilla: 1637963
26ba25
RH-Acked-by: John Snow <jsnow@redhat.com>
26ba25
RH-Acked-by: Fam Zheng <famz@redhat.com>
26ba25
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
26ba25
26ba25
blockdev-mirror with the same node for source and target segfaults
26ba25
today: A node is in its own backing chain, so mirror_start_job() decides
26ba25
that this is an active commit. When adding the intermediate nodes with
26ba25
block_job_add_bdrv(), it starts the iteration through the subchain with
26ba25
the backing file of source, though, so it never reaches target and
26ba25
instead runs into NULL at the base.
26ba25
26ba25
While we could fix that by starting with source itself, there is no
26ba25
point in allowing mirroring a node into itself and I wouldn't be
26ba25
surprised if this caused more problems later.
26ba25
26ba25
So just check for this scenario and error out.
26ba25
26ba25
Cc: qemu-stable@nongnu.org
26ba25
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
26ba25
Reviewed-by: Eric Blake <eblake@redhat.com>
26ba25
(cherry picked from commit 86fae10c64d642256cf019e6829929fa0d259c7a)
26ba25
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
26ba25
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
26ba25
---
26ba25
 block/mirror.c             | 5 +++++
26ba25
 tests/qemu-iotests/041     | 6 ++++++
26ba25
 tests/qemu-iotests/041.out | 4 ++--
26ba25
 3 files changed, 13 insertions(+), 2 deletions(-)
26ba25
26ba25
diff --git a/block/mirror.c b/block/mirror.c
26ba25
index 163b1d4..313e6e9 100644
26ba25
--- a/block/mirror.c
26ba25
+++ b/block/mirror.c
26ba25
@@ -1149,6 +1149,11 @@ static void mirror_start_job(const char *job_id, BlockDriverState *bs,
26ba25
         buf_size = DEFAULT_MIRROR_BUF_SIZE;
26ba25
     }
26ba25
 
26ba25
+    if (bs == target) {
26ba25
+        error_setg(errp, "Can't mirror node into itself");
26ba25
+        return;
26ba25
+    }
26ba25
+
26ba25
     /* In the case of active commit, add dummy driver to provide consistent
26ba25
      * reads on the top, while disabling it in the intermediate nodes, and make
26ba25
      * the backing chain writable. */
26ba25
diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041
26ba25
index c20ac7d..9336ab6 100755
26ba25
--- a/tests/qemu-iotests/041
26ba25
+++ b/tests/qemu-iotests/041
26ba25
@@ -234,6 +234,12 @@ class TestSingleBlockdev(TestSingleDrive):
26ba25
         result = self.vm.qmp("blockdev-add", **args)
26ba25
         self.assert_qmp(result, 'return', {})
26ba25
 
26ba25
+    def test_mirror_to_self(self):
26ba25
+        result = self.vm.qmp(self.qmp_cmd, job_id='job0',
26ba25
+                             device=self.qmp_target, sync='full',
26ba25
+                             target=self.qmp_target)
26ba25
+        self.assert_qmp(result, 'error/class', 'GenericError')
26ba25
+
26ba25
     test_large_cluster = None
26ba25
     test_image_not_found = None
26ba25
     test_small_buffer2 = None
26ba25
diff --git a/tests/qemu-iotests/041.out b/tests/qemu-iotests/041.out
26ba25
index c28b392..e071d0b 100644
26ba25
--- a/tests/qemu-iotests/041.out
26ba25
+++ b/tests/qemu-iotests/041.out
26ba25
@@ -1,5 +1,5 @@
26ba25
-.....................................................................................
26ba25
+........................................................................................
26ba25
 ----------------------------------------------------------------------
26ba25
-Ran 85 tests
26ba25
+Ran 88 tests
26ba25
 
26ba25
 OK
26ba25
-- 
26ba25
1.8.3.1
26ba25