block: Add BlockJobTxn support to backup_run

Allow a BlockJobTxn to be passed into backup_run, which
will allow the job to join a transactional group if present.

Propagate this new parameter outward into new QMP helper
functions in blockdev.c to allow transaction commands to
pass forward their BlockJobTxn object in a forthcoming patch.

[split up from a patch originally by Stefan and Fam. --js]
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: John Snow <jsnow@redhat.com>

Signed-off-by: John Snow <jsnow@redhat.com>
Message-id: 1446765200-3054-12-git-send-email-jsnow@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
John Snow 2015-11-05 18:13:17 -05:00 committed by Kevin Wolf
parent c347b2c62a
commit 78f51fde88
3 changed files with 88 additions and 30 deletions

View File

@ -493,7 +493,7 @@ void backup_start(BlockDriverState *bs, BlockDriverState *target,
BlockdevOnError on_source_error, BlockdevOnError on_source_error,
BlockdevOnError on_target_error, BlockdevOnError on_target_error,
BlockCompletionFunc *cb, void *opaque, BlockCompletionFunc *cb, void *opaque,
Error **errp) BlockJobTxn *txn, Error **errp)
{ {
int64_t len; int64_t len;
@ -575,6 +575,7 @@ void backup_start(BlockDriverState *bs, BlockDriverState *target,
sync_bitmap : NULL; sync_bitmap : NULL;
job->common.len = len; job->common.len = len;
job->common.co = qemu_coroutine_create(backup_run); job->common.co = qemu_coroutine_create(backup_run);
block_job_txn_add_job(txn, &job->common);
qemu_coroutine_enter(job->common.co, job); qemu_coroutine_enter(job->common.co, job);
return; return;

View File

@ -1716,6 +1716,18 @@ typedef struct DriveBackupState {
BlockJob *job; BlockJob *job;
} DriveBackupState; } 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) static void drive_backup_prepare(BlkActionState *common, Error **errp)
{ {
DriveBackupState *state = DO_UPCAST(DriveBackupState, common, common); DriveBackupState *state = DO_UPCAST(DriveBackupState, common, common);
@ -1744,15 +1756,15 @@ static void drive_backup_prepare(BlkActionState *common, Error **errp)
bdrv_drained_begin(blk_bs(blk)); bdrv_drained_begin(blk_bs(blk));
state->bs = blk_bs(blk); state->bs = blk_bs(blk);
qmp_drive_backup(backup->device, backup->target, do_drive_backup(backup->device, backup->target,
backup->has_format, backup->format, backup->has_format, backup->format,
backup->sync, backup->sync,
backup->has_mode, backup->mode, backup->has_mode, backup->mode,
backup->has_speed, backup->speed, backup->has_speed, backup->speed,
backup->has_bitmap, backup->bitmap, backup->has_bitmap, backup->bitmap,
backup->has_on_source_error, backup->on_source_error, backup->has_on_source_error, backup->on_source_error,
backup->has_on_target_error, backup->on_target_error, backup->has_on_target_error, backup->on_target_error,
&local_err); NULL, &local_err);
if (local_err) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
return; return;
@ -1789,6 +1801,15 @@ typedef struct BlockdevBackupState {
AioContext *aio_context; AioContext *aio_context;
} BlockdevBackupState; } BlockdevBackupState;
static void do_blockdev_backup(const char *device, const char *target,
enum MirrorSyncMode sync,
bool has_speed, int64_t speed,
bool has_on_source_error,
BlockdevOnError on_source_error,
bool has_on_target_error,
BlockdevOnError on_target_error,
BlockJobTxn *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);
@ -1827,12 +1848,12 @@ static void blockdev_backup_prepare(BlkActionState *common, Error **errp)
state->bs = blk_bs(blk); state->bs = blk_bs(blk);
bdrv_drained_begin(state->bs); bdrv_drained_begin(state->bs);
qmp_blockdev_backup(backup->device, backup->target, do_blockdev_backup(backup->device, backup->target,
backup->sync, backup->sync,
backup->has_speed, backup->speed, backup->has_speed, backup->speed,
backup->has_on_source_error, backup->on_source_error, backup->has_on_source_error, backup->on_source_error,
backup->has_on_target_error, backup->on_target_error, backup->has_on_target_error, backup->on_target_error,
&local_err); NULL, &local_err);
if (local_err) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
return; return;
@ -2895,15 +2916,17 @@ out:
aio_context_release(aio_context); aio_context_release(aio_context);
} }
void qmp_drive_backup(const char *device, const char *target, static void do_drive_backup(const char *device, const char *target,
bool has_format, const char *format, bool has_format, const char *format,
enum MirrorSyncMode sync, enum MirrorSyncMode sync,
bool has_mode, enum NewImageMode mode, bool has_mode, enum NewImageMode mode,
bool has_speed, int64_t speed, bool has_speed, int64_t speed,
bool has_bitmap, const char *bitmap, bool has_bitmap, const char *bitmap,
bool has_on_source_error, BlockdevOnError on_source_error, bool has_on_source_error,
bool has_on_target_error, BlockdevOnError on_target_error, BlockdevOnError on_source_error,
Error **errp) bool has_on_target_error,
BlockdevOnError on_target_error,
BlockJobTxn *txn, Error **errp)
{ {
BlockBackend *blk; BlockBackend *blk;
BlockDriverState *bs; BlockDriverState *bs;
@ -3018,7 +3041,7 @@ void qmp_drive_backup(const char *device, const char *target,
backup_start(bs, target_bs, speed, sync, bmap, backup_start(bs, target_bs, speed, sync, bmap,
on_source_error, on_target_error, on_source_error, on_target_error,
block_job_cb, bs, &local_err); block_job_cb, bs, txn, &local_err);
if (local_err != NULL) { if (local_err != NULL) {
bdrv_unref(target_bs); bdrv_unref(target_bs);
error_propagate(errp, local_err); error_propagate(errp, local_err);
@ -3029,19 +3052,37 @@ out:
aio_context_release(aio_context); 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) BlockDeviceInfoList *qmp_query_named_block_nodes(Error **errp)
{ {
return bdrv_named_nodes_list(errp); return bdrv_named_nodes_list(errp);
} }
void qmp_blockdev_backup(const char *device, const char *target, void do_blockdev_backup(const char *device, const char *target,
enum MirrorSyncMode sync, enum MirrorSyncMode sync,
bool has_speed, int64_t speed, bool has_speed, int64_t speed,
bool has_on_source_error, bool has_on_source_error,
BlockdevOnError on_source_error, BlockdevOnError on_source_error,
bool has_on_target_error, bool has_on_target_error,
BlockdevOnError on_target_error, BlockdevOnError on_target_error,
Error **errp) BlockJobTxn *txn, Error **errp)
{ {
BlockBackend *blk, *target_blk; BlockBackend *blk, *target_blk;
BlockDriverState *bs; BlockDriverState *bs;
@ -3089,7 +3130,7 @@ void qmp_blockdev_backup(const char *device, const char *target,
bdrv_ref(target_bs); bdrv_ref(target_bs);
bdrv_set_aio_context(target_bs, aio_context); bdrv_set_aio_context(target_bs, aio_context);
backup_start(bs, target_bs, speed, sync, NULL, on_source_error, 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, txn, &local_err);
if (local_err != NULL) { if (local_err != NULL) {
bdrv_unref(target_bs); bdrv_unref(target_bs);
error_propagate(errp, local_err); error_propagate(errp, local_err);
@ -3098,6 +3139,21 @@ out:
aio_context_release(aio_context); aio_context_release(aio_context);
} }
void qmp_blockdev_backup(const char *device, const char *target,
enum MirrorSyncMode sync,
bool has_speed, int64_t speed,
bool has_on_source_error,
BlockdevOnError on_source_error,
bool has_on_target_error,
BlockdevOnError on_target_error,
Error **errp)
{
do_blockdev_backup(device, target, sync, has_speed, speed,
has_on_source_error, on_source_error,
has_on_target_error, on_target_error,
NULL, errp);
}
void qmp_drive_mirror(const char *device, const char *target, void qmp_drive_mirror(const char *device, const char *target,
bool has_format, const char *format, bool has_format, const char *format,
bool has_node_name, const char *node_name, bool has_node_name, const char *node_name,

View File

@ -669,6 +669,7 @@ void mirror_start(BlockDriverState *bs, BlockDriverState *target,
* @on_target_error: The action to take upon error writing to the target. * @on_target_error: The action to take upon error writing to the target.
* @cb: Completion function for the job. * @cb: Completion function for the job.
* @opaque: Opaque pointer value passed to @cb. * @opaque: Opaque pointer value passed to @cb.
* @txn: Transaction that this job is part of (may be NULL).
* *
* Start a backup operation on @bs. Clusters in @bs are written to @target * Start a backup operation on @bs. Clusters in @bs are written to @target
* until the job is cancelled or manually completed. * until the job is cancelled or manually completed.
@ -679,7 +680,7 @@ void backup_start(BlockDriverState *bs, BlockDriverState *target,
BlockdevOnError on_source_error, BlockdevOnError on_source_error,
BlockdevOnError on_target_error, BlockdevOnError on_target_error,
BlockCompletionFunc *cb, void *opaque, BlockCompletionFunc *cb, void *opaque,
Error **errp); BlockJobTxn *txn, Error **errp);
void blk_set_bs(BlockBackend *blk, BlockDriverState *bs); void blk_set_bs(BlockBackend *blk, BlockDriverState *bs);