提交 df92562e 编写于 作者: F Fam Zheng 提交者: Max Reitz

qmp: Add blockdev-mirror command

This will start a mirror job from a named device to another named
device, its relation with drive-mirror is similar with blockdev-backup
to drive-backup.

In blockdev-mirror, the target node should be prepared by blockdev-add,
which will be responsible for assigning a name to the new node, so
we don't have 'node-name' parameter.
Signed-off-by: NFam Zheng <famz@redhat.com>
Acked-by: NMarkus Armbruster <armbru@redhat.com>
Message-id: 1450932306-13717-5-git-send-email-famz@redhat.com
Reviewed-by: NMax Reitz <mreitz@redhat.com>
Signed-off-by: NMax Reitz <mreitz@redhat.com>
上级 e40e5027
......@@ -3345,6 +3345,10 @@ static void blockdev_mirror_common(BlockDriverState *bs,
if (bdrv_op_is_blocked(target, BLOCK_OP_TYPE_MIRROR_TARGET, errp)) {
return;
}
if (target->blk) {
error_setg(errp, "Cannot mirror to an attached block device");
return;
}
if (!bs->backing && sync == MIRROR_SYNC_MODE_TOP) {
sync = MIRROR_SYNC_MODE_FULL;
......@@ -3518,6 +3522,64 @@ out:
aio_context_release(aio_context);
}
void qmp_blockdev_mirror(const char *device, const char *target,
bool has_replaces, const char *replaces,
MirrorSyncMode sync,
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,
Error **errp)
{
BlockDriverState *bs;
BlockBackend *blk;
BlockDriverState *target_bs;
AioContext *aio_context;
Error *local_err = NULL;
blk = blk_by_name(device);
if (!blk) {
error_setg(errp, "Device '%s' not found", device);
return;
}
bs = blk_bs(blk);
if (!bs) {
error_setg(errp, "Device '%s' has no media", device);
return;
}
target_bs = bdrv_lookup_bs(target, target, errp);
if (!target_bs) {
return;
}
aio_context = bdrv_get_aio_context(bs);
aio_context_acquire(aio_context);
bdrv_ref(target_bs);
bdrv_set_aio_context(target_bs, aio_context);
blockdev_mirror_common(bs, target_bs,
has_replaces, replaces, sync,
has_speed, speed,
has_granularity, granularity,
has_buf_size, buf_size,
has_on_source_error, on_source_error,
has_on_target_error, on_target_error,
true, true,
&local_err);
if (local_err) {
error_propagate(errp, local_err);
bdrv_unref(target_bs);
}
aio_context_release(aio_context);
}
/* Get the block job for a given device name and acquire its AioContext */
static BlockJob *find_block_job(const char *device, AioContext **aio_context,
Error **errp)
......
......@@ -1183,6 +1183,54 @@
{ 'command': 'block-dirty-bitmap-clear',
'data': 'BlockDirtyBitmap' }
##
# @blockdev-mirror
#
# Start mirroring a block device's writes to a new destination.
#
# @device: the name of the device whose writes should be mirrored.
#
# @target: the id or node-name of the block device to mirror to. This mustn't be
# attached to guest.
#
# @replaces: #optional with sync=full graph node name to be replaced by the new
# image when a whole image copy is done. This can be used to repair
# broken Quorum files.
#
# @speed: #optional the maximum speed, in bytes per second
#
# @sync: what parts of the disk image should be copied to the destination
# (all the disk, only the sectors allocated in the topmost image, or
# only new I/O).
#
# @granularity: #optional granularity of the dirty bitmap, default is 64K
# if the image format doesn't have clusters, 4K if the clusters
# are smaller than that, else the cluster size. Must be a
# power of 2 between 512 and 64M
#
# @buf-size: #optional maximum amount of data in flight from source to
# target
#
# @on-source-error: #optional the action to take on an error on the source,
# default 'report'. 'stop' and 'enospc' can only be used
# if the block device supports io-status (see BlockInfo).
#
# @on-target-error: #optional the action to take on an error on the target,
# default 'report' (no limitations, since this applies to
# a different block device than @device).
#
# Returns: nothing on success.
#
# Since 2.6
##
{ 'command': 'blockdev-mirror',
'data': { 'device': 'str', 'target': 'str',
'*replaces': 'str',
'sync': 'MirrorSyncMode',
'*speed': 'int', '*granularity': 'uint32',
'*buf-size': 'int', '*on-source-error': 'BlockdevOnError',
'*on-target-error': 'BlockdevOnError' } }
##
# @block_set_io_throttle:
#
......
......@@ -1635,7 +1635,7 @@ Arguments:
- "speed": maximum speed of the streaming job, in bytes per second
(json-int)
- "granularity": granularity of the dirty bitmap, in bytes (json-int, optional)
- "buf_size": maximum amount of data in flight from source to target, in bytes
- "buf-size": maximum amount of data in flight from source to target, in bytes
(json-int, default 10M)
- "sync": what parts of the disk image should be copied to the destination;
possibilities include "full" for all the disk, "top" for only the sectors
......@@ -1664,6 +1664,54 @@ Example:
EQMP
{
.name = "blockdev-mirror",
.args_type = "sync:s,device:B,target:B,replaces:s?,speed:i?,"
"on-source-error:s?,on-target-error:s?,"
"granularity:i?,buf-size:i?",
.mhandler.cmd_new = qmp_marshal_blockdev_mirror,
},
SQMP
blockdev-mirror
------------
Start mirroring a block device's writes to another block device. target
specifies the target of mirror operation.
Arguments:
- "device": device name to operate on (json-string)
- "target": device name to mirror to (json-string)
- "replaces": the block driver node name to replace when finished
(json-string, optional)
- "speed": maximum speed of the streaming job, in bytes per second
(json-int)
- "granularity": granularity of the dirty bitmap, in bytes (json-int, optional)
- "buf_size": maximum amount of data in flight from source to target, in bytes
(json-int, default 10M)
- "sync": what parts of the disk image should be copied to the destination;
possibilities include "full" for all the disk, "top" for only the sectors
allocated in the topmost image, or "none" to only replicate new I/O
(MirrorSyncMode).
- "on-source-error": the action to take on an error on the source
(BlockdevOnError, default 'report')
- "on-target-error": the action to take on an error on the target
(BlockdevOnError, default 'report')
The default value of the granularity is the image cluster size clamped
between 4096 and 65536, if the image format defines one. If the format
does not define a cluster size, the default value of the granularity
is 65536.
Example:
-> { "execute": "blockdev-mirror", "arguments": { "device": "ide-hd0",
"target": "target0",
"sync": "full" } }
<- { "return": {} }
EQMP
{
.name = "change-backing-file",
.args_type = "device:s,image-node-name:s,backing-file:s",
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册