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

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