Blame SOURCES/kvm-mirror-Fail-gracefully-for-source-target.patch

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