block: simplify drive-backup
Now that we can support boxed commands, use it to greatly reduce the number of parameters (and likelihood of getting out of sync) when adjusting drive-backup parameters. Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Signed-off-by: Denis V. Lunev <den@openvz.org> CC: Jeff Cody <jcody@redhat.com> CC: Markus Armbruster <armbru@redhat.com> CC: Eric Blake <eblake@redhat.com> CC: John Snow <jsnow@redhat.com> CC: Stefan Hajnoczi <stefanha@redhat.com> CC: Kevin Wolf <kwolf@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
3ea1a09111
commit
81206a8987
111
blockdev.c
111
blockdev.c
@ -1841,17 +1841,8 @@ typedef struct DriveBackupState {
|
||||
BlockJob *job;
|
||||
} DriveBackupState;
|
||||
|
||||
static void do_drive_backup(const char *job_id, 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 do_drive_backup(DriveBackup *backup, BlockJobTxn *txn,
|
||||
Error **errp);
|
||||
|
||||
static void drive_backup_prepare(BlkActionState *common, Error **errp)
|
||||
{
|
||||
@ -1874,16 +1865,7 @@ static void drive_backup_prepare(BlkActionState *common, Error **errp)
|
||||
bdrv_drained_begin(bs);
|
||||
state->bs = bs;
|
||||
|
||||
do_drive_backup(backup->has_job_id ? backup->job_id : NULL,
|
||||
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);
|
||||
do_drive_backup(backup, common->block_job_txn, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
@ -3134,17 +3116,7 @@ out:
|
||||
aio_context_release(aio_context);
|
||||
}
|
||||
|
||||
static void do_drive_backup(const char *job_id, 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 do_drive_backup(DriveBackup *backup, BlockJobTxn *txn, Error **errp)
|
||||
{
|
||||
BlockDriverState *bs;
|
||||
BlockDriverState *target_bs;
|
||||
@ -3156,20 +3128,23 @@ static void do_drive_backup(const char *job_id, const char *device,
|
||||
int flags;
|
||||
int64_t size;
|
||||
|
||||
if (!has_speed) {
|
||||
speed = 0;
|
||||
if (!backup->has_speed) {
|
||||
backup->speed = 0;
|
||||
}
|
||||
if (!has_on_source_error) {
|
||||
on_source_error = BLOCKDEV_ON_ERROR_REPORT;
|
||||
if (!backup->has_on_source_error) {
|
||||
backup->on_source_error = BLOCKDEV_ON_ERROR_REPORT;
|
||||
}
|
||||
if (!has_on_target_error) {
|
||||
on_target_error = BLOCKDEV_ON_ERROR_REPORT;
|
||||
if (!backup->has_on_target_error) {
|
||||
backup->on_target_error = BLOCKDEV_ON_ERROR_REPORT;
|
||||
}
|
||||
if (!has_mode) {
|
||||
mode = NEW_IMAGE_MODE_ABSOLUTE_PATHS;
|
||||
if (!backup->has_mode) {
|
||||
backup->mode = NEW_IMAGE_MODE_ABSOLUTE_PATHS;
|
||||
}
|
||||
if (!backup->has_job_id) {
|
||||
backup->job_id = NULL;
|
||||
}
|
||||
|
||||
bs = qmp_get_root_bs(device, errp);
|
||||
bs = qmp_get_root_bs(backup->device, errp);
|
||||
if (!bs) {
|
||||
return;
|
||||
}
|
||||
@ -3177,8 +3152,9 @@ static void do_drive_backup(const char *job_id, const char *device,
|
||||
aio_context = bdrv_get_aio_context(bs);
|
||||
aio_context_acquire(aio_context);
|
||||
|
||||
if (!has_format) {
|
||||
format = mode == NEW_IMAGE_MODE_EXISTING ? NULL : bs->drv->format_name;
|
||||
if (!backup->has_format) {
|
||||
backup->format = backup->mode == NEW_IMAGE_MODE_EXISTING ?
|
||||
NULL : (char*) bs->drv->format_name;
|
||||
}
|
||||
|
||||
/* Early check to avoid creating target */
|
||||
@ -3190,13 +3166,13 @@ static void do_drive_backup(const char *job_id, const char *device,
|
||||
|
||||
/* See if we have a backing HD we can use to create our new image
|
||||
* on top of. */
|
||||
if (sync == MIRROR_SYNC_MODE_TOP) {
|
||||
if (backup->sync == MIRROR_SYNC_MODE_TOP) {
|
||||
source = backing_bs(bs);
|
||||
if (!source) {
|
||||
sync = MIRROR_SYNC_MODE_FULL;
|
||||
backup->sync = MIRROR_SYNC_MODE_FULL;
|
||||
}
|
||||
}
|
||||
if (sync == MIRROR_SYNC_MODE_NONE) {
|
||||
if (backup->sync == MIRROR_SYNC_MODE_NONE) {
|
||||
source = bs;
|
||||
}
|
||||
|
||||
@ -3206,14 +3182,14 @@ static void do_drive_backup(const char *job_id, const char *device,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (mode != NEW_IMAGE_MODE_EXISTING) {
|
||||
assert(format);
|
||||
if (backup->mode != NEW_IMAGE_MODE_EXISTING) {
|
||||
assert(backup->format);
|
||||
if (source) {
|
||||
bdrv_img_create(target, format, source->filename,
|
||||
bdrv_img_create(backup->target, backup->format, source->filename,
|
||||
source->drv->format_name, NULL,
|
||||
size, flags, &local_err, false);
|
||||
} else {
|
||||
bdrv_img_create(target, format, NULL, NULL, NULL,
|
||||
bdrv_img_create(backup->target, backup->format, NULL, NULL, NULL,
|
||||
size, flags, &local_err, false);
|
||||
}
|
||||
}
|
||||
@ -3223,29 +3199,29 @@ static void do_drive_backup(const char *job_id, const char *device,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (format) {
|
||||
if (backup->format) {
|
||||
options = qdict_new();
|
||||
qdict_put(options, "driver", qstring_from_str(format));
|
||||
qdict_put(options, "driver", qstring_from_str(backup->format));
|
||||
}
|
||||
|
||||
target_bs = bdrv_open(target, NULL, options, flags, errp);
|
||||
target_bs = bdrv_open(backup->target, NULL, options, flags, errp);
|
||||
if (!target_bs) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
bdrv_set_aio_context(target_bs, aio_context);
|
||||
|
||||
if (has_bitmap) {
|
||||
bmap = bdrv_find_dirty_bitmap(bs, bitmap);
|
||||
if (backup->has_bitmap) {
|
||||
bmap = bdrv_find_dirty_bitmap(bs, backup->bitmap);
|
||||
if (!bmap) {
|
||||
error_setg(errp, "Bitmap '%s' could not be found", bitmap);
|
||||
error_setg(errp, "Bitmap '%s' could not be found", backup->bitmap);
|
||||
bdrv_unref(target_bs);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
backup_start(job_id, bs, target_bs, speed, sync, bmap,
|
||||
on_source_error, on_target_error,
|
||||
backup_start(backup->job_id, bs, target_bs, backup->speed, backup->sync,
|
||||
bmap, backup->on_source_error, backup->on_target_error,
|
||||
block_job_cb, bs, txn, &local_err);
|
||||
bdrv_unref(target_bs);
|
||||
if (local_err != NULL) {
|
||||
@ -3257,24 +3233,9 @@ out:
|
||||
aio_context_release(aio_context);
|
||||
}
|
||||
|
||||
void qmp_drive_backup(bool has_job_id, const char *job_id,
|
||||
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)
|
||||
void qmp_drive_backup(DriveBackup *arg, Error **errp)
|
||||
{
|
||||
return do_drive_backup(has_job_id ? job_id : NULL, 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);
|
||||
return do_drive_backup(arg, NULL, errp);
|
||||
}
|
||||
|
||||
BlockDeviceInfoList *qmp_query_named_block_nodes(Error **errp)
|
||||
|
21
hmp.c
21
hmp.c
@ -1109,8 +1109,16 @@ void hmp_drive_backup(Monitor *mon, const QDict *qdict)
|
||||
const char *format = qdict_get_try_str(qdict, "format");
|
||||
bool reuse = qdict_get_try_bool(qdict, "reuse", false);
|
||||
bool full = qdict_get_try_bool(qdict, "full", false);
|
||||
enum NewImageMode mode;
|
||||
Error *err = NULL;
|
||||
DriveBackup backup = {
|
||||
.device = (char *)device,
|
||||
.target = (char *)filename,
|
||||
.has_format = !!format,
|
||||
.format = (char *)format,
|
||||
.sync = full ? MIRROR_SYNC_MODE_FULL : MIRROR_SYNC_MODE_TOP,
|
||||
.has_mode = true,
|
||||
.mode = reuse ? NEW_IMAGE_MODE_EXISTING : NEW_IMAGE_MODE_ABSOLUTE_PATHS,
|
||||
};
|
||||
|
||||
if (!filename) {
|
||||
error_setg(&err, QERR_MISSING_PARAMETER, "target");
|
||||
@ -1118,16 +1126,7 @@ void hmp_drive_backup(Monitor *mon, const QDict *qdict)
|
||||
return;
|
||||
}
|
||||
|
||||
if (reuse) {
|
||||
mode = NEW_IMAGE_MODE_EXISTING;
|
||||
} else {
|
||||
mode = NEW_IMAGE_MODE_ABSOLUTE_PATHS;
|
||||
}
|
||||
|
||||
qmp_drive_backup(false, NULL, device, filename, !!format, format,
|
||||
full ? MIRROR_SYNC_MODE_FULL : MIRROR_SYNC_MODE_TOP,
|
||||
true, mode, false, 0, false, NULL,
|
||||
false, 0, false, 0, &err);
|
||||
qmp_drive_backup(&backup, &err);
|
||||
hmp_handle_error(mon, &err);
|
||||
}
|
||||
|
||||
|
@ -1091,7 +1091,8 @@
|
||||
#
|
||||
# Since 1.6
|
||||
##
|
||||
{ 'command': 'drive-backup', 'data': 'DriveBackup' }
|
||||
{ 'command': 'drive-backup', 'boxed': true,
|
||||
'data': 'DriveBackup' }
|
||||
|
||||
##
|
||||
# @blockdev-backup
|
||||
|
Loading…
Reference in New Issue
Block a user