[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH V2 07/10] snapshot: qmp use new internal API for ext
From: |
Wenchao Xia |
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 |
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 <address@hidden>
---
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
- [Qemu-devel] [PATCH V2 03/10] error: add function error_set_check(), (continued)
- [Qemu-devel] [PATCH V2 03/10] error: add function error_set_check(), Wenchao Xia, 2013/01/07
- [Qemu-devel] [PATCH V2 01/10] block: export function bdrv_find_snapshot(), Wenchao Xia, 2013/01/07
- [Qemu-devel] [PATCH V2 04/10] oslib-win32: add lock for time functions, Wenchao Xia, 2013/01/07
- [Qemu-devel] [PATCH V2 04/10] oslib-win32: add lock for time functions, Wenchao Xia, 2013/01/07
- [Qemu-devel] [PATCH V2 06/10] snapshot: implemention of internal common API to take snapshots, Wenchao Xia, 2013/01/07
- [Qemu-devel] [PATCH V2 09/10] snapshot: qmp add blockdev-snapshot-internal-sync interface, Wenchao Xia, 2013/01/07
- [Qemu-devel] [PATCH V2 05/10] snapshot: design of internal common API to take snapshots, Wenchao Xia, 2013/01/07
- [Qemu-devel] [PATCH V2 10/10] snapshot: hmp add internal snapshot support for block device, Wenchao Xia, 2013/01/07
- [Qemu-devel] [PATCH V2 07/10] snapshot: qmp use new internal API for external snapshot transaction,
Wenchao Xia <=
- Re: [Qemu-devel] [PATCH V2 07/10] snapshot: qmp use new internal API for external snapshot transaction, Stefan Hajnoczi, 2013/01/09
- Re: [Qemu-devel] [PATCH V2 07/10] snapshot: qmp use new internal API for external snapshot transaction, Wenchao Xia, 2013/01/09
- Re: [Qemu-devel] [PATCH V2 07/10] snapshot: qmp use new internal API for external snapshot transaction, Stefan Hajnoczi, 2013/01/10
- Re: [Qemu-devel] [PATCH V2 07/10] snapshot: qmp use new internal API for external snapshot transaction, Wenchao Xia, 2013/01/11
- Re: [Qemu-devel] [PATCH V2 07/10] snapshot: qmp use new internal API for external snapshot transaction, Stefan Hajnoczi, 2013/01/11
- Re: [Qemu-devel] [PATCH V2 07/10] snapshot: qmp use new internal API for external snapshot transaction, Wenchao Xia, 2013/01/13
- Re: [Qemu-devel] [PATCH V2 07/10] snapshot: qmp use new internal API for external snapshot transaction, Stefan Hajnoczi, 2013/01/14
- Re: [Qemu-devel] [PATCH V2 07/10] snapshot: qmp use new internal API for external snapshot transaction, Wenchao Xia, 2013/01/15
[Qemu-devel] [PATCH V2 08/10] snapshot: qmp add internal snapshot transaction interface, Wenchao Xia, 2013/01/07
Re: [Qemu-devel] [PATCH V2 00/10] snapshot: take block snapshots in unified way, Eric Blake, 2013/01/09