summaryrefslogtreecommitdiff
path: root/blockdev.c
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2012-03-06 18:55:59 +0100
committerKevin Wolf <kwolf@redhat.com>2012-03-12 15:14:07 +0100
commit6cc2a4157b31c47303da96c5ed7836db3c10def6 (patch)
treef31c97b9ca1ffffd7eb7c8aef2ab933b36d3479a /blockdev.c
parentbc8b094feb61c5f3ad55113f1c9b3288dd843b10 (diff)
downloadqemu-6cc2a4157b31c47303da96c5ed7836db3c10def6.tar.gz
qmp: convert blockdev-snapshot-sync to a wrapper around transactions
Simplify the blockdev-snapshot-sync code and gain failsafe operation by turning it into a wrapper around the new transaction command. A new option is also added matching "mode". Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'blockdev.c')
-rw-r--r--blockdev.c85
1 files changed, 23 insertions, 62 deletions
diff --git a/blockdev.c b/blockdev.c
index 0a6edc3e14..1a500b830d 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -649,72 +649,33 @@ void do_commit(Monitor *mon, const QDict *qdict)
}
}
+static void blockdev_do_action(int kind, void *data, Error **errp)
+{
+ BlockdevAction action;
+ BlockdevActionList list;
+
+ action.kind = kind;
+ action.data = data;
+ list.value = &action;
+ list.next = NULL;
+ qmp_transaction(&list, errp);
+}
+
void qmp_blockdev_snapshot_sync(const char *device, const char *snapshot_file,
bool has_format, const char *format,
+ bool has_mode, enum NewImageMode mode,
Error **errp)
{
- BlockDriverState *bs;
- BlockDriver *drv, *old_drv, *proto_drv;
- int ret = 0;
- int flags;
- char old_filename[1024];
-
- bs = bdrv_find(device);
- if (!bs) {
- error_set(errp, QERR_DEVICE_NOT_FOUND, device);
- return;
- }
- if (bdrv_in_use(bs)) {
- error_set(errp, QERR_DEVICE_IN_USE, device);
- return;
- }
-
- pstrcpy(old_filename, sizeof(old_filename), bs->filename);
-
- old_drv = bs->drv;
- flags = bs->open_flags;
-
- if (!has_format) {
- format = "qcow2";
- }
-
- drv = bdrv_find_format(format);
- if (!drv) {
- error_set(errp, QERR_INVALID_BLOCK_FORMAT, format);
- return;
- }
-
- proto_drv = bdrv_find_protocol(snapshot_file);
- if (!proto_drv) {
- error_set(errp, QERR_INVALID_BLOCK_FORMAT, format);
- return;
- }
-
- ret = bdrv_img_create(snapshot_file, format, bs->filename,
- bs->drv->format_name, NULL, -1, flags);
- if (ret) {
- error_set(errp, QERR_UNDEFINED_ERROR);
- return;
- }
-
- bdrv_drain_all();
- bdrv_flush(bs);
-
- bdrv_close(bs);
- ret = bdrv_open(bs, snapshot_file, flags, drv);
- /*
- * If reopening the image file we just created fails, fall back
- * and try to re-open the original image. If that fails too, we
- * are in serious trouble.
- */
- if (ret != 0) {
- ret = bdrv_open(bs, old_filename, flags, old_drv);
- if (ret != 0) {
- error_set(errp, QERR_OPEN_FILE_FAILED, old_filename);
- } else {
- error_set(errp, QERR_OPEN_FILE_FAILED, snapshot_file);
- }
- }
+ BlockdevSnapshot snapshot = {
+ .device = (char *) device,
+ .snapshot_file = (char *) snapshot_file,
+ .has_format = has_format,
+ .format = (char *) format,
+ .has_mode = has_mode,
+ .mode = mode,
+ };
+ blockdev_do_action(BLOCKDEV_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC, &snapshot,
+ errp);
}