From 49a89a5341394df30e48b99fe789403656d1144d Mon Sep 17 00:00:00 2001 From: Federico Simoncelli Date: Fri, 23 Mar 2012 12:12:51 -0300 Subject: [RHEL6 qemu-kvm PATCH 6/9] rename blockdev-group-snapshot-sync RH-Author: Federico Simoncelli Message-id: <1332504778-17403-7-git-send-email-fsimonce@redhat.com> Patchwork-id: 38945 O-Subject: [RHEL6.3 qemu-kvm PATCH v6 06/13] rename blockdev-group-snapshot-sync Bugzilla: 802284 RH-Acked-by: Laszlo Ersek RH-Acked-by: Kevin Wolf RH-Acked-by: Jeffrey Cody From: Paolo Bonzini We will add other kinds of operation. Prepare for this by adjusting the schema. Signed-off-by: Paolo Bonzini Signed-off-by: Kevin Wolf BZ: 802284 (cherry picked from commit 52e7c241ac766406f05fa331eec9dbb33ebd2640) --- blockdev.c | 80 ++++++++++++++++++++++++++++------------------------- qapi-schema.json | 42 ++++++++++++++++++---------- qemu-monitor.hx | 52 +++++++++++++++++++---------------- 3 files changed, 97 insertions(+), 77 deletions(-) Signed-off-by: Eduardo Habkost --- blockdev.c | 80 ++++++++++++++++++++++++++++------------------------- qapi-schema.json | 42 ++++++++++++++++++---------- qemu-monitor.hx | 52 +++++++++++++++++++---------------- 3 files changed, 97 insertions(+), 77 deletions(-) diff --git a/blockdev.c b/blockdev.c index d571c4b..70cc2e4 100644 --- a/blockdev.c +++ b/blockdev.c @@ -702,31 +702,24 @@ void qmp_blockdev_snapshot_sync(const char *device, const char *snapshot_file, #ifdef CONFIG_LIVE_SNAPSHOTS /* 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 */ @@ -734,21 +727,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; } @@ -761,49 +779,35 @@ 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; } if (!bdrv_is_inserted(states->old_bs)) { - error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, dev_info->device); + error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, device); 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; } } diff --git a/qapi-schema.json b/qapi-schema.json index 59edf0e..e262321 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -4,7 +4,7 @@ #ifdef CONFIG_LIVE_SNAPSHOTS ## -# @SnapshotDev +# @BlockdevSnapshot # # @device: the name of the device to generate the snapshot from. # @@ -12,19 +12,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 @@ -33,13 +44,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 diff --git a/qemu-monitor.hx b/qemu-monitor.hx index ac032ec..75ffc52 100644 --- a/qemu-monitor.hx +++ b/qemu-monitor.hx @@ -1483,43 +1483,47 @@ ETEXI #ifdef CONFIG_LIVE_SNAPSHOTS { - .name = "blockdev-group-snapshot-sync", - .args_type = "devlist:O", - .params = "device:B,snapshot-file:s,format:s?", + .name = "transaction", + .args_type = "actions:O", .user_print = monitor_user_noop, - .mhandler.cmd_new = qmp_marshal_input_blockdev_group_snapshot_sync, + .mhandler.cmd_new = qmp_marshal_input_transaction, }, #endif 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 -- 1.7.3.2