From patchwork Mon Dec 17 06:25:06 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wayne Xia X-Patchwork-Id: 206791 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 0A17D2C008E for ; Mon, 17 Dec 2012 18:06:17 +1100 (EST) Received: from localhost ([::1]:51986 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TkUIZ-0007cI-A4 for incoming@patchwork.ozlabs.org; Mon, 17 Dec 2012 01:35:35 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52681) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TkUEk-0002p5-8j for qemu-devel@nongnu.org; Mon, 17 Dec 2012 01:35:22 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TkUAs-0006rQ-Cf for qemu-devel@nongnu.org; Mon, 17 Dec 2012 01:31:38 -0500 Received: from e23smtp07.au.ibm.com ([202.81.31.140]:43105) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TkUAr-0006r8-IY for qemu-devel@nongnu.org; Mon, 17 Dec 2012 01:27:38 -0500 Received: from /spool/local by e23smtp07.au.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Mon, 17 Dec 2012 16:22:27 +1000 Received: from d23dlp01.au.ibm.com (202.81.31.203) by e23smtp07.au.ibm.com (202.81.31.204) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Mon, 17 Dec 2012 16:22:26 +1000 Received: from d23relay05.au.ibm.com (d23relay05.au.ibm.com [9.190.235.152]) by d23dlp01.au.ibm.com (Postfix) with ESMTP id 9ECB92CE804D for ; Mon, 17 Dec 2012 17:27:33 +1100 (EST) Received: from d23av04.au.ibm.com (d23av04.au.ibm.com [9.190.235.139]) by d23relay05.au.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id qBH6GMJj62128138 for ; Mon, 17 Dec 2012 17:16:22 +1100 Received: from d23av04.au.ibm.com (loopback [127.0.0.1]) by d23av04.au.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id qBH6RX9g031810 for ; Mon, 17 Dec 2012 17:27:33 +1100 Received: from RedHat62GAWSWenchao (wenchaox.cn.ibm.com [9.115.122.150]) by d23av04.au.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id qBH6PGrh027846; Mon, 17 Dec 2012 17:27:31 +1100 From: Wenchao Xia To: qemu-devel@nongnu.org Date: Mon, 17 Dec 2012 14:25:06 +0800 Message-Id: <1355725509-5429-4-git-send-email-xiawenc@linux.vnet.ibm.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1355725509-5429-1-git-send-email-xiawenc@linux.vnet.ibm.com> References: <1355725509-5429-1-git-send-email-xiawenc@linux.vnet.ibm.com> X-Content-Scanned: Fidelis XPS MAILER x-cbid: 12121706-0260-0000-0000-0000024D318A X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4.x-2.6.x [generic] X-Received-From: 202.81.31.140 Cc: kwolf@redhat.com, aliguori@us.ibm.com, stefanha@gmail.com, blauwirbel@gmail.com, pbonzini@redhat.com, Wenchao Xia Subject: [Qemu-devel] [PATCH 3/6] snapshot: design of common API to take snapshots X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org This patch added API to take snapshots in unified style for both internal or external type. The core structure is based on transaction, for that there is a qmp interface need to support , qmp_transaction, so all operations are packed as requests. In this way a sperate internal layer for snapshot is splitted out from qmp layer, and now qmp can just translate the user request and fill in internal API. Internal API use params defined inside qemu, so other component inside qemu can use it without considering the qmp's parameter format. Signed-off-by: Wenchao Xia --- blockdev.h | 129 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 129 insertions(+), 0 deletions(-) diff --git a/blockdev.h b/blockdev.h index d73d552..4a1b508 100644 --- a/blockdev.h +++ b/blockdev.h @@ -66,4 +66,133 @@ void qmp_change_blockdev(const char *device, const char *filename, bool has_format, const char *format, Error **errp); void do_commit(Monitor *mon, const QDict *qdict); int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data); + + +/* snapshot transaction API. + * Split out a layer around core struct BlkTransactionStates, so other + * component in qemu can fill the request and simply use the API to submit, + * QMP may just use part of the API's function, no need to expose all internal + * function to user. + */ + +/* sync snapshot */ + +typedef enum BlkTransactionOperationSync { + BLK_SN_SYNC_CREATE = 0, + BLK_SN_SYNC_DELETE, +} BlkTransactionOperationSync; + +/* internal snapshot */ + +typedef struct SNTime { + uint32_t date_sec; /* UTC date of the snapshot */ + uint32_t date_nsec; + uint64_t vm_clock_nsec; /* VM clock relative to boot */ +} SNTime; + +typedef enum BlkSnapshotIntStep { + BLK_SNAPSHOT_INT_START = 0, + BLK_SNAPSHOT_INT_CREATED, + BLK_SNAPSHOT_INT_CANCELED, +} BlkSnapshotIntStep; + +typedef struct BlkSnapshotInternal { + /* caller input */ + const char *sn_name; /* must be set in create/delete. */ + BlockDriverState *bs; /* must be set in create/delete */ + SNTime time; /* must be set in create. */ + uint64_t vm_state_size; /* optional, default is 0, only valid in create. */ + /* following were used internal */ + QEMUSnapshotInfo sn; + QEMUSnapshotInfo old_sn; + bool old_sn_exist; + BlkSnapshotIntStep step; +} BlkSnapshotInternal; + +/* external snapshot */ + +typedef enum BlkSnapshotExtStep { + BLK_SNAPSHOT_EXT_START = 0, + BLK_SNAPSHOT_EXT_CREATED, + BLK_SNAPSHOT_EXT_INVALIDATED, + BLK_SNAPSHOT_EXT_CANCELED, +} BlkSnapshotExtStep; + +typedef struct BlkSnapshotExternal { + /* caller input */ + const char *new_image_file; /* must be set in create/delete. */ + BlockDriverState *old_bs; /* must be set in create/delete. */ + const char *format; /* must be set in create. */ + /* following were used internal */ + BlockDriverState *new_bs; + BlockDriver *format_drv; + BlkSnapshotExtStep step; +} BlkSnapshotExternal; + +typedef enum BlkSnapshotType { + BLK_SNAPSHOT_INTERNAL = 0, + BLK_SNAPSHOT_EXTERNAL, + BLK_SNAPSHOT_NOSUPPORT, +} BlkSnapshotType; + +/* for simple sync type params were all put here ignoring the difference of + different operation type as create/delete. */ +typedef struct BlkTransactionStatesSync { + /* caller input */ + BlkSnapshotType type; + union { + BlkSnapshotInternal internal; + BlkSnapshotExternal external; + }; + bool use_existing; + BlkTransactionOperationSync op; +} BlkTransactionStatesSync; + +/* async snapshot, not supported now */ +typedef struct BlkTransactionStatesAsync { + int reserved; +} BlkTransactionStatesAsync; + +/* Core structure for group snapshots, fill in it and then call the API. */ +typedef struct BlkTransactionStates BlkTransactionStates; + +struct BlkTransactionStates { + /* caller input */ + bool async; + union { + BlkTransactionStatesSync st_sync; + BlkTransactionStatesSync st_async; + }; + /* following were used internal */ + Error *err; + int (*blk_trans_do)(BlkTransactionStates *states, Error **errp); + int (*blk_trans_invalid)(BlkTransactionStates *states, Error **errp); + int (*blk_trans_cancel)(BlkTransactionStates *states, Error **errp); + QSIMPLEQ_ENTRY(BlkTransactionStates) entry; +}; + +typedef QSIMPLEQ_HEAD(snap_bdrv_states, BlkTransactionStates) \ + BlkTransactionStatesList; + +/* API */ +BlkTransactionStates *blk_trans_st_new(void); +void blk_trans_st_delete(BlkTransactionStates **p_st); +BlkTransactionStatesList *blk_trans_st_list_new(void); +void blk_trans_st_list_delete(BlkTransactionStatesList **p_list); + +/* add a request to list, request would be checked to see if it is valid, + return -1 when met error and states would not be queued. */ +int add_transaction(BlkTransactionStatesList *list, + BlkTransactionStates *states, + Error **errp); + +/* 'Atomic' submit the request. In snapshot creation case, if any + * fail then we do not pivot any of the devices in the group, and abandon the + * snapshots + */ +int submit_transaction(BlkTransactionStatesList *list, Error **errp); + +/* helper */ +SNTime get_sn_time(void); +void generate_sn_name_from_time(SNTime *time, char *time_str, int size); #endif