mirror of https://github.com/xemu-project/xemu.git
blockdev: unify qmp_blockdev_backup and blockdev-backup transaction paths
Issuing a blockdev-backup from qmp_blockdev_backup takes a slightly different path than when it's issued from a transaction. In the code, this is manifested as some redundancy between do_blockdev_backup() and blockdev_backup_prepare(). This change unifies both paths, merging do_blockdev_backup() and blockdev_backup_prepare(), and changing qmp_blockdev_backup() to create a transaction instead of calling do_backup_common() direcly. As a side-effect, now qmp_blockdev_backup() is executed inside a drained section, as it happens when creating a blockdev-backup transaction. This change is visible from the user's perspective, as the job gets paused and immediately resumed before starting the actual work. Signed-off-by: Sergio Lopez <slp@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Reviewed-by: Kevin Wolf <kwolf@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
2288ccfac9
commit
5b7bfe515e
60
blockdev.c
60
blockdev.c
|
@ -1940,16 +1940,13 @@ typedef struct BlockdevBackupState {
|
||||||
BlockJob *job;
|
BlockJob *job;
|
||||||
} BlockdevBackupState;
|
} BlockdevBackupState;
|
||||||
|
|
||||||
static BlockJob *do_blockdev_backup(BlockdevBackup *backup, JobTxn *txn,
|
|
||||||
Error **errp);
|
|
||||||
|
|
||||||
static void blockdev_backup_prepare(BlkActionState *common, Error **errp)
|
static void blockdev_backup_prepare(BlkActionState *common, Error **errp)
|
||||||
{
|
{
|
||||||
BlockdevBackupState *state = DO_UPCAST(BlockdevBackupState, common, common);
|
BlockdevBackupState *state = DO_UPCAST(BlockdevBackupState, common, common);
|
||||||
BlockdevBackup *backup;
|
BlockdevBackup *backup;
|
||||||
BlockDriverState *bs, *target;
|
BlockDriverState *bs;
|
||||||
|
BlockDriverState *target_bs;
|
||||||
AioContext *aio_context;
|
AioContext *aio_context;
|
||||||
Error *local_err = NULL;
|
|
||||||
|
|
||||||
assert(common->action->type == TRANSACTION_ACTION_KIND_BLOCKDEV_BACKUP);
|
assert(common->action->type == TRANSACTION_ACTION_KIND_BLOCKDEV_BACKUP);
|
||||||
backup = common->action->u.blockdev_backup.data;
|
backup = common->action->u.blockdev_backup.data;
|
||||||
|
@ -1959,8 +1956,8 @@ static void blockdev_backup_prepare(BlkActionState *common, Error **errp)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
target = bdrv_lookup_bs(backup->target, backup->target, errp);
|
target_bs = bdrv_lookup_bs(backup->target, backup->target, errp);
|
||||||
if (!target) {
|
if (!target_bs) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1971,13 +1968,10 @@ static void blockdev_backup_prepare(BlkActionState *common, Error **errp)
|
||||||
/* Paired with .clean() */
|
/* Paired with .clean() */
|
||||||
bdrv_drained_begin(state->bs);
|
bdrv_drained_begin(state->bs);
|
||||||
|
|
||||||
state->job = do_blockdev_backup(backup, common->block_job_txn, &local_err);
|
state->job = do_backup_common(qapi_BlockdevBackup_base(backup),
|
||||||
if (local_err) {
|
bs, target_bs, aio_context,
|
||||||
error_propagate(errp, local_err);
|
common->block_job_txn, errp);
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
|
||||||
aio_context_release(aio_context);
|
aio_context_release(aio_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3695,41 +3689,13 @@ XDbgBlockGraph *qmp_x_debug_query_block_graph(Error **errp)
|
||||||
return bdrv_get_xdbg_block_graph(errp);
|
return bdrv_get_xdbg_block_graph(errp);
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockJob *do_blockdev_backup(BlockdevBackup *backup, JobTxn *txn,
|
void qmp_blockdev_backup(BlockdevBackup *backup, Error **errp)
|
||||||
Error **errp)
|
|
||||||
{
|
{
|
||||||
BlockDriverState *bs;
|
TransactionAction action = {
|
||||||
BlockDriverState *target_bs;
|
.type = TRANSACTION_ACTION_KIND_BLOCKDEV_BACKUP,
|
||||||
AioContext *aio_context;
|
.u.blockdev_backup.data = backup,
|
||||||
BlockJob *job;
|
};
|
||||||
|
blockdev_do_action(&action, errp);
|
||||||
bs = bdrv_lookup_bs(backup->device, backup->device, errp);
|
|
||||||
if (!bs) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
target_bs = bdrv_lookup_bs(backup->target, backup->target, errp);
|
|
||||||
if (!target_bs) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
aio_context = bdrv_get_aio_context(bs);
|
|
||||||
aio_context_acquire(aio_context);
|
|
||||||
|
|
||||||
job = do_backup_common(qapi_BlockdevBackup_base(backup),
|
|
||||||
bs, target_bs, aio_context, txn, errp);
|
|
||||||
|
|
||||||
aio_context_release(aio_context);
|
|
||||||
return job;
|
|
||||||
}
|
|
||||||
|
|
||||||
void qmp_blockdev_backup(BlockdevBackup *arg, Error **errp)
|
|
||||||
{
|
|
||||||
BlockJob *job;
|
|
||||||
job = do_blockdev_backup(arg, NULL, errp);
|
|
||||||
if (job) {
|
|
||||||
job_start(&job->job);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parameter check and block job starting for drive mirroring.
|
/* Parameter check and block job starting for drive mirroring.
|
||||||
|
|
Loading…
Reference in New Issue