aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--block/mirror.c33
-rw-r--r--blockdev.c4
-rwxr-xr-xtests/qemu-iotests/04127
-rw-r--r--tests/qemu-iotests/041.out4
4 files changed, 8 insertions, 60 deletions
diff --git a/block/mirror.c b/block/mirror.c
index efca8fc177..23aa10e5bf 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -20,7 +20,6 @@
#include "qapi/qmp/qerror.h"
#include "qemu/ratelimit.h"
#include "qemu/bitmap.h"
-#include "qemu/error-report.h"
#define SLICE_TIME 100000000ULL /* ns */
#define MAX_IN_FLIGHT 16
@@ -466,24 +465,20 @@ static void mirror_exit(BlockJob *job, void *opaque)
to_replace = s->to_replace;
}
- /* This was checked in mirror_start_job(), but meanwhile one of the
- * nodes could have been newly attached to a BlockBackend. */
- if (bdrv_has_blk(to_replace) && bdrv_has_blk(s->target)) {
- error_report("block job: Can't create node with two BlockBackends");
- data->ret = -EINVAL;
- goto out;
- }
-
if (bdrv_get_flags(s->target) != bdrv_get_flags(to_replace)) {
bdrv_reopen(s->target, bdrv_get_flags(to_replace), NULL);
}
+
+ /* The mirror job has no requests in flight any more, but we need to
+ * drain potential other users of the BDS before changing the graph. */
+ bdrv_drained_begin(s->target);
bdrv_replace_in_backing_chain(to_replace, s->target);
+ bdrv_drained_end(s->target);
+
/* We just changed the BDS the job BB refers to */
blk_remove_bs(job->blk);
blk_insert_bs(job->blk, src);
}
-
-out:
if (s->to_replace) {
bdrv_op_unblock_all(s->to_replace, s->replace_blocker);
error_free(s->replace_blocker);
@@ -807,7 +802,6 @@ static void mirror_start_job(BlockDriverState *bs, BlockDriverState *target,
bool is_none_mode, BlockDriverState *base)
{
MirrorBlockJob *s;
- BlockDriverState *replaced_bs;
if (granularity == 0) {
granularity = bdrv_get_default_bitmap_granularity(target);
@@ -824,21 +818,6 @@ static void mirror_start_job(BlockDriverState *bs, BlockDriverState *target,
buf_size = DEFAULT_MIRROR_BUF_SIZE;
}
- /* We can't support this case as long as the block layer can't handle
- * multiple BlockBackends per BlockDriverState. */
- if (replaces) {
- replaced_bs = bdrv_lookup_bs(replaces, replaces, errp);
- if (replaced_bs == NULL) {
- return;
- }
- } else {
- replaced_bs = bs;
- }
- if (bdrv_has_blk(replaced_bs) && bdrv_has_blk(target)) {
- error_setg(errp, "Can't create node with two BlockBackends");
- return;
- }
-
s = block_job_create(driver, bs, speed, cb, opaque, errp);
if (!s) {
return;
diff --git a/blockdev.c b/blockdev.c
index af0b022e6f..3c06746456 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -3459,10 +3459,6 @@ static void blockdev_mirror_common(BlockDriverState *bs,
if (bdrv_op_is_blocked(target, BLOCK_OP_TYPE_MIRROR_TARGET, errp)) {
return;
}
- if (bdrv_has_blk(target)) {
- error_setg(errp, "Cannot mirror to an attached block device");
- return;
- }
if (!bs->backing && sync == MIRROR_SYNC_MODE_TOP) {
sync = MIRROR_SYNC_MODE_FULL;
diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041
index b1c542f99b..ed1d9d464c 100755
--- a/tests/qemu-iotests/041
+++ b/tests/qemu-iotests/041
@@ -207,33 +207,6 @@ class TestSingleBlockdev(TestSingleDrive):
test_image_not_found = None
test_small_buffer2 = None
-class TestBlockdevAttached(iotests.QMPTestCase):
- image_len = 1 * 1024 * 1024 # MB
-
- def setUp(self):
- iotests.create_image(backing_img, self.image_len)
- qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, test_img)
- qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, target_img)
- self.vm = iotests.VM().add_drive(test_img)
- self.vm.launch()
-
- def tearDown(self):
- self.vm.shutdown()
- os.remove(test_img)
- os.remove(target_img)
-
- def test_blockdev_attached(self):
- self.assert_no_active_block_jobs()
- args = {'options':
- {'driver': iotests.imgfmt,
- 'id': 'drive1',
- 'file': { 'filename': target_img, 'driver': 'file' } } }
- result = self.vm.qmp("blockdev-add", **args)
- self.assert_qmp(result, 'return', {})
- result = self.vm.qmp('blockdev-mirror', device='drive0', sync='full',
- target='drive1')
- self.assert_qmp(result, 'error/class', 'GenericError')
-
class TestSingleDriveZeroLength(TestSingleDrive):
image_len = 0
test_small_buffer2 = None
diff --git a/tests/qemu-iotests/041.out b/tests/qemu-iotests/041.out
index b67d0504a6..b0cadc8245 100644
--- a/tests/qemu-iotests/041.out
+++ b/tests/qemu-iotests/041.out
@@ -1,5 +1,5 @@
-............................................................................
+...........................................................................
----------------------------------------------------------------------
-Ran 76 tests
+Ran 75 tests
OK