From: Fam Zheng <famz@redhat.com>
To: qemu-devel@nongnu.org
Cc: Kevin Wolf <kwolf@redhat.com>,
qemu-block@nongnu.org, Jeff Cody <jcody@redhat.com>,
Markus Armbruster <armbru@redhat.com>,
mreitz@redhat.com, Stefan Hajnoczi <stefanha@redhat.com>,
pbonzini@redhat.com
Subject: [Qemu-devel] [PATCH v2 3/6] block: Extract blockdev part of qmp_drive_mirror
Date: Thu, 25 Jun 2015 11:22:47 +0800 [thread overview]
Message-ID: <1435202570-12360-4-git-send-email-famz@redhat.com> (raw)
In-Reply-To: <1435202570-12360-1-git-send-email-famz@redhat.com>
This is the part that will be reused by blockdev-mirror.
Signed-off-by: Fam Zheng <famz@redhat.com>
---
blockdev.c | 155 ++++++++++++++++++++++++++++++++++++-------------------------
1 file changed, 92 insertions(+), 63 deletions(-)
diff --git a/blockdev.c b/blockdev.c
index b573e56..2a0c0e2 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -2883,29 +2883,22 @@ out:
#define DEFAULT_MIRROR_BUF_SIZE (10 << 20)
-void qmp_drive_mirror(const char *device, const char *target,
- bool has_format, const char *format,
- bool has_node_name, const char *node_name,
- bool has_replaces, const char *replaces,
- enum MirrorSyncMode sync,
- bool has_mode, enum NewImageMode mode,
- bool has_speed, int64_t speed,
- bool has_granularity, uint32_t granularity,
- bool has_buf_size, int64_t buf_size,
- bool has_on_source_error, BlockdevOnError on_source_error,
- bool has_on_target_error, BlockdevOnError on_target_error,
- Error **errp)
+/* Parameter check and block job starting for mirroring.
+ * Caller should hold @device and @target's aio context (They must to be on the
+ * same aio context). */
+static void blockdev_mirror_common(BlockDriverState *bs,
+ BlockDriverState *target,
+ bool has_replaces, const char *replaces,
+ enum MirrorSyncMode sync,
+ bool has_speed, int64_t speed,
+ bool has_granularity, uint32_t granularity,
+ bool has_buf_size, int64_t buf_size,
+ bool has_on_source_error,
+ BlockdevOnError on_source_error,
+ bool has_on_target_error,
+ BlockdevOnError on_target_error,
+ Error **errp)
{
- BlockBackend *blk;
- BlockDriverState *bs;
- BlockDriverState *source, *target_bs;
- AioContext *aio_context;
- BlockDriver *drv = NULL;
- Error *local_err = NULL;
- QDict *options = NULL;
- int flags;
- int64_t size;
- int ret;
if (!has_speed) {
speed = 0;
@@ -2916,9 +2909,6 @@ void qmp_drive_mirror(const char *device, const char *target,
if (!has_on_target_error) {
on_target_error = BLOCKDEV_ON_ERROR_REPORT;
}
- if (!has_mode) {
- mode = NEW_IMAGE_MODE_ABSOLUTE_PATHS;
- }
if (!has_granularity) {
granularity = 0;
}
@@ -2936,35 +2926,76 @@ void qmp_drive_mirror(const char *device, const char *target,
return;
}
- blk = blk_by_name(device);
- if (!blk) {
- error_set(errp, QERR_DEVICE_NOT_FOUND, device);
- return;
- }
-
- aio_context = blk_get_aio_context(blk);
- aio_context_acquire(aio_context);
-
- if (!blk_is_available(blk)) {
- error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);
- goto out;
- }
- bs = blk_bs(blk);
-
- if (!has_format) {
- format = mode == NEW_IMAGE_MODE_EXISTING ? NULL : bs->drv->format_name;
- }
- if (format) {
- drv = bdrv_find_format(format);
- if (!drv) {
- error_set(errp, QERR_INVALID_BLOCK_FORMAT, format);
- goto out;
- }
- }
-
if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_MIRROR_SOURCE, errp)) {
+ return;
+ }
+
+ if (!bs->backing_hd && sync == MIRROR_SYNC_MODE_TOP) {
+ sync = MIRROR_SYNC_MODE_FULL;
+ }
+
+ /* pass the node name to replace to mirror start since it's loose coupling
+ * and will allow to check whether the node still exist at mirror completion
+ */
+ mirror_start(bs, target,
+ has_replaces ? replaces : NULL,
+ speed, granularity, buf_size, sync,
+ on_source_error, on_target_error,
+ block_job_cb, bs, errp);
+}
+
+void qmp_drive_mirror(const char *device, const char *target,
+ bool has_format, const char *format,
+ bool has_node_name, const char *node_name,
+ bool has_replaces, const char *replaces,
+ enum MirrorSyncMode sync,
+ bool has_mode, enum NewImageMode mode,
+ bool has_speed, int64_t speed,
+ bool has_granularity, uint32_t granularity,
+ bool has_buf_size, int64_t buf_size,
+ bool has_on_source_error, BlockdevOnError on_source_error,
+ bool has_on_target_error, BlockdevOnError on_target_error,
+ Error **errp)
+{
+ BlockDriverState *bs;
+ BlockBackend *blk;
+ BlockDriverState *source, *target_bs;
+ AioContext *aio_context;
+ BlockDriver *drv = NULL;
+ Error *local_err = NULL;
+ QDict *options = NULL;
+ int flags;
+ int64_t size;
+ int ret;
+
+ blk = blk_by_name(device);
+ if (!blk) {
+ error_set(errp, QERR_DEVICE_NOT_FOUND, device);
+ return;
+ }
+
+ aio_context = blk_get_aio_context(blk);
+ aio_context_acquire(aio_context);
+
+ if (!blk_is_available(blk)) {
+ error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);
goto out;
}
+ bs = blk_bs(blk);
+ if (!has_mode) {
+ mode = NEW_IMAGE_MODE_ABSOLUTE_PATHS;
+ }
+
+ if (!has_format) {
+ format = mode == NEW_IMAGE_MODE_EXISTING ? NULL : bs->drv->format_name;
+ }
+ if (format) {
+ drv = bdrv_find_format(format);
+ if (!drv) {
+ error_set(errp, QERR_INVALID_BLOCK_FORMAT, format);
+ goto out;
+ }
+ }
flags = bs->open_flags | BDRV_O_RDWR;
source = bs->backing_hd;
@@ -3057,20 +3088,18 @@ void qmp_drive_mirror(const char *device, const char *target,
bdrv_set_aio_context(target_bs, aio_context);
- /* pass the node name to replace to mirror start since it's loose coupling
- * and will allow to check whether the node still exist at mirror completion
- */
- mirror_start(bs, target_bs,
- has_replaces ? replaces : NULL,
- speed, granularity, buf_size, sync,
- on_source_error, on_target_error,
- block_job_cb, bs, &local_err);
- if (local_err != NULL) {
- bdrv_unref(target_bs);
+ blockdev_mirror_common(bs, target_bs,
+ has_replaces, replaces, sync,
+ has_speed, speed,
+ has_granularity, granularity,
+ has_buf_size, buf_size,
+ has_on_source_error, on_source_error,
+ has_on_target_error, on_target_error,
+ &local_err);
+ if (local_err) {
error_propagate(errp, local_err);
- goto out;
+ bdrv_unref(target_bs);
}
-
out:
aio_context_release(aio_context);
}
--
2.4.3
next prev parent reply other threads:[~2015-06-25 3:23 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-06-25 3:22 [Qemu-devel] [PATCH v2 0/6] qmp: Add blockdev-mirror Fam Zheng
2015-06-25 3:22 ` [Qemu-devel] [PATCH v2 1/6] block: Add blocker on mirror target Fam Zheng
2015-07-20 15:10 ` Max Reitz
2015-06-25 3:22 ` [Qemu-devel] [PATCH v2 2/6] block: Rename BLOCK_OP_TYPE_MIRROR to BLOCK_OP_TYPE_MIRROR_SOURCE Fam Zheng
2015-06-25 3:22 ` Fam Zheng [this message]
2015-07-20 15:30 ` [Qemu-devel] [PATCH v2 3/6] block: Extract blockdev part of qmp_drive_mirror Max Reitz
2015-06-25 3:22 ` [Qemu-devel] [PATCH v2 4/6] block: Add check on mirror target Fam Zheng
2015-06-25 3:22 ` [Qemu-devel] [PATCH v2 5/6] qmp: Add blockdev-mirror command Fam Zheng
2015-07-02 13:12 ` Markus Armbruster
2015-07-20 15:33 ` Max Reitz
2015-07-22 1:42 ` Fam Zheng
2015-06-25 3:22 ` [Qemu-devel] [PATCH v2 6/6] iotests: Add test cases for blockdev-mirror Fam Zheng
2015-06-25 14:25 ` [Qemu-devel] [Qemu-block] [PATCH v2 0/6] qmp: Add blockdev-mirror Stefan Hajnoczi
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=1435202570-12360-4-git-send-email-famz@redhat.com \
--to=famz@redhat.com \
--cc=armbru@redhat.com \
--cc=jcody@redhat.com \
--cc=kwolf@redhat.com \
--cc=mreitz@redhat.com \
--cc=pbonzini@redhat.com \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@redhat.com \
/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).