From: Kevin Wolf <kwolf@redhat.com>
To: qemu-block@nongnu.org
Cc: kwolf@redhat.com, mreitz@redhat.com, jcody@redhat.com,
jsnow@redhat.com, berto@igalia.com, qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH 06/14] mirror: Allow target that already has a BlockBackend
Date: Wed, 4 May 2016 11:39:17 +0200 [thread overview]
Message-ID: <1462354765-14037-7-git-send-email-kwolf@redhat.com> (raw)
In-Reply-To: <1462354765-14037-1-git-send-email-kwolf@redhat.com>
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 <kwolf@redhat.com>
---
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 516c6cb..da9eeff 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -3434,10 +3434,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
next prev parent reply other threads:[~2016-05-04 9:40 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-05-04 9:39 [Qemu-devel] [PATCH 00/14] block jobs: Convert I/O to BlockBackend Kevin Wolf
2016-05-04 9:39 ` [Qemu-devel] [PATCH 01/14] block: keep a list of block jobs Kevin Wolf
2016-05-13 13:09 ` Max Reitz
2016-05-04 9:39 ` [Qemu-devel] [PATCH 02/14] block: Cancel jobs first in bdrv_close_all() Kevin Wolf
2016-05-06 9:17 ` Alberto Garcia
2016-05-13 13:14 ` Max Reitz
2016-05-04 9:39 ` [Qemu-devel] [PATCH 03/14] block: Default to enabled write cache in blk_new() Kevin Wolf
2016-05-13 13:24 ` Max Reitz
2016-05-04 9:39 ` [Qemu-devel] [PATCH 04/14] block: Convert block job core to BlockBackend Kevin Wolf
2016-05-13 13:45 ` Max Reitz
2016-05-04 9:39 ` [Qemu-devel] [PATCH 05/14] stream: Use BlockBackend for I/O Kevin Wolf
2016-05-13 14:03 ` Max Reitz
2016-05-04 9:39 ` Kevin Wolf [this message]
2016-05-13 14:18 ` [Qemu-devel] [PATCH 06/14] mirror: Allow target that already has a BlockBackend Max Reitz
2016-05-04 9:39 ` [Qemu-devel] [PATCH 07/14] mirror: Use BlockBackend for I/O Kevin Wolf
2016-05-13 14:38 ` Max Reitz
2016-05-13 14:38 ` Max Reitz
2016-05-13 14:57 ` Eric Blake
2016-05-04 9:39 ` [Qemu-devel] [PATCH 08/14] backup: Don't leak BackupBlockJob in error path Kevin Wolf
2016-05-09 13:21 ` Alberto Garcia
2016-05-13 14:46 ` Max Reitz
2016-05-04 9:39 ` [Qemu-devel] [PATCH 09/14] backup: Pack Notifier within BackupBlockJob Kevin Wolf
2016-05-13 15:01 ` Max Reitz
2016-05-04 9:39 ` [Qemu-devel] [PATCH 10/14] backup: Remove bs parameter from backup_do_cow() Kevin Wolf
2016-05-13 15:06 ` Max Reitz
2016-05-04 9:39 ` [Qemu-devel] [PATCH 11/14] block: Add blk_co_readv/writev() Kevin Wolf
2016-05-13 15:12 ` Max Reitz
2016-05-04 9:39 ` [Qemu-devel] [PATCH 12/14] backup: Use BlockBackend for I/O Kevin Wolf
2016-05-13 15:25 ` Max Reitz
2016-05-04 9:39 ` [Qemu-devel] [PATCH 13/14] commit: " Kevin Wolf
2016-05-13 15:36 ` Max Reitz
2016-05-04 9:39 ` [Qemu-devel] [PATCH 14/14] blockjob: Remove BlockJob.bs Kevin Wolf
2016-05-13 15:37 ` Max Reitz
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1462354765-14037-7-git-send-email-kwolf@redhat.com \
--to=kwolf@redhat.com \
--cc=berto@igalia.com \
--cc=jcody@redhat.com \
--cc=jsnow@redhat.com \
--cc=mreitz@redhat.com \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).