提交 52e7c241 编写于 作者: P Paolo Bonzini 提交者: Kevin Wolf

rename blockdev-group-snapshot-sync

We will add other kinds of operation.  Prepare for this by adjusting
the schema.
Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
Signed-off-by: NKevin Wolf <kwolf@redhat.com>
上级 dc8fb6df
......@@ -719,31 +719,24 @@ void qmp_blockdev_snapshot_sync(const char *device, const char *snapshot_file,
/* New and old BlockDriverState structs for group snapshots */
typedef struct BlkGroupSnapshotStates {
typedef struct BlkTransactionStates {
BlockDriverState *old_bs;
BlockDriverState *new_bs;
QSIMPLEQ_ENTRY(BlkGroupSnapshotStates) entry;
} BlkGroupSnapshotStates;
QSIMPLEQ_ENTRY(BlkTransactionStates) entry;
} BlkTransactionStates;
/*
* 'Atomic' group snapshots. The snapshots are taken as a set, and if any fail
* then we do not pivot any of the devices in the group, and abandon the
* snapshots
*/
void qmp_blockdev_group_snapshot_sync(SnapshotDevList *dev_list,
Error **errp)
void qmp_transaction(BlockdevActionList *dev_list, Error **errp)
{
int ret = 0;
SnapshotDevList *dev_entry = dev_list;
SnapshotDev *dev_info = NULL;
BlkGroupSnapshotStates *states, *next;
BlockDriver *proto_drv;
BlockDriver *drv;
int flags;
const char *format;
const char *snapshot_file;
BlockdevActionList *dev_entry = dev_list;
BlkTransactionStates *states, *next;
QSIMPLEQ_HEAD(snap_bdrv_states, BlkGroupSnapshotStates) snap_bdrv_states;
QSIMPLEQ_HEAD(snap_bdrv_states, BlkTransactionStates) snap_bdrv_states;
QSIMPLEQ_INIT(&snap_bdrv_states);
/* drain all i/o before any snapshots */
......@@ -751,21 +744,46 @@ void qmp_blockdev_group_snapshot_sync(SnapshotDevList *dev_list,
/* We don't do anything in this loop that commits us to the snapshot */
while (NULL != dev_entry) {
BlockdevAction *dev_info = NULL;
BlockDriver *proto_drv;
BlockDriver *drv;
int flags;
const char *device;
const char *format = "qcow2";
const char *new_image_file = NULL;
dev_info = dev_entry->value;
dev_entry = dev_entry->next;
states = g_malloc0(sizeof(BlkGroupSnapshotStates));
states = g_malloc0(sizeof(BlkTransactionStates));
QSIMPLEQ_INSERT_TAIL(&snap_bdrv_states, states, entry);
states->old_bs = bdrv_find(dev_info->device);
switch (dev_info->kind) {
case BLOCKDEV_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC:
device = dev_info->blockdev_snapshot_sync->device;
if (dev_info->blockdev_snapshot_sync->has_format) {
format = dev_info->blockdev_snapshot_sync->format;
}
new_image_file = dev_info->blockdev_snapshot_sync->snapshot_file;
break;
default:
abort();
}
drv = bdrv_find_format(format);
if (!drv) {
error_set(errp, QERR_INVALID_BLOCK_FORMAT, format);
goto delete_and_fail;
}
states->old_bs = bdrv_find(device);
if (!states->old_bs) {
error_set(errp, QERR_DEVICE_NOT_FOUND, dev_info->device);
error_set(errp, QERR_DEVICE_NOT_FOUND, device);
goto delete_and_fail;
}
if (bdrv_in_use(states->old_bs)) {
error_set(errp, QERR_DEVICE_IN_USE, dev_info->device);
error_set(errp, QERR_DEVICE_IN_USE, device);
goto delete_and_fail;
}
......@@ -778,44 +796,30 @@ void qmp_blockdev_group_snapshot_sync(SnapshotDevList *dev_list,
}
}
snapshot_file = dev_info->snapshot_file;
flags = states->old_bs->open_flags;
if (!dev_info->has_format) {
format = "qcow2";
} else {
format = dev_info->format;
}
drv = bdrv_find_format(format);
if (!drv) {
error_set(errp, QERR_INVALID_BLOCK_FORMAT, format);
goto delete_and_fail;
}
proto_drv = bdrv_find_protocol(snapshot_file);
proto_drv = bdrv_find_protocol(new_image_file);
if (!proto_drv) {
error_set(errp, QERR_INVALID_BLOCK_FORMAT, format);
goto delete_and_fail;
}
/* create new image w/backing file */
ret = bdrv_img_create(snapshot_file, format,
ret = bdrv_img_create(new_image_file, format,
states->old_bs->filename,
states->old_bs->drv->format_name,
NULL, -1, flags);
if (ret) {
error_set(errp, QERR_OPEN_FILE_FAILED, snapshot_file);
error_set(errp, QERR_OPEN_FILE_FAILED, new_image_file);
goto delete_and_fail;
}
/* We will manually add the backing_hd field to the bs later */
states->new_bs = bdrv_new("");
ret = bdrv_open(states->new_bs, snapshot_file,
ret = bdrv_open(states->new_bs, new_image_file,
flags | BDRV_O_NO_BACKING, drv);
if (ret != 0) {
error_set(errp, QERR_OPEN_FILE_FAILED, snapshot_file);
error_set(errp, QERR_OPEN_FILE_FAILED, new_image_file);
goto delete_and_fail;
}
}
......
......@@ -1118,7 +1118,7 @@
{ 'command': 'block_resize', 'data': { 'device': 'str', 'size': 'int' }}
##
# @SnapshotDev
# @BlockdevSnapshot
#
# @device: the name of the device to generate the snapshot from.
#
......@@ -1126,19 +1126,30 @@
#
# @format: #optional the format of the snapshot image, default is 'qcow2'.
##
{ 'type': 'SnapshotDev',
'data': {'device': 'str', 'snapshot-file': 'str', '*format': 'str' } }
{ 'type': 'BlockdevSnapshot',
'data': { 'device': 'str', 'snapshot-file': 'str', '*format': 'str' } }
##
# @BlockdevAction
#
# A discriminated record of operations that can be performed with
# @transaction.
##
{ 'union': 'BlockdevAction',
'data': {
'blockdev-snapshot-sync': 'BlockdevSnapshot',
} }
##
# @blockdev-group-snapshot-sync
# @transaction
#
# Generates a synchronous snapshot of a group of one or more block devices,
# as atomically as possible. If the snapshot of any device in the group
# fails, then the entire group snapshot will be abandoned and the
# appropriate error returned.
# Atomically operate on a group of one or more block devices. If
# any operation fails, then the entire set of actions will be
# abandoned and the appropriate error returned. The only operation
# supported is currently blockdev-snapshot-sync.
#
# List of:
# @SnapshotDev: information needed for the device snapshot
# @BlockdevAction: information needed for the device snapshot
#
# Returns: nothing on success
# If @device is not a valid block device, DeviceNotFound
......@@ -1147,13 +1158,14 @@
# If @snapshot-file can't be opened, OpenFileFailed
# If @format is invalid, InvalidBlockFormat
#
# Note: The group snapshot attempt returns failure on the first snapshot
# device failure. Therefore, there will be only one device or snapshot file
# returned in an error condition, and subsequent devices will not have been
# attempted.
# Note: The transaction aborts on the first failure. Therefore, there will
# be only one device or snapshot file returned in an error condition, and
# subsequent actions will not have been attempted.
#
# Since 1.1
##
{ 'command': 'blockdev-group-snapshot-sync',
'data': { 'devlist': [ 'SnapshotDev' ] } }
{ 'command': 'transaction',
'data': { 'actions': [ 'BlockdevAction' ] } }
##
# @blockdev-snapshot-sync
......
......@@ -687,41 +687,45 @@ EQMP
.mhandler.cmd_new = qmp_marshal_input_block_job_cancel,
},
{
.name = "blockdev-group-snapshot-sync",
.args_type = "devlist:O",
.params = "device:B,snapshot-file:s,format:s?",
.mhandler.cmd_new = qmp_marshal_input_blockdev_group_snapshot_sync,
.name = "transaction",
.args_type = "actions:O",
.mhandler.cmd_new = qmp_marshal_input_transaction,
},
SQMP
blockdev-group-snapshot-sync
----------------------
Synchronous snapshot of one or more block devices. A list array input
is accepted, that contains the device and snapshot file information for
each device in group. The default format, if not specified, is qcow2.
transaction
-----------
If there is any failure creating or opening a new snapshot, all snapshots
for the group are abandoned, and the original disks pre-snapshot attempt
are used.
Atomically operate on one or more block devices. The only supported
operation for now is snapshotting. If there is any failure performing
any of the operations, all snapshots for the group are abandoned, and
the original disks pre-snapshot attempt are used.
A list of dictionaries is accepted, that contains the actions to be performed.
For snapshots this is the device, the file to use for the new snapshot,
and the format. The default format, if not specified, is qcow2.
Arguments:
devlist array:
- "device": device name to snapshot (json-string)
- "snapshot-file": name of new image file (json-string)
- "format": format of new image (json-string, optional)
actions array:
- "type": the operation to perform. The only supported
value is "blockdev-snapshot-sync". (json-string)
- "data": a dictionary. The contents depend on the value
of "type". When "type" is "blockdev-snapshot-sync":
- "device": device name to snapshot (json-string)
- "snapshot-file": name of new image file (json-string)
- "format": format of new image (json-string, optional)
Example:
-> { "execute": "blockdev-group-snapshot-sync", "arguments":
{ "devlist": [{ "device": "ide-hd0",
"snapshot-file": "/some/place/my-image",
"format": "qcow2" },
{ "device": "ide-hd1",
"snapshot-file": "/some/place/my-image2",
"format": "qcow2" }] } }
-> { "execute": "transaction",
"arguments": { "actions": [
{ 'type': 'blockdev-snapshot-sync', 'data' : { "device": "ide-hd0",
"snapshot-file": "/some/place/my-image",
"format": "qcow2" } },
{ 'type': 'blockdev-snapshot-sync', 'data' : { "device": "ide-hd1",
"snapshot-file": "/some/place/my-image2",
"format": "qcow2" } } ] } }
<- { "return": {} }
EQMP
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册