qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH v5 3/4] block: Add blockdev-backup to transactio


From: Fam Zheng
Subject: Re: [Qemu-devel] [PATCH v5 3/4] block: Add blockdev-backup to transaction
Date: Thu, 18 Dec 2014 18:31:12 +0800
User-agent: Mutt/1.5.23 (2014-03-12)

On Wed, 12/17 16:20, John Snow wrote:
> On 12/17/2014 07:51 AM, Fam Zheng wrote:
> >Signed-off-by: Fam Zheng <address@hidden>
> >---
> >  blockdev.c       | 79 
> > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> >  qapi-schema.json |  2 ++
> >  2 files changed, 81 insertions(+)
> >
> >diff --git a/blockdev.c b/blockdev.c
> >index dbbab1d..9f9ae88 100644
> >--- a/blockdev.c
> >+++ b/blockdev.c
> >@@ -1559,6 +1559,79 @@ static void drive_backup_clean(BlkTransactionState 
> >*common)
> >      }
> >  }
> >
> >+typedef struct BlockdevBackupState {
> >+    BlkTransactionState common;
> >+    BlockDriverState *bs;
> >+    BlockJob *job;
> >+    AioContext *aio_context;
> >+} BlockdevBackupState;
> >+
> >+static void blockdev_backup_prepare(BlkTransactionState *common, Error 
> >**errp)
> >+{
> >+    BlockdevBackupState *state = DO_UPCAST(BlockdevBackupState, common, 
> >common);
> >+    BlockdevBackup *backup;
> >+    BlockDriverState *bs, *target;
> >+    Error *local_err = NULL;
> >+
> >+    assert(common->action->kind == TRANSACTION_ACTION_KIND_BLOCKDEV_BACKUP);
> >+    backup = common->action->blockdev_backup;
> >+
> >+    bs = bdrv_find(backup->device);
> >+    if (!bs) {
> >+        error_set(errp, QERR_DEVICE_NOT_FOUND, backup->device);
> >+        return;
> >+    }
> >+
> >+    target = bdrv_find(backup->target);
> >+    if (!target) {
> >+        error_set(errp, QERR_DEVICE_NOT_FOUND, backup->target);
> >+        return;
> >+    }
> >+
> >+    /* AioContext is released in .clean() */
> >+    state->aio_context = bdrv_get_aio_context(bs);
> >+    if (state->aio_context != bdrv_get_aio_context(target)) {
> >+        state->aio_context = NULL;
> >+        error_setg(errp, "Backup between two IO threads is not 
> >implemented");
> >+        return;
> >+    }
> >+    aio_context_acquire(state->aio_context);
> >+
> >+    qmp_blockdev_backup(backup->device, backup->target,
> >+                        backup->sync,
> >+                        backup->has_speed, backup->speed,
> >+                        backup->has_on_source_error, 
> >backup->on_source_error,
> >+                        backup->has_on_target_error, 
> >backup->on_target_error,
> >+                        &local_err);
> >+    if (local_err) {
> >+        error_propagate(errp, local_err);
> >+        return;
> >+    }
> >+
> >+    state->bs = bdrv_find(backup->device);
> 
> Just some questions:
> 
> why not use 'bs' instead of calling the function again? Granted, it should
> work a second time if it worked once.

Yeah, it should be "bs", a mistake but not wrong.

> 
> >+    state->job = state->bs->job;
> 
> Why stash both bs and bs->job? Can the BDS change what its job member points
> to between .prepare() and .abort() ?

Copied from drive_backup_prepare. Actually there is a comment about this in
blockdev_backup_abort below:

> 
> >+}
> >+
> >+static void blockdev_backup_abort(BlkTransactionState *common)
> >+{
> >+    BlockdevBackupState *state = DO_UPCAST(BlockdevBackupState, common, 
> >common);
> >+    BlockDriverState *bs = state->bs;
> >+
> >+    /* Only cancel if it's the job we started */
> >+    if (bs && bs->job && bs->job == state->job) {

I think there is one case this is useful: a transaction containing two block
jobs, which *will* fail and abort(). With this check, only the right (started)
block_job_cancel_sync is called.

> >+        block_job_cancel_sync(bs->job);
> >+    }
> >+}
> >+
> >+static void blockdev_backup_clean(BlkTransactionState *common)
> >+{
> >+    BlockdevBackupState *state = DO_UPCAST(BlockdevBackupState, 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");
> >@@ -1582,6 +1655,12 @@ static const BdrvActionOps actions[] = {
> >          .abort = drive_backup_abort,
> >          .clean = drive_backup_clean,
> >      },
> >+    [TRANSACTION_ACTION_KIND_BLOCKDEV_BACKUP] = {
> >+        .instance_size = sizeof(BlockdevBackupState),
> >+        .prepare = blockdev_backup_prepare,
> >+        .abort = blockdev_backup_abort,
> >+        .clean = blockdev_backup_clean,
> >+    },
> >      [TRANSACTION_ACTION_KIND_ABORT] = {
> >          .instance_size = sizeof(BlkTransactionState),
> >          .prepare = abort_prepare,
> >diff --git a/qapi-schema.json b/qapi-schema.json
> >index 47d99cf..fbfc52f 100644
> >--- a/qapi-schema.json
> >+++ b/qapi-schema.json
> >@@ -1260,11 +1260,13 @@
> >  # drive-backup since 1.6
> >  # abort since 1.6
> >  # blockdev-snapshot-internal-sync since 1.7
> >+# blockdev-backup since 2.3
> >  ##
> >  { 'union': 'TransactionAction',
> >    'data': {
> >         'blockdev-snapshot-sync': 'BlockdevSnapshot',
> >         'drive-backup': 'DriveBackup',
> >+       'blockdev-backup': 'BlockdevBackup',
> >         'abort': 'Abort',
> >         'blockdev-snapshot-internal-sync': 'BlockdevSnapshotInternal'
> >     } }
> >
> 
> At any rate, regardless of the answers to my questions:
> Reviewed-by: John Snow <address@hidden>
> 

Thanks! I'm going to fix the above bdrv_find() while keeping your rev-by. I
hope that is OK for you. :)

Fam



reply via email to

[Prev in Thread] Current Thread [Next in Thread]