From: Stefan Hajnoczi <stefanha@redhat.com>
To: qemu-devel@nongnu.org
Cc: Kevin Wolf <kwolf@redhat.com>,
famz@redhat.com, Jeff Cody <jcody@redhat.com>,
Max Reitz <mreitz@redhat.com>,
vsementsov@parallels.com, Stefan Hajnoczi <stefanha@redhat.com>,
John Snow <jsnow@redhat.com>
Subject: [Qemu-devel] [RFC 7/9] block/backup: support block job transactions
Date: Fri, 12 Jun 2015 11:09:19 +0100 [thread overview]
Message-ID: <1434103761-29871-8-git-send-email-stefanha@redhat.com> (raw)
In-Reply-To: <1434103761-29871-1-git-send-email-stefanha@redhat.com>
Join the transaction when the backup block job is in incremental backup
mode.
This ensures that the sync bitmap is not thrown away if another block
job in the transaction is cancelled or fails. This is critical so
incremental backup with multiple disks can be retried in case of
cancellation/failure.
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
block/backup.c | 7 +++++-
blockdev.c | 73 ++++++++++++++++++++++++++++++++++++++++++----------------
2 files changed, 59 insertions(+), 21 deletions(-)
diff --git a/block/backup.c b/block/backup.c
index c1ad975..ecc1b00 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -428,6 +428,8 @@ static void coroutine_fn backup_run(void *opaque)
qemu_co_rwlock_wrlock(&job->flush_rwlock);
qemu_co_rwlock_unlock(&job->flush_rwlock);
+ block_job_txn_prepare_to_complete(job->common.txn, &job->common, ret);
+
if (job->sync_bitmap) {
BdrvDirtyBitmap *bm;
if (ret < 0 || block_job_is_cancelled(&job->common)) {
@@ -456,7 +458,7 @@ void backup_start(BlockDriverState *bs, BlockDriverState *target,
BlockdevOnError on_source_error,
BlockdevOnError on_target_error,
BlockCompletionFunc *cb, void *opaque,
- Error **errp)
+ BlockJobTxn *txn, Error **errp)
{
int64_t len;
@@ -536,6 +538,9 @@ void backup_start(BlockDriverState *bs, BlockDriverState *target,
job->sync_mode = sync_mode;
job->sync_bitmap = sync_mode == MIRROR_SYNC_MODE_DIRTY_BITMAP ?
sync_bitmap : NULL;
+ if (job->sync_bitmap) {
+ block_job_txn_add_job(txn, &job->common);
+ }
job->common.len = len;
job->common.co = qemu_coroutine_create(backup_run);
qemu_coroutine_enter(job->common.co, job);
diff --git a/blockdev.c b/blockdev.c
index 2cdc7f3..aa46d7c 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1573,6 +1573,18 @@ typedef struct DriveBackupState {
BlockJob *job;
} DriveBackupState;
+static void do_drive_backup(const char *device, const char *target,
+ bool has_format, const char *format,
+ enum MirrorSyncMode sync,
+ bool has_mode, enum NewImageMode mode,
+ bool has_speed, int64_t speed,
+ bool has_bitmap, const char *bitmap,
+ bool has_on_source_error,
+ BlockdevOnError on_source_error,
+ bool has_on_target_error,
+ BlockdevOnError on_target_error,
+ BlockJobTxn *txn, Error **errp);
+
static void drive_backup_prepare(BlkActionState *common, Error **errp)
{
DriveBackupState *state = DO_UPCAST(DriveBackupState, common, common);
@@ -1595,15 +1607,16 @@ static void drive_backup_prepare(BlkActionState *common, Error **errp)
state->aio_context = bdrv_get_aio_context(bs);
aio_context_acquire(state->aio_context);
- qmp_drive_backup(backup->device, backup->target,
- backup->has_format, backup->format,
- backup->sync,
- backup->has_mode, backup->mode,
- backup->has_speed, backup->speed,
- backup->has_bitmap, backup->bitmap,
- backup->has_on_source_error, backup->on_source_error,
- backup->has_on_target_error, backup->on_target_error,
- &local_err);
+ do_drive_backup(backup->device, backup->target,
+ backup->has_format, backup->format,
+ backup->sync,
+ backup->has_mode, backup->mode,
+ backup->has_speed, backup->speed,
+ backup->has_bitmap, backup->bitmap,
+ backup->has_on_source_error, backup->on_source_error,
+ backup->has_on_target_error, backup->on_target_error,
+ common->block_job_txn,
+ &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
@@ -2559,15 +2572,17 @@ out:
aio_context_release(aio_context);
}
-void qmp_drive_backup(const char *device, const char *target,
- bool has_format, const char *format,
- enum MirrorSyncMode sync,
- bool has_mode, enum NewImageMode mode,
- bool has_speed, int64_t speed,
- bool has_bitmap, const char *bitmap,
- bool has_on_source_error, BlockdevOnError on_source_error,
- bool has_on_target_error, BlockdevOnError on_target_error,
- Error **errp)
+static void do_drive_backup(const char *device, const char *target,
+ bool has_format, const char *format,
+ enum MirrorSyncMode sync,
+ bool has_mode, enum NewImageMode mode,
+ bool has_speed, int64_t speed,
+ bool has_bitmap, const char *bitmap,
+ bool has_on_source_error,
+ BlockdevOnError on_source_error,
+ bool has_on_target_error,
+ BlockdevOnError on_target_error,
+ BlockJobTxn *txn, Error **errp)
{
BlockBackend *blk;
BlockDriverState *bs;
@@ -2683,7 +2698,7 @@ void qmp_drive_backup(const char *device, const char *target,
backup_start(bs, target_bs, speed, sync, bmap,
on_source_error, on_target_error,
- block_job_cb, bs, &local_err);
+ block_job_cb, bs, txn, &local_err);
if (local_err != NULL) {
bdrv_unref(target_bs);
error_propagate(errp, local_err);
@@ -2694,6 +2709,24 @@ out:
aio_context_release(aio_context);
}
+void qmp_drive_backup(const char *device, const char *target,
+ bool has_format, const char *format,
+ enum MirrorSyncMode sync,
+ bool has_mode, enum NewImageMode mode,
+ bool has_speed, int64_t speed,
+ bool has_bitmap, const char *bitmap,
+ bool has_on_source_error, BlockdevOnError on_source_error,
+ bool has_on_target_error, BlockdevOnError on_target_error,
+ Error **errp)
+{
+ return do_drive_backup(device, target, has_format, format, sync,
+ has_mode, mode, has_speed, speed,
+ has_bitmap, bitmap,
+ has_on_source_error, on_source_error,
+ has_on_target_error, on_target_error,
+ NULL, errp);
+}
+
BlockDeviceInfoList *qmp_query_named_block_nodes(Error **errp)
{
return bdrv_named_nodes_list(errp);
@@ -2744,7 +2777,7 @@ void qmp_blockdev_backup(const char *device, const char *target,
bdrv_ref(target_bs);
bdrv_set_aio_context(target_bs, aio_context);
backup_start(bs, target_bs, speed, sync, NULL, on_source_error,
- on_target_error, block_job_cb, bs, &local_err);
+ on_target_error, block_job_cb, bs, NULL, &local_err);
if (local_err != NULL) {
bdrv_unref(target_bs);
error_propagate(errp, local_err);
--
2.4.2
next prev parent reply other threads:[~2015-06-12 10:09 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-06-12 10:09 [Qemu-devel] [RFC 0/9] block: incremental backup transactions using BlockJobTxn Stefan Hajnoczi
2015-06-12 10:09 ` [Qemu-devel] [RFC 1/9] qapi: Add transaction support to block-dirty-bitmap operations Stefan Hajnoczi
2015-06-12 10:09 ` [Qemu-devel] [RFC 2/9] iotests: add transactional incremental backup test Stefan Hajnoczi
2015-06-12 10:09 ` [Qemu-devel] [RFC 3/9] block: rename BlkTransactionState and BdrvActionOps Stefan Hajnoczi
2015-06-12 10:09 ` [Qemu-devel] [RFC 4/9] block: keep bitmap if incremental backup job is cancelled Stefan Hajnoczi
2015-06-12 22:39 ` John Snow
2015-06-15 14:48 ` Stefan Hajnoczi
2015-06-24 17:35 ` Max Reitz
2015-06-25 12:51 ` Stefan Hajnoczi
2015-06-12 10:09 ` [Qemu-devel] [RFC 5/9] block: add block job transactions Stefan Hajnoczi
2015-06-24 18:37 ` Max Reitz
2015-06-25 12:50 ` Stefan Hajnoczi
2015-06-12 10:09 ` [Qemu-devel] [RFC 6/9] blockdev: make BlockJobTxn available to qmp 'transaction' Stefan Hajnoczi
2015-06-12 10:09 ` Stefan Hajnoczi [this message]
2015-06-12 10:09 ` [Qemu-devel] [RFC 8/9] iotests: 124 - transactional failure test Stefan Hajnoczi
2015-06-12 10:09 ` [Qemu-devel] [RFC 9/9] qmp-commands.hx: Update the supported 'transaction' operations 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=1434103761-29871-8-git-send-email-stefanha@redhat.com \
--to=stefanha@redhat.com \
--cc=famz@redhat.com \
--cc=jcody@redhat.com \
--cc=jsnow@redhat.com \
--cc=kwolf@redhat.com \
--cc=mreitz@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=vsementsov@parallels.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).