]> Git Repo - qemu.git/commitdiff
mirror: Fail gracefully for source == target
authorKevin Wolf <[email protected]>
Tue, 14 Aug 2018 09:52:25 +0000 (11:52 +0200)
committerKevin Wolf <[email protected]>
Wed, 15 Aug 2018 10:50:39 +0000 (12:50 +0200)
blockdev-mirror with the same node for source and target segfaults
today: A node is in its own backing chain, so mirror_start_job() decides
that this is an active commit. When adding the intermediate nodes with
block_job_add_bdrv(), it starts the iteration through the subchain with
the backing file of source, though, so it never reaches target and
instead runs into NULL at the base.

While we could fix that by starting with source itself, there is no
point in allowing mirroring a node into itself and I wouldn't be
surprised if this caused more problems later.

So just check for this scenario and error out.

Cc: [email protected]
Signed-off-by: Kevin Wolf <[email protected]>
Reviewed-by: Eric Blake <[email protected]>
block/mirror.c
tests/qemu-iotests/041
tests/qemu-iotests/041.out

index b48c3f8cf5a585a6c9c24333ad40be321ade35cb..dd5ca02b098f52b77135ec7e59761a0990c85112 100644 (file)
@@ -1499,6 +1499,11 @@ static void mirror_start_job(const char *job_id, BlockDriverState *bs,
         buf_size = DEFAULT_MIRROR_BUF_SIZE;
     }
 
+    if (bs == target) {
+        error_setg(errp, "Can't mirror node into itself");
+        return;
+    }
+
     /* In the case of active commit, add dummy driver to provide consistent
      * reads on the top, while disabling it in the intermediate nodes, and make
      * the backing chain writable. */
index c20ac7da876209e2eda331c3a165f8ab06050ed5..9336ab6ff50d145ec5df372867dbf082f62dd5a0 100755 (executable)
@@ -234,6 +234,12 @@ class TestSingleBlockdev(TestSingleDrive):
         result = self.vm.qmp("blockdev-add", **args)
         self.assert_qmp(result, 'return', {})
 
+    def test_mirror_to_self(self):
+        result = self.vm.qmp(self.qmp_cmd, job_id='job0',
+                             device=self.qmp_target, sync='full',
+                             target=self.qmp_target)
+        self.assert_qmp(result, 'error/class', 'GenericError')
+
     test_large_cluster = None
     test_image_not_found = None
     test_small_buffer2 = None
index c28b392b87e4b604ea5130b9ed863f18da2d0e84..e071d0b26119cc838ed66be6cd6445043e6fba23 100644 (file)
@@ -1,5 +1,5 @@
-.....................................................................................
+........................................................................................
 ----------------------------------------------------------------------
-Ran 85 tests
+Ran 88 tests
 
 OK
This page took 0.032003 seconds and 4 git commands to generate.