block: Extract blockdev part of qmp_drive_mirror
This is the part that will be reused by blockdev-mirror. Signed-off-by: Fam Zheng <famz@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Message-id: 1450932306-13717-3-git-send-email-famz@redhat.com Signed-off-by: Max Reitz <mreitz@redhat.com>
This commit is contained in:
parent
05e4d14bf3
commit
4193cdd771
114
blockdev.c
114
blockdev.c
@ -3291,29 +3291,23 @@ void qmp_blockdev_backup(const char *device, const char *target,
|
|||||||
NULL, errp);
|
NULL, errp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void qmp_drive_mirror(const char *device, const char *target,
|
/* Parameter check and block job starting for drive mirroring.
|
||||||
bool has_format, const char *format,
|
* Caller should hold @device and @target's aio context (must be the same).
|
||||||
bool has_node_name, const char *node_name,
|
**/
|
||||||
bool has_replaces, const char *replaces,
|
static void blockdev_mirror_common(BlockDriverState *bs,
|
||||||
enum MirrorSyncMode sync,
|
BlockDriverState *target,
|
||||||
bool has_mode, enum NewImageMode mode,
|
bool has_replaces, const char *replaces,
|
||||||
bool has_speed, int64_t speed,
|
enum MirrorSyncMode sync,
|
||||||
bool has_granularity, uint32_t granularity,
|
bool has_speed, int64_t speed,
|
||||||
bool has_buf_size, int64_t buf_size,
|
bool has_granularity, uint32_t granularity,
|
||||||
bool has_on_source_error, BlockdevOnError on_source_error,
|
bool has_buf_size, int64_t buf_size,
|
||||||
bool has_on_target_error, BlockdevOnError on_target_error,
|
bool has_on_source_error,
|
||||||
bool has_unmap, bool unmap,
|
BlockdevOnError on_source_error,
|
||||||
Error **errp)
|
bool has_on_target_error,
|
||||||
|
BlockdevOnError on_target_error,
|
||||||
|
bool has_unmap, bool unmap,
|
||||||
|
Error **errp)
|
||||||
{
|
{
|
||||||
BlockBackend *blk;
|
|
||||||
BlockDriverState *bs;
|
|
||||||
BlockDriverState *source, *target_bs;
|
|
||||||
AioContext *aio_context;
|
|
||||||
Error *local_err = NULL;
|
|
||||||
QDict *options;
|
|
||||||
int flags;
|
|
||||||
int64_t size;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (!has_speed) {
|
if (!has_speed) {
|
||||||
speed = 0;
|
speed = 0;
|
||||||
@ -3324,9 +3318,6 @@ void qmp_drive_mirror(const char *device, const char *target,
|
|||||||
if (!has_on_target_error) {
|
if (!has_on_target_error) {
|
||||||
on_target_error = BLOCKDEV_ON_ERROR_REPORT;
|
on_target_error = BLOCKDEV_ON_ERROR_REPORT;
|
||||||
}
|
}
|
||||||
if (!has_mode) {
|
|
||||||
mode = NEW_IMAGE_MODE_ABSOLUTE_PATHS;
|
|
||||||
}
|
|
||||||
if (!has_granularity) {
|
if (!has_granularity) {
|
||||||
granularity = 0;
|
granularity = 0;
|
||||||
}
|
}
|
||||||
@ -3348,6 +3339,48 @@ void qmp_drive_mirror(const char *device, const char *target,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_MIRROR_SOURCE, errp)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bs->backing && sync == MIRROR_SYNC_MODE_TOP) {
|
||||||
|
sync = MIRROR_SYNC_MODE_FULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* pass the node name to replace to mirror start since it's loose coupling
|
||||||
|
* and will allow to check whether the node still exist at mirror completion
|
||||||
|
*/
|
||||||
|
mirror_start(bs, target,
|
||||||
|
has_replaces ? replaces : NULL,
|
||||||
|
speed, granularity, buf_size, sync,
|
||||||
|
on_source_error, on_target_error, unmap,
|
||||||
|
block_job_cb, bs, errp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void qmp_drive_mirror(const char *device, const char *target,
|
||||||
|
bool has_format, const char *format,
|
||||||
|
bool has_node_name, const char *node_name,
|
||||||
|
bool has_replaces, const char *replaces,
|
||||||
|
enum MirrorSyncMode sync,
|
||||||
|
bool has_mode, enum NewImageMode mode,
|
||||||
|
bool has_speed, int64_t speed,
|
||||||
|
bool has_granularity, uint32_t granularity,
|
||||||
|
bool has_buf_size, int64_t buf_size,
|
||||||
|
bool has_on_source_error, BlockdevOnError on_source_error,
|
||||||
|
bool has_on_target_error, BlockdevOnError on_target_error,
|
||||||
|
bool has_unmap, bool unmap,
|
||||||
|
Error **errp)
|
||||||
|
{
|
||||||
|
BlockDriverState *bs;
|
||||||
|
BlockBackend *blk;
|
||||||
|
BlockDriverState *source, *target_bs;
|
||||||
|
AioContext *aio_context;
|
||||||
|
Error *local_err = NULL;
|
||||||
|
QDict *options = NULL;
|
||||||
|
int flags;
|
||||||
|
int64_t size;
|
||||||
|
int ret;
|
||||||
|
|
||||||
blk = blk_by_name(device);
|
blk = blk_by_name(device);
|
||||||
if (!blk) {
|
if (!blk) {
|
||||||
error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
|
error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
|
||||||
@ -3363,15 +3396,14 @@ void qmp_drive_mirror(const char *device, const char *target,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
bs = blk_bs(blk);
|
bs = blk_bs(blk);
|
||||||
|
if (!has_mode) {
|
||||||
|
mode = NEW_IMAGE_MODE_ABSOLUTE_PATHS;
|
||||||
|
}
|
||||||
|
|
||||||
if (!has_format) {
|
if (!has_format) {
|
||||||
format = mode == NEW_IMAGE_MODE_EXISTING ? NULL : bs->drv->format_name;
|
format = mode == NEW_IMAGE_MODE_EXISTING ? NULL : bs->drv->format_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_MIRROR_SOURCE, errp)) {
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
flags = bs->open_flags | BDRV_O_RDWR;
|
flags = bs->open_flags | BDRV_O_RDWR;
|
||||||
source = backing_bs(bs);
|
source = backing_bs(bs);
|
||||||
if (!source && sync == MIRROR_SYNC_MODE_TOP) {
|
if (!source && sync == MIRROR_SYNC_MODE_TOP) {
|
||||||
@ -3466,21 +3498,19 @@ void qmp_drive_mirror(const char *device, const char *target,
|
|||||||
|
|
||||||
bdrv_set_aio_context(target_bs, aio_context);
|
bdrv_set_aio_context(target_bs, aio_context);
|
||||||
|
|
||||||
/* pass the node name to replace to mirror start since it's loose coupling
|
blockdev_mirror_common(bs, target_bs,
|
||||||
* and will allow to check whether the node still exist at mirror completion
|
has_replaces, replaces, sync,
|
||||||
*/
|
has_speed, speed,
|
||||||
mirror_start(bs, target_bs,
|
has_granularity, granularity,
|
||||||
has_replaces ? replaces : NULL,
|
has_buf_size, buf_size,
|
||||||
speed, granularity, buf_size, sync,
|
has_on_source_error, on_source_error,
|
||||||
on_source_error, on_target_error,
|
has_on_target_error, on_target_error,
|
||||||
unmap,
|
has_unmap, unmap,
|
||||||
block_job_cb, bs, &local_err);
|
&local_err);
|
||||||
if (local_err != NULL) {
|
if (local_err) {
|
||||||
bdrv_unref(target_bs);
|
|
||||||
error_propagate(errp, local_err);
|
error_propagate(errp, local_err);
|
||||||
goto out;
|
bdrv_unref(target_bs);
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
aio_context_release(aio_context);
|
aio_context_release(aio_context);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user