From: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
To: qemu-devel@nongnu.org
Cc: kwolf@redhat.com, aliguori@us.ibm.com, quintela@redhat.com,
stefanha@gmail.com, Wenchao Xia <xiawenc@linux.vnet.ibm.com>,
lcapitulino@redhat.com, pbonzini@redhat.com, dietmar@proxmox.com
Subject: [Qemu-devel] [PATCH V2 07/10] snapshot: qmp use new internal API for external snapshot transaction
Date: Mon, 7 Jan 2013 15:28:06 +0800 [thread overview]
Message-ID: <1357543689-11415-9-git-send-email-xiawenc@linux.vnet.ibm.com> (raw)
In-Reply-To: <1357543689-11415-1-git-send-email-xiawenc@linux.vnet.ibm.com>
This patch switch to internal common API to take group external
snapshots from qmp_transaction interface. qmp layer simply does
a translation from user input.
Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
---
blockdev.c | 215 ++++++++++++++++++++++++------------------------------------
1 files changed, 87 insertions(+), 128 deletions(-)
diff --git a/blockdev.c b/blockdev.c
index 668506d..299039f 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1173,157 +1173,116 @@ void qmp_blockdev_snapshot_sync(const char *device, const char *snapshot_file,
errp);
}
-
-/* New and old BlockDriverState structs for group snapshots */
-typedef struct BlkTransactionStates {
- BlockDriverState *old_bs;
- BlockDriverState *new_bs;
- 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_transaction(BlockdevActionList *dev_list, Error **errp)
+/* translation from qmp commands */
+static int fill_blk_trs_ext_create_sync(BlockdevSnapshot *create_sync,
+ BlkTransStatesSync *st_sync,
+ Error **errp)
{
- int ret = 0;
- BlockdevActionList *dev_entry = dev_list;
- BlkTransactionStates *states, *next;
- Error *local_err = NULL;
-
- QSIMPLEQ_HEAD(snap_bdrv_states, BlkTransactionStates) snap_bdrv_states;
- QSIMPLEQ_INIT(&snap_bdrv_states);
+ const char *format = "qcow2";
+ enum NewImageMode mode = NEW_IMAGE_MODE_ABSOLUTE_PATHS;
+ BlockDriverState *bs;
+ const char *device = create_sync->device;
+ const char *name = create_sync->snapshot_file;
- /* drain all i/o before any snapshots */
- bdrv_drain_all();
+ if (create_sync->has_mode) {
+ mode = create_sync->mode;
+ }
+ if (create_sync->has_format) {
+ format = create_sync->format;
+ }
- /* 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;
- enum NewImageMode mode;
- const char *new_image_file;
- const char *device;
- const char *format = "qcow2";
+ /* find the target bs */
+ bs = bdrv_find(device);
+ if (!bs) {
+ error_set(errp, QERR_DEVICE_NOT_FOUND, device);
+ return -1;
+ }
- dev_info = dev_entry->value;
- dev_entry = dev_entry->next;
+ switch (mode) {
+ case NEW_IMAGE_MODE_EXISTING:
+ st_sync->use_existing = true;
+ break;
+ case NEW_IMAGE_MODE_ABSOLUTE_PATHS:
+ st_sync->use_existing = false;
+ break;
+ default:
+ error_setg(errp, "Device %s requested invalid snapshot"
+ " mode %d.", device, mode);
+ return -1;
+ }
- states = g_malloc0(sizeof(BlkTransactionStates));
- QSIMPLEQ_INSERT_TAIL(&snap_bdrv_states, states, entry);
+ st_sync->external.new_image_file = name;
+ st_sync->external.format = format;
+ st_sync->external.old_bs = bs;
- 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_mode) {
- dev_info->blockdev_snapshot_sync->mode = NEW_IMAGE_MODE_ABSOLUTE_PATHS;
- }
- new_image_file = dev_info->blockdev_snapshot_sync->snapshot_file;
- if (dev_info->blockdev_snapshot_sync->has_format) {
- format = dev_info->blockdev_snapshot_sync->format;
- }
- mode = dev_info->blockdev_snapshot_sync->mode;
- break;
- default:
- abort();
- }
+ return 0;
+}
- drv = bdrv_find_format(format);
- if (!drv) {
- error_set(errp, QERR_INVALID_BLOCK_FORMAT, format);
- goto delete_and_fail;
- }
+static int fill_blk_trs(BlockdevAction *dev_info,
+ BlkTransStates *states,
+ SNTime *time,
+ const char *time_str,
+ Error **errp)
+{
+ int ret = 0;
- states->old_bs = bdrv_find(device);
- if (!states->old_bs) {
- error_set(errp, QERR_DEVICE_NOT_FOUND, device);
- goto delete_and_fail;
- }
+ switch (dev_info->kind) {
+ case BLOCKDEV_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC:
+ states->st_sync.type = BLK_SNAPSHOT_EXTERNAL;
+ states->st_sync.op = BLK_SN_SYNC_CREATE;
+ ret = fill_blk_trs_ext_create_sync(dev_info->blockdev_snapshot_sync,
+ &states->st_sync,
+ errp);
+ break;
+ default:
+ abort();
+ }
- if (!bdrv_is_inserted(states->old_bs)) {
- error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);
- goto delete_and_fail;
- }
+ return ret;
+}
- if (bdrv_in_use(states->old_bs)) {
- error_set(errp, QERR_DEVICE_IN_USE, device);
- goto delete_and_fail;
- }
+/* Here this funtion prepare the request list, submit for atomic snapshot. */
+void qmp_transaction(BlockdevActionList *dev_list, Error **errp)
+{
+ BlockdevActionList *dev_entry = dev_list;
+ BlkTransStates *states;
+ int ret;
- if (!bdrv_is_read_only(states->old_bs)) {
- if (bdrv_flush(states->old_bs)) {
- error_set(errp, QERR_IO_ERROR);
- goto delete_and_fail;
- }
- }
+ BlkTransStatesList *snap_bdrv_states = blk_trans_st_list_new();
- flags = states->old_bs->open_flags;
+ /* translate qmp request */
+ /* for group snapshot create we use same time stamp here */
+ SNTime time = get_sn_time();
+ char time_str[256];
+ generate_sn_name_from_time(&time, time_str, sizeof(time_str));
+ while (NULL != dev_entry) {
+ BlockdevAction *dev_info = NULL;
- proto_drv = bdrv_find_protocol(new_image_file);
- if (!proto_drv) {
- error_set(errp, QERR_INVALID_BLOCK_FORMAT, format);
- goto delete_and_fail;
- }
+ dev_info = dev_entry->value;
+ dev_entry = dev_entry->next;
- /* create new image w/backing file */
- if (mode != NEW_IMAGE_MODE_EXISTING) {
- bdrv_img_create(new_image_file, format,
- states->old_bs->filename,
- states->old_bs->drv->format_name,
- NULL, -1, flags, &local_err);
- if (error_is_set(&local_err)) {
- error_propagate(errp, local_err);
- goto delete_and_fail;
- }
+ states = blk_trans_st_new();
+ ret = fill_blk_trs(dev_info, states, &time, time_str, errp);
+ if (ret < 0) {
+ blk_trans_st_delete(&states);
+ goto exit;
}
- /* We will manually add the backing_hd field to the bs later */
- states->new_bs = bdrv_new("");
- 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, new_image_file);
- goto delete_and_fail;
+ ret = add_transaction(snap_bdrv_states, states, errp);
+ if (ret < 0) {
+ blk_trans_st_delete(&states);
+ goto exit;
}
}
+ /* submit to internal API, no need to check return for no following
+ action now. */
+ submit_transaction(snap_bdrv_states, errp);
- /* Now we are going to do the actual pivot. Everything up to this point
- * is reversible, but we are committed at this point */
- QSIMPLEQ_FOREACH(states, &snap_bdrv_states, entry) {
- /* This removes our old bs from the bdrv_states, and adds the new bs */
- bdrv_append(states->new_bs, states->old_bs);
- /* We don't need (or want) to use the transactional
- * bdrv_reopen_multiple() across all the entries at once, because we
- * don't want to abort all of them if one of them fails the reopen */
- bdrv_reopen(states->new_bs, states->new_bs->open_flags & ~BDRV_O_RDWR,
- NULL);
- }
-
- /* success */
- goto exit;
-
-delete_and_fail:
- /*
- * failure, and it is all-or-none; abandon each new bs, and keep using
- * the original bs for all images
- */
- QSIMPLEQ_FOREACH(states, &snap_bdrv_states, entry) {
- if (states->new_bs) {
- bdrv_delete(states->new_bs);
- }
- }
exit:
- QSIMPLEQ_FOREACH_SAFE(states, &snap_bdrv_states, entry, next) {
- g_free(states);
- }
+ blk_trans_st_list_delete(&snap_bdrv_states);
}
-
static void eject_device(BlockDriverState *bs, int force, Error **errp)
{
if (bdrv_in_use(bs)) {
--
1.7.1
next prev parent reply other threads:[~2013-01-07 7:31 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-01-07 7:27 [Qemu-devel] [PATCH V2 00/10] snapshot: take block snapshots in unified way Wenchao Xia
2013-01-07 7:27 ` [Qemu-devel] [PATCH V2 01/10] block: export function bdrv_find_snapshot() Wenchao Xia
2013-01-07 7:28 ` [Qemu-devel] [PATCH V2 02/10] block: add function deappend() Wenchao Xia
2013-01-07 7:28 ` [Qemu-devel] [PATCH V2 03/10] error: add function error_set_check() Wenchao Xia
2013-01-07 7:28 ` [Qemu-devel] [PATCH V2 04/10] oslib-win32: add lock for time functions Wenchao Xia
2013-01-07 17:12 ` Stefan Weil
2013-01-08 2:27 ` Wenchao Xia
2013-01-07 7:28 ` Wenchao Xia
2013-01-07 7:28 ` [Qemu-devel] [PATCH V2 05/10] snapshot: design of internal common API to take snapshots Wenchao Xia
2013-01-07 7:28 ` [Qemu-devel] [PATCH V2 06/10] snapshot: implemention " Wenchao Xia
2013-01-07 7:28 ` Wenchao Xia [this message]
2013-01-09 12:44 ` [Qemu-devel] [PATCH V2 07/10] snapshot: qmp use new internal API for external snapshot transaction Stefan Hajnoczi
2013-01-10 3:21 ` Wenchao Xia
2013-01-10 12:41 ` Stefan Hajnoczi
2013-01-11 6:22 ` Wenchao Xia
2013-01-11 9:12 ` Stefan Hajnoczi
2013-01-14 2:56 ` Wenchao Xia
2013-01-14 10:06 ` Stefan Hajnoczi
2013-01-15 7:03 ` Wenchao Xia
2013-03-12 8:30 ` Wenchao Xia
2013-03-12 15:43 ` Stefan Hajnoczi
2013-03-13 1:36 ` Wenchao Xia
2013-03-13 8:42 ` Stefan Hajnoczi
2013-03-13 10:18 ` Kevin Wolf
2013-03-14 5:08 ` Wenchao Xia
2013-03-14 8:22 ` Kevin Wolf
2013-03-18 10:00 ` Wenchao Xia
2013-01-07 7:28 ` [Qemu-devel] [PATCH V2 08/10] snapshot: qmp add internal snapshot transaction interface Wenchao Xia
2013-01-07 7:28 ` [Qemu-devel] [PATCH V2 09/10] snapshot: qmp add blockdev-snapshot-internal-sync interface Wenchao Xia
2013-01-07 7:28 ` [Qemu-devel] [PATCH V2 10/10] snapshot: hmp add internal snapshot support for block device Wenchao Xia
2013-01-09 22:34 ` [Qemu-devel] [PATCH V2 00/10] snapshot: take block snapshots in unified way Eric Blake
2013-01-10 6:01 ` Wenchao Xia
2013-01-11 13:56 ` Luiz Capitulino
2013-01-14 2:09 ` Wenchao Xia
2013-01-14 10:08 ` Stefan Hajnoczi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1357543689-11415-9-git-send-email-xiawenc@linux.vnet.ibm.com \
--to=xiawenc@linux.vnet.ibm.com \
--cc=aliguori@us.ibm.com \
--cc=dietmar@proxmox.com \
--cc=kwolf@redhat.com \
--cc=lcapitulino@redhat.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=quintela@redhat.com \
--cc=stefanha@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).