[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-block] [PULL 24/31] mirror: Allow target that already has a BlockB
From: |
Kevin Wolf |
Subject: |
[Qemu-block] [PULL 24/31] mirror: Allow target that already has a BlockBackend |
Date: |
Wed, 25 May 2016 19:39:49 +0200 |
We had to forbid mirroring to a target BDS that already had a BB
attached because the node swapping at job completion would add a second
BB and we didn't support multiple BBs on a single BDS at the time. Now
we do, so we can lift the restriction.
As we allow additional BlockBackends for the target, we must expect
other users to be sending requests. There may no requests be in flight
during the graph modification, so we have to drain those users now.
The core part of this patch is a revert of commit 40365552.
Signed-off-by: Kevin Wolf <address@hidden>
Reviewed-by: Max Reitz <address@hidden>
---
block/mirror.c | 33 ++++++---------------------------
blockdev.c | 4 ----
tests/qemu-iotests/041 | 27 ---------------------------
tests/qemu-iotests/041.out | 4 ++--
4 files changed, 8 insertions(+), 60 deletions(-)
diff --git a/block/mirror.c b/block/mirror.c
index efca8fc..23aa10e 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 af0b022..3c06746 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 b1c542f..ed1d9d4 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 b67d050..b0cadc8 100644
--- a/tests/qemu-iotests/041.out
+++ b/tests/qemu-iotests/041.out
@@ -1,5 +1,5 @@
-............................................................................
+...........................................................................
----------------------------------------------------------------------
-Ran 76 tests
+Ran 75 tests
OK
--
1.8.3.1
- [Qemu-block] [PULL 14/31] block: Propagate .drained_begin/end callbacks, (continued)
- [Qemu-block] [PULL 14/31] block: Propagate .drained_begin/end callbacks, Kevin Wolf, 2016/05/25
- [Qemu-block] [PULL 15/31] dma-helpers: change interface to byte-based, Kevin Wolf, 2016/05/25
- [Qemu-block] [PULL 19/31] block: Cancel jobs first in bdrv_close_all(), Kevin Wolf, 2016/05/25
- [Qemu-block] [PULL 18/31] block: keep a list of block jobs, Kevin Wolf, 2016/05/25
- [Qemu-block] [PULL 22/31] block: Make blk_co_preadv/pwritev() public, Kevin Wolf, 2016/05/25
- [Qemu-block] [PULL 17/31] block: Rename blk_write_zeroes(), Kevin Wolf, 2016/05/25
- [Qemu-block] [PULL 23/31] stream: Use BlockBackend for I/O, Kevin Wolf, 2016/05/25
- [Qemu-block] [PULL 28/31] backup: Remove bs parameter from backup_do_cow(), Kevin Wolf, 2016/05/25
- [Qemu-block] [PULL 21/31] block: Convert block job core to BlockBackend, Kevin Wolf, 2016/05/25
- [Qemu-block] [PULL 27/31] backup: Pack Notifier within BackupBlockJob, Kevin Wolf, 2016/05/25
- [Qemu-block] [PULL 24/31] mirror: Allow target that already has a BlockBackend,
Kevin Wolf <=
- [Qemu-block] [PULL 26/31] backup: Don't leak BackupBlockJob in error path, Kevin Wolf, 2016/05/25
- [Qemu-block] [PULL 25/31] mirror: Use BlockBackend for I/O, Kevin Wolf, 2016/05/25
- [Qemu-block] [PULL 29/31] backup: Use BlockBackend for I/O, Kevin Wolf, 2016/05/25
- [Qemu-block] [PULL 30/31] commit: Use BlockBackend for I/O, Kevin Wolf, 2016/05/25
- [Qemu-block] [PULL 31/31] blockjob: Remove BlockJob.bs, Kevin Wolf, 2016/05/25
- Re: [Qemu-block] [Qemu-devel] [PULL 00/31] Block layer patches, Peter Maydell, 2016/05/26