From: Max Reitz <mreitz@redhat.com>
To: Fam Zheng <famz@redhat.com>, qemu-devel@nongnu.org
Cc: Kevin Wolf <kwolf@redhat.com>, Jeff Cody <jcody@redhat.com>,
vsementsov@parallels.com, stefanha@redhat.com,
John Snow <jsnow@redhat.com>
Subject: Re: [Qemu-devel] [PATCH v4 01/14] qapi: Add transaction support to block-dirty-bitmap operations
Date: Mon, 3 Aug 2015 18:49:43 +0200 [thread overview]
Message-ID: <55BF9BA7.7030309@redhat.com> (raw)
In-Reply-To: <1438238370-16212-2-git-send-email-famz@redhat.com>
On 30.07.2015 08:39, Fam Zheng wrote:
> From: John Snow <jsnow@redhat.com>
>
> This adds two qmp commands to transactions.
>
> block-dirty-bitmap-add allows you to create a bitmap simultaneously
> alongside a new full backup to accomplish a clean synchronization
> point.
>
> block-dirty-bitmap-clear allows you to reset a bitmap back to as-if
> it were new, which can also be used alongside a full backup to
> accomplish a clean synchronization point.
>
> Signed-off-by: Fam Zheng <famz@redhat.com>
> Signed-off-by: John Snow <jsnow@redhat.com>
> Reviewed-by: Max Reitz <mreitz@redhat.com>
> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
> Signed-off-by: Fam Zheng <famz@redhat.com>
> ---
> block.c | 19 +++++++-
> blockdev.c | 114 +++++++++++++++++++++++++++++++++++++++++++++-
> docs/bitmaps.md | 6 +--
> include/block/block.h | 1 -
> include/block/block_int.h | 3 ++
> qapi-schema.json | 6 ++-
> 6 files changed, 139 insertions(+), 10 deletions(-)
>
> diff --git a/block.c b/block.c
> index d088ee0..cee68c2 100644
> --- a/block.c
> +++ b/block.c
> @@ -3566,10 +3566,25 @@ void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap,
> hbitmap_reset(bitmap->bitmap, cur_sector, nr_sectors);
> }
>
> -void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap)
> +void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap **out)
> {
> assert(bdrv_dirty_bitmap_enabled(bitmap));
> - hbitmap_reset_all(bitmap->bitmap);
> + if (!out) {
> + hbitmap_reset_all(bitmap->bitmap);
> + } else {
> + HBitmap *backup = bitmap->bitmap;
> + bitmap->bitmap = hbitmap_alloc(bitmap->size,
> + hbitmap_granularity(backup));
> + *out = backup;
> + }
> +}
> +
> +void bdrv_undo_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap *in)
> +{
> + HBitmap *tmp = bitmap->bitmap;
> + assert(bdrv_dirty_bitmap_enabled(bitmap));
> + bitmap->bitmap = in;
> + hbitmap_free(tmp);
> }
>
> void bdrv_set_dirty(BlockDriverState *bs, int64_t cur_sector,
> diff --git a/blockdev.c b/blockdev.c
> index 62a4586..b80439b 100644
> --- a/blockdev.c
> +++ b/blockdev.c
> @@ -1708,6 +1708,106 @@ static void blockdev_backup_clean(BlkTransactionState *common)
> }
> }
>
> +typedef struct BlockDirtyBitmapState {
> + BlkTransactionState common;
> + BdrvDirtyBitmap *bitmap;
> + BlockDriverState *bs;
> + AioContext *aio_context;
> + HBitmap *backup;
> + bool prepared;
> +} BlockDirtyBitmapState;
> +
> +static void block_dirty_bitmap_add_prepare(BlkTransactionState *common,
> + Error **errp)
> +{
> + Error *local_err = NULL;
> + BlockDirtyBitmapAdd *action;
> + BlockDirtyBitmapState *state = DO_UPCAST(BlockDirtyBitmapState,
> + common, common);
> +
> + action = common->action->block_dirty_bitmap_add;
> + /* AIO context taken and released within qmp_block_dirty_bitmap_add */
> + qmp_block_dirty_bitmap_add(action->node, action->name,
> + action->has_granularity, action->granularity,
> + &local_err);
> +
> + if (!local_err) {
> + state->prepared = true;
> + } else {
> + error_propagate(errp, local_err);
> + }
> +}
> +
> +static void block_dirty_bitmap_add_abort(BlkTransactionState *common)
> +{
> + BlockDirtyBitmapAdd *action;
> + BlockDirtyBitmapState *state = DO_UPCAST(BlockDirtyBitmapState,
> + common, common);
> +
> + action = common->action->block_dirty_bitmap_add;
> + /* Should not be able to fail: IF the bitmap was added via .prepare(),
> + * then the node reference and bitmap name must have been valid.
> + */
> + if (state->prepared) {
> + qmp_block_dirty_bitmap_remove(action->node, action->name, &error_abort);
> + }
> +}
> +
> +static void block_dirty_bitmap_clear_prepare(BlkTransactionState *common,
> + Error **errp)
> +{
> + BlockDirtyBitmapState *state = DO_UPCAST(BlockDirtyBitmapState,
> + common, common);
> + BlockDirtyBitmap *action;
> +
> + action = common->action->block_dirty_bitmap_clear;
> + state->bitmap = block_dirty_bitmap_lookup(action->node,
> + action->name,
> + &state->bs,
> + &state->aio_context,
> + errp);
> + if (!state->bitmap) {
> + return;
> + }
> +
> + if (bdrv_dirty_bitmap_frozen(state->bitmap)) {
> + error_setg(errp, "Cannot modify a frozen bitmap");
> + return;
> + } else if (!bdrv_dirty_bitmap_enabled(state->bitmap)) {
> + error_setg(errp, "Cannot clear a disabled bitmap");
> + return;
> + }
> +
> + bdrv_clear_dirty_bitmap(state->bitmap, &state->backup);
> + /* AioContext is released in .clean() */
> +}
> +
> +static void block_dirty_bitmap_clear_abort(BlkTransactionState *common)
> +{
> + BlockDirtyBitmapState *state = DO_UPCAST(BlockDirtyBitmapState,
> + common, common);
> +
> + bdrv_undo_clear_dirty_bitmap(state->bitmap, state->backup);
> +}
> +
> +static void block_dirty_bitmap_clear_commit(BlkTransactionState *common)
> +{
> + BlockDirtyBitmapState *state = DO_UPCAST(BlockDirtyBitmapState,
> + common, common);
> +
> + hbitmap_free(state->backup);
> +}
> +
> +static void block_dirty_bitmap_clear_clean(BlkTransactionState *common)
> +{
> + BlockDirtyBitmapState *state = DO_UPCAST(BlockDirtyBitmapState,
> + common, common);
> +
> + if (state->aio_context) {
> + aio_context_release(state->aio_context);
> + }
> +}
> +
> static void abort_prepare(BlkTransactionState *common, Error **errp)
> {
> error_setg(errp, "Transaction aborted using Abort action");
> @@ -1748,6 +1848,18 @@ static const BdrvActionOps actions[] = {
> .abort = internal_snapshot_abort,
> .clean = internal_snapshot_clean,
> },
> + [TRANSACTION_ACTION_KIND_BLOCK_DIRTY_BITMAP_ADD] = {
> + .instance_size = sizeof(BlockDirtyBitmapState),
> + .prepare = block_dirty_bitmap_add_prepare,
> + .abort = block_dirty_bitmap_add_abort,
> + },
> + [TRANSACTION_ACTION_KIND_BLOCK_DIRTY_BITMAP_CLEAR] = {
> + .instance_size = sizeof(BlockDirtyBitmapState),
> + .prepare = block_dirty_bitmap_clear_prepare,
> + .commit = block_dirty_bitmap_clear_commit,
> + .abort = block_dirty_bitmap_clear_abort,
> + .clean = block_dirty_bitmap_clear_clean,
> + }
> };
>
> /*
> @@ -2131,7 +2243,7 @@ void qmp_block_dirty_bitmap_clear(const char *node, const char *name,
> goto out;
> }
>
> - bdrv_clear_dirty_bitmap(bitmap);
> + bdrv_clear_dirty_bitmap(bitmap, NULL);
>
> out:
> aio_context_release(aio_context);
> diff --git a/docs/bitmaps.md b/docs/bitmaps.md
> index fa87f07..9fd8ea6 100644
> --- a/docs/bitmaps.md
> +++ b/docs/bitmaps.md
> @@ -97,11 +97,7 @@ which is included at the end of this document.
> }
> ```
>
> -## Transactions (Not yet implemented)
> -
> -* Transactional commands are forthcoming in a future version,
> - and are not yet available for use. This section serves as
> - documentation of intent for their design and usage.
> +## Transactions
>
> ### Justification
>
> diff --git a/include/block/block.h b/include/block/block.h
> index 37916f7..b1116e9 100644
> --- a/include/block/block.h
> +++ b/include/block/block.h
> @@ -503,7 +503,6 @@ void bdrv_set_dirty_bitmap(BdrvDirtyBitmap *bitmap,
> int64_t cur_sector, int nr_sectors);
> void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap,
> int64_t cur_sector, int nr_sectors);
> -void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap);
> void bdrv_dirty_iter_init(BdrvDirtyBitmap *bitmap, struct HBitmapIter *hbi);
> void bdrv_set_dirty_iter(struct HBitmapIter *hbi, int64_t offset);
> int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap);
> diff --git a/include/block/block_int.h b/include/block/block_int.h
> index 14ad4c3..281d790 100644
> --- a/include/block/block_int.h
> +++ b/include/block/block_int.h
> @@ -664,4 +664,7 @@ void blk_dev_resize_cb(BlockBackend *blk);
>
> void bdrv_set_dirty(BlockDriverState *bs, int64_t cur_sector, int nr_sectors);
>
> +void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap **out);
> +void bdrv_undo_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap *in);
> +
> #endif /* BLOCK_INT_H */
> diff --git a/qapi-schema.json b/qapi-schema.json
> index 4342a08..83de942 100644
> --- a/qapi-schema.json
> +++ b/qapi-schema.json
> @@ -1493,6 +1493,8 @@
> # abort since 1.6
> # blockdev-snapshot-internal-sync since 1.7
> # blockdev-backup since 2.3
> +# block-dirty-bitmap-add since 2.4
> +# block-dirty-bitmap-clear since 2.4
*2.5, and keep my R-b.
Max
> ##
> { 'union': 'TransactionAction',
> 'data': {
> @@ -1500,7 +1502,9 @@
> 'drive-backup': 'DriveBackup',
> 'blockdev-backup': 'BlockdevBackup',
> 'abort': 'Abort',
> - 'blockdev-snapshot-internal-sync': 'BlockdevSnapshotInternal'
> + 'blockdev-snapshot-internal-sync': 'BlockdevSnapshotInternal',
> + 'block-dirty-bitmap-add': 'BlockDirtyBitmapAdd',
> + 'block-dirty-bitmap-clear': 'BlockDirtyBitmap'
> } }
>
> ##
>
next prev parent reply other threads:[~2015-08-03 16:49 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-07-30 6:39 [Qemu-devel] [PATCH v4 00/14] block: incremental backup transactions using BlockJobTxn Fam Zheng
2015-07-30 6:39 ` [Qemu-devel] [PATCH v4 01/14] qapi: Add transaction support to block-dirty-bitmap operations Fam Zheng
2015-08-03 16:49 ` Max Reitz [this message]
2015-09-07 6:32 ` Fam Zheng
2015-07-30 6:39 ` [Qemu-devel] [PATCH v4 02/14] iotests: add transactional incremental backup test Fam Zheng
2015-07-30 6:39 ` [Qemu-devel] [PATCH v4 03/14] block: rename BlkTransactionState and BdrvActionOps Fam Zheng
2015-07-30 6:39 ` [Qemu-devel] [PATCH v4 04/14] backup: Extract dirty bitmap handling as a separate function Fam Zheng
2015-08-03 17:06 ` Max Reitz
2015-07-30 6:39 ` [Qemu-devel] [PATCH v4 05/14] blockjob: Introduce reference count Fam Zheng
2015-08-03 17:16 ` Max Reitz
2015-07-30 6:39 ` [Qemu-devel] [PATCH v4 06/14] blockjob: Add .commit and .abort block job actions Fam Zheng
2015-08-03 17:27 ` Max Reitz
2015-07-30 6:39 ` [Qemu-devel] [PATCH v4 07/14] blockjob: Add "completed" and "ret" in BlockJob Fam Zheng
2015-08-03 17:32 ` Max Reitz
2015-07-30 6:39 ` [Qemu-devel] [PATCH v4 08/14] blockjob: Simplify block_job_finish_sync Fam Zheng
2015-08-03 17:37 ` Max Reitz
2015-07-30 6:39 ` [Qemu-devel] [PATCH v4 09/14] block: add block job transactions Fam Zheng
2015-08-03 18:06 ` Max Reitz
2015-09-07 6:36 ` Fam Zheng
2015-07-30 6:39 ` [Qemu-devel] [PATCH v4 10/14] blockdev: make BlockJobTxn available to qmp 'transaction' Fam Zheng
2015-08-03 18:13 ` Max Reitz
2015-09-07 6:52 ` Fam Zheng
2015-07-30 6:39 ` [Qemu-devel] [PATCH v4 11/14] block/backup: support block job transactions Fam Zheng
2015-08-03 18:26 ` Max Reitz
2015-09-07 6:57 ` Fam Zheng
2015-07-30 6:39 ` [Qemu-devel] [PATCH v4 12/14] iotests: 124 - transactional failure test Fam Zheng
2015-07-30 6:39 ` [Qemu-devel] [PATCH v4 13/14] qmp-commands.hx: Update the supported 'transaction' operations Fam Zheng
2015-07-30 6:39 ` [Qemu-devel] [PATCH v4 14/14] tests: add BlockJobTxn unit test Fam Zheng
2015-08-03 18:45 ` Max Reitz
2015-09-07 7:11 ` Fam Zheng
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=55BF9BA7.7030309@redhat.com \
--to=mreitz@redhat.com \
--cc=famz@redhat.com \
--cc=jcody@redhat.com \
--cc=jsnow@redhat.com \
--cc=kwolf@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@redhat.com \
--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).