|
|
9ae3a8 |
From 9845ad55c470e47c0074d92611bf9fb2903ab58a Mon Sep 17 00:00:00 2001
|
|
|
9ae3a8 |
From: Kevin Wolf <kwolf@redhat.com>
|
|
|
9ae3a8 |
Date: Mon, 9 Sep 2013 14:27:52 +0200
|
|
|
9ae3a8 |
Subject: [PATCH 01/38] block: package preparation code in qmp_transaction()
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
|
|
9ae3a8 |
Message-id: <1378736903-18489-2-git-send-email-kwolf@redhat.com>
|
|
|
9ae3a8 |
Patchwork-id: 54188
|
|
|
9ae3a8 |
O-Subject: [RHEL-7.0 qemu-kvm PATCH 01/32] block: package preparation code in qmp_transaction()
|
|
|
9ae3a8 |
Bugzilla: 1005818
|
|
|
9ae3a8 |
RH-Acked-by: Fam Zheng <famz@redhat.com>
|
|
|
9ae3a8 |
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
|
|
9ae3a8 |
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
From: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Bugzilla: 1005818
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
The code before really committing is moved into a function. Most
|
|
|
9ae3a8 |
code is simply moved from qmp_transaction(), except that on fail it
|
|
|
9ae3a8 |
just returns now. Other code such as input parsing is not touched,
|
|
|
9ae3a8 |
to make it easier in review.
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
|
|
|
9ae3a8 |
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
|
|
|
9ae3a8 |
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
|
9ae3a8 |
Reviewed-by: Eric Blake <eblake@redhat.com>
|
|
|
9ae3a8 |
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
|
|
9ae3a8 |
(cherry picked from commit 9b9877ee9f1c27588a286f591852c0b7c0548b6a)
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
|
|
9ae3a8 |
---
|
|
|
9ae3a8 |
blockdev.c | 139 ++++++++++++++++++++++++++++++++++---------------------------
|
|
|
9ae3a8 |
1 file changed, 77 insertions(+), 62 deletions(-)
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
9ae3a8 |
---
|
|
|
9ae3a8 |
blockdev.c | 139 +++++++++++++++++++++++++++++++++---------------------------
|
|
|
9ae3a8 |
1 files changed, 77 insertions(+), 62 deletions(-)
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
diff --git a/blockdev.c b/blockdev.c
|
|
|
9ae3a8 |
index 6500c47..1bff654 100644
|
|
|
9ae3a8 |
--- a/blockdev.c
|
|
|
9ae3a8 |
+++ b/blockdev.c
|
|
|
9ae3a8 |
@@ -785,6 +785,78 @@ typedef struct BlkTransactionStates {
|
|
|
9ae3a8 |
QSIMPLEQ_ENTRY(BlkTransactionStates) entry;
|
|
|
9ae3a8 |
} BlkTransactionStates;
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
+static void external_snapshot_prepare(const char *device,
|
|
|
9ae3a8 |
+ const char *format,
|
|
|
9ae3a8 |
+ const char *new_image_file,
|
|
|
9ae3a8 |
+ enum NewImageMode mode,
|
|
|
9ae3a8 |
+ BlkTransactionStates *states,
|
|
|
9ae3a8 |
+ Error **errp)
|
|
|
9ae3a8 |
+{
|
|
|
9ae3a8 |
+ BlockDriver *proto_drv;
|
|
|
9ae3a8 |
+ BlockDriver *drv;
|
|
|
9ae3a8 |
+ int flags, ret;
|
|
|
9ae3a8 |
+ Error *local_err = NULL;
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ drv = bdrv_find_format(format);
|
|
|
9ae3a8 |
+ if (!drv) {
|
|
|
9ae3a8 |
+ error_set(errp, QERR_INVALID_BLOCK_FORMAT, format);
|
|
|
9ae3a8 |
+ return;
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ states->old_bs = bdrv_find(device);
|
|
|
9ae3a8 |
+ if (!states->old_bs) {
|
|
|
9ae3a8 |
+ error_set(errp, QERR_DEVICE_NOT_FOUND, device);
|
|
|
9ae3a8 |
+ return;
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ if (!bdrv_is_inserted(states->old_bs)) {
|
|
|
9ae3a8 |
+ error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);
|
|
|
9ae3a8 |
+ return;
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ if (bdrv_in_use(states->old_bs)) {
|
|
|
9ae3a8 |
+ error_set(errp, QERR_DEVICE_IN_USE, device);
|
|
|
9ae3a8 |
+ return;
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ if (!bdrv_is_read_only(states->old_bs)) {
|
|
|
9ae3a8 |
+ if (bdrv_flush(states->old_bs)) {
|
|
|
9ae3a8 |
+ error_set(errp, QERR_IO_ERROR);
|
|
|
9ae3a8 |
+ return;
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ flags = states->old_bs->open_flags;
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ proto_drv = bdrv_find_protocol(new_image_file);
|
|
|
9ae3a8 |
+ if (!proto_drv) {
|
|
|
9ae3a8 |
+ error_set(errp, QERR_INVALID_BLOCK_FORMAT, format);
|
|
|
9ae3a8 |
+ return;
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ /* create new image w/backing file */
|
|
|
9ae3a8 |
+ if (mode != NEW_IMAGE_MODE_EXISTING) {
|
|
|
9ae3a8 |
+ bdrv_img_create(new_image_file, format,
|
|
|
9ae3a8 |
+ states->old_bs->filename,
|
|
|
9ae3a8 |
+ states->old_bs->drv->format_name,
|
|
|
9ae3a8 |
+ NULL, -1, flags, &local_err, false);
|
|
|
9ae3a8 |
+ if (error_is_set(&local_err)) {
|
|
|
9ae3a8 |
+ error_propagate(errp, local_err);
|
|
|
9ae3a8 |
+ return;
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ /* We will manually add the backing_hd field to the bs later */
|
|
|
9ae3a8 |
+ states->new_bs = bdrv_new("");
|
|
|
9ae3a8 |
+ /* TODO Inherit bs->options or only take explicit options with an
|
|
|
9ae3a8 |
+ * extended QMP command? */
|
|
|
9ae3a8 |
+ ret = bdrv_open(states->new_bs, new_image_file, NULL,
|
|
|
9ae3a8 |
+ flags | BDRV_O_NO_BACKING, drv);
|
|
|
9ae3a8 |
+ if (ret != 0) {
|
|
|
9ae3a8 |
+ error_set(errp, QERR_OPEN_FILE_FAILED, new_image_file);
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
+}
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
/*
|
|
|
9ae3a8 |
* 'Atomic' group snapshots. The snapshots are taken as a set, and if any fail
|
|
|
9ae3a8 |
* then we do not pivot any of the devices in the group, and abandon the
|
|
|
9ae3a8 |
@@ -792,7 +864,6 @@ typedef struct BlkTransactionStates {
|
|
|
9ae3a8 |
*/
|
|
|
9ae3a8 |
void qmp_transaction(BlockdevActionList *dev_list, Error **errp)
|
|
|
9ae3a8 |
{
|
|
|
9ae3a8 |
- int ret = 0;
|
|
|
9ae3a8 |
BlockdevActionList *dev_entry = dev_list;
|
|
|
9ae3a8 |
BlkTransactionStates *states, *next;
|
|
|
9ae3a8 |
Error *local_err = NULL;
|
|
|
9ae3a8 |
@@ -806,9 +877,6 @@ void qmp_transaction(BlockdevActionList *dev_list, Error **errp)
|
|
|
9ae3a8 |
/* We don't do anything in this loop that commits us to the snapshot */
|
|
|
9ae3a8 |
while (NULL != dev_entry) {
|
|
|
9ae3a8 |
BlockdevAction *dev_info = NULL;
|
|
|
9ae3a8 |
- BlockDriver *proto_drv;
|
|
|
9ae3a8 |
- BlockDriver *drv;
|
|
|
9ae3a8 |
- int flags;
|
|
|
9ae3a8 |
enum NewImageMode mode;
|
|
|
9ae3a8 |
const char *new_image_file;
|
|
|
9ae3a8 |
const char *device;
|
|
|
9ae3a8 |
@@ -831,70 +899,17 @@ void qmp_transaction(BlockdevActionList *dev_list, Error **errp)
|
|
|
9ae3a8 |
format = dev_info->blockdev_snapshot_sync->format;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
mode = dev_info->blockdev_snapshot_sync->mode;
|
|
|
9ae3a8 |
- break;
|
|
|
9ae3a8 |
- default:
|
|
|
9ae3a8 |
- abort();
|
|
|
9ae3a8 |
- }
|
|
|
9ae3a8 |
-
|
|
|
9ae3a8 |
- drv = bdrv_find_format(format);
|
|
|
9ae3a8 |
- if (!drv) {
|
|
|
9ae3a8 |
- error_set(errp, QERR_INVALID_BLOCK_FORMAT, format);
|
|
|
9ae3a8 |
- goto delete_and_fail;
|
|
|
9ae3a8 |
- }
|
|
|
9ae3a8 |
-
|
|
|
9ae3a8 |
- states->old_bs = bdrv_find(device);
|
|
|
9ae3a8 |
- if (!states->old_bs) {
|
|
|
9ae3a8 |
- error_set(errp, QERR_DEVICE_NOT_FOUND, device);
|
|
|
9ae3a8 |
- goto delete_and_fail;
|
|
|
9ae3a8 |
- }
|
|
|
9ae3a8 |
-
|
|
|
9ae3a8 |
- if (!bdrv_is_inserted(states->old_bs)) {
|
|
|
9ae3a8 |
- error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);
|
|
|
9ae3a8 |
- goto delete_and_fail;
|
|
|
9ae3a8 |
- }
|
|
|
9ae3a8 |
-
|
|
|
9ae3a8 |
- if (bdrv_in_use(states->old_bs)) {
|
|
|
9ae3a8 |
- error_set(errp, QERR_DEVICE_IN_USE, device);
|
|
|
9ae3a8 |
- goto delete_and_fail;
|
|
|
9ae3a8 |
- }
|
|
|
9ae3a8 |
-
|
|
|
9ae3a8 |
- if (!bdrv_is_read_only(states->old_bs)) {
|
|
|
9ae3a8 |
- if (bdrv_flush(states->old_bs)) {
|
|
|
9ae3a8 |
- error_set(errp, QERR_IO_ERROR);
|
|
|
9ae3a8 |
- goto delete_and_fail;
|
|
|
9ae3a8 |
- }
|
|
|
9ae3a8 |
- }
|
|
|
9ae3a8 |
-
|
|
|
9ae3a8 |
- flags = states->old_bs->open_flags;
|
|
|
9ae3a8 |
-
|
|
|
9ae3a8 |
- proto_drv = bdrv_find_protocol(new_image_file);
|
|
|
9ae3a8 |
- if (!proto_drv) {
|
|
|
9ae3a8 |
- error_set(errp, QERR_INVALID_BLOCK_FORMAT, format);
|
|
|
9ae3a8 |
- goto delete_and_fail;
|
|
|
9ae3a8 |
- }
|
|
|
9ae3a8 |
-
|
|
|
9ae3a8 |
- /* create new image w/backing file */
|
|
|
9ae3a8 |
- if (mode != NEW_IMAGE_MODE_EXISTING) {
|
|
|
9ae3a8 |
- bdrv_img_create(new_image_file, format,
|
|
|
9ae3a8 |
- states->old_bs->filename,
|
|
|
9ae3a8 |
- states->old_bs->drv->format_name,
|
|
|
9ae3a8 |
- NULL, -1, flags, &local_err, false);
|
|
|
9ae3a8 |
+ external_snapshot_prepare(device, format, new_image_file,
|
|
|
9ae3a8 |
+ mode, states, &local_err);
|
|
|
9ae3a8 |
if (error_is_set(&local_err)) {
|
|
|
9ae3a8 |
error_propagate(errp, local_err);
|
|
|
9ae3a8 |
goto delete_and_fail;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
+ break;
|
|
|
9ae3a8 |
+ default:
|
|
|
9ae3a8 |
+ abort();
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- /* We will manually add the backing_hd field to the bs later */
|
|
|
9ae3a8 |
- states->new_bs = bdrv_new("");
|
|
|
9ae3a8 |
- /* TODO Inherit bs->options or only take explicit options with an
|
|
|
9ae3a8 |
- * extended QMP command? */
|
|
|
9ae3a8 |
- ret = bdrv_open(states->new_bs, new_image_file, NULL,
|
|
|
9ae3a8 |
- flags | BDRV_O_NO_BACKING, drv);
|
|
|
9ae3a8 |
- if (ret != 0) {
|
|
|
9ae3a8 |
- error_set(errp, QERR_OPEN_FILE_FAILED, new_image_file);
|
|
|
9ae3a8 |
- goto delete_and_fail;
|
|
|
9ae3a8 |
- }
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
--
|
|
|
9ae3a8 |
1.7.1
|
|
|
9ae3a8 |
|