Now qmp_transaction support creating internal snapshot. Signed-off-by: Wenchao Xia <xiaw...@linux.vnet.ibm.com> --- blockdev.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ qapi-schema.json | 29 +++++++++++++++++++++++++++++ qmp-commands.hx | 24 +++++++++++++++++------- 3 files changed, 92 insertions(+), 7 deletions(-)
diff --git a/blockdev.c b/blockdev.c index 299039f..09eeb7f 100644 --- a/blockdev.c +++ b/blockdev.c @@ -1218,6 +1218,41 @@ static int fill_blk_trs_ext_create_sync(BlockdevSnapshot *create_sync, return 0; } +static int fill_blk_trs_int_create_sync(BlockdevSnapshotInternal *create_sync, + BlkTransStatesSync *st_sync, + SNTime *time, + const char *time_str, + Error **errp) +{ + BlockDriverState *bs; + const char *device = create_sync->device; + const char *name = NULL; + + if (create_sync->has_name) { + name = create_sync->name; + } + + /* find the target bs */ + bs = bdrv_find(device); + if (!bs) { + error_set(errp, QERR_DEVICE_NOT_FOUND, device); + return -1; + } + + st_sync->use_existing = false; + + /* internal case, if caller need create new one with default string */ + if (name == NULL) { + st_sync->internal.sn_name = time_str; + } else { + st_sync->internal.sn_name = name; + } + st_sync->internal.bs = bs; + st_sync->internal.time = *time; + + return 0; +} + static int fill_blk_trs(BlockdevAction *dev_info, BlkTransStates *states, SNTime *time, @@ -1234,6 +1269,17 @@ static int fill_blk_trs(BlockdevAction *dev_info, &states->st_sync, errp); break; + case BLOCKDEV_ACTION_KIND_BLOCKDEV_SNAPSHOT_INTERNAL_SYNC: + states->st_sync.type = BLK_SNAPSHOT_INTERNAL; + states->st_sync.op = BLK_SN_SYNC_CREATE; + BlockdevSnapshotInternal *create_sync; + create_sync = dev_info->blockdev_snapshot_internal_sync; + ret = fill_blk_trs_int_create_sync(create_sync, + &states->st_sync, + time, + time_str, + errp); + break; default: abort(); } diff --git a/qapi-schema.json b/qapi-schema.json index 5dfa052..ea3ef77 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -1474,6 +1474,20 @@ 'data': [ 'existing', 'absolute-paths' ] } ## +# @NewSnapshotMode +# +# An enumeration that tells QEMU how to create internal snapshot. +# +# @existing: QEMU should look for an existing snapshot. +# +# @new: QEMU should create a new internal snapshot, if it exist, overwrite it. +# +# Since: 1.4 +## +{ 'enum': 'NewSnapshotMode' + 'data': [ 'existing', 'new' ] } + +## # @BlockdevSnapshot # # @device: the name of the device to generate the snapshot from. @@ -1490,6 +1504,20 @@ '*mode': 'NewImageMode' } } ## +# @BlockdevSnapshotInternal +# +# @device: the name of the device to generate the snapshot from. +# +# @name: #optional the name of the internal snapshot to create, default is to +# generate it automatically according to host time. If a snapshot with +# name exist, it will be overwritten. +# +# Since: 1.4 +## +{ 'type': 'BlockdevSnapshotInternal', + 'data': { 'device': 'str', '*name': 'str', } } + +## # @BlockdevAction # # A discriminated record of operations that can be performed with @@ -1498,6 +1526,7 @@ { 'union': 'BlockdevAction', 'data': { 'blockdev-snapshot-sync': 'BlockdevSnapshot', + 'blockdev-snapshot-internal-sync': 'BlockdevSnapshotInternal', } } ## diff --git a/qmp-commands.hx b/qmp-commands.hx index 5c692d0..3c2f468 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -863,10 +863,13 @@ 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. +For external snapshots this is the device, the file to use for the new +snapshot, and the format. The default format, if not specified, is qcow2. +For internal snapshots this is the device, the snapshot name. If name is +not specified, it would be generated automatically according to host time. +If an internal snapshot with name exist, it will be over written. -Each new snapshot defaults to being created by QEMU (wiping any +Each new external snapshot defaults to being created by QEMU (wiping any contents if the file already exists), but it is also possible to reuse an externally-created file. In the latter case, you should ensure that the new image file has the same contents as the current one; QEMU cannot @@ -876,15 +879,20 @@ current image file as the backing file for the new image. Arguments: actions array: - - "type": the operation to perform. The only supported - value is "blockdev-snapshot-sync". (json-string) + - "type": the operation to perform. The supported values are + "blockdev-snapshot-sync" and "blockdev-snapshot-internal-sync". + (json-string) - "data": a dictionary. The contents depend on the value - of "type". When "type" is "blockdev-snapshot-sync": + 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) - "mode": whether and how QEMU should create the snapshot file (NewImageMode, optional, default "absolute-paths") + When "type" is "blockdev-snapshot-internal-sync": + - "device": device name to snapshot (json-string) + - "name": name of internal snapshot (json-string, optional) Example: @@ -896,7 +904,9 @@ Example: { 'type': 'blockdev-snapshot-sync', 'data' : { "device": "ide-hd1", "snapshot-file": "/some/place/my-image2", "mode": "existing", - "format": "qcow2" } } ] } } + "format": "qcow2" } }, + { 'type': 'blockdev-snapshot-internal-sync', 'data' : { "device": "ide-hd2", + "name": "snapshot0" } } ] } } <- { "return": {} } EQMP -- 1.7.1