From patchwork Thu Apr 25 08:42:34 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Liu Yuan X-Patchwork-Id: 239430 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 905F42C0092 for ; Thu, 25 Apr 2013 18:43:11 +1000 (EST) Received: from localhost ([::1]:58878 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UVHll-0005vd-Lj for incoming@patchwork.ozlabs.org; Thu, 25 Apr 2013 04:43:09 -0400 Received: from eggs.gnu.org ([208.118.235.92]:52934) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UVHlQ-0005vT-6l for qemu-devel@nongnu.org; Thu, 25 Apr 2013 04:42:53 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UVHlL-0005uP-65 for qemu-devel@nongnu.org; Thu, 25 Apr 2013 04:42:48 -0400 Received: from mail-da0-x231.google.com ([2607:f8b0:400e:c00::231]:50479) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UVHlK-0005tw-Rx for qemu-devel@nongnu.org; Thu, 25 Apr 2013 04:42:43 -0400 Received: by mail-da0-f49.google.com with SMTP id t11so1304934daj.22 for ; Thu, 25 Apr 2013 01:42:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=x-received:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references; bh=i/2kttXhuHHP8EXhuiuTm9RQomANh9aFDrLKaBgjg0Y=; b=WVa58BhZDtWW4bHS5kMunhJzOS0iCse/Bm8o4xZhW/PQYRP31/wpsJmz4WP6o3sCJm Ar++Jwgxm5g0hHY4hqD5IpzB6YTigtTzzTyZGRQif7HijlB4trQ4qvDaTqymOJ433z9O up1uFRZjmdKj0gGZCTf0WegtvAXj/tSvaaZ1vu5/9rbB5oP+MnZW4JCZNuUKu6vn79Y4 J/M8M0SqFy/iVzL5xzbBn7TTMYea7yrY8kkXznNTCJpSDKe21SHkNkffjK1BLxyMXIO8 tz79lGylaJK3urYYX98NYvhK/1dFU92c7U7LPKyp4/J62NfmF1y6PJqEGlIQQYLzNPOb yrLw== X-Received: by 10.68.223.167 with SMTP id qv7mr52714873pbc.68.1366879361787; Thu, 25 Apr 2013 01:42:41 -0700 (PDT) Received: from localhost.localdomain ([60.191.49.171]) by mx.google.com with ESMTPSA id be10sm6486532pbd.30.2013.04.25.01.42.39 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 25 Apr 2013 01:42:41 -0700 (PDT) From: Liu Yuan To: sheepdog@lists.wpkg.org Date: Thu, 25 Apr 2013 16:42:34 +0800 Message-Id: <1366879354-5120-1-git-send-email-namei.unix@gmail.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1366822079-6582-1-git-send-email-namei.unix@gmail.com> References: <1366822079-6582-1-git-send-email-namei.unix@gmail.com> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2607:f8b0:400e:c00::231 Cc: Kevin Wolf , Stefan Hajnoczi , qemu-devel@nongnu.org, MORITA Kazutaka Subject: [Qemu-devel] [PATCH v3] sheepdog: fix loadvm operation 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 From: Liu Yuan Currently the 'loadvm' opertaion works as following: 1. switch to the snapshot 2. mark current working VDI as a snapshot 3. rely on sd_create_branch to create a new working VDI based on the snapshot This works not the same as other format as QCOW2. For e.g, qemu > savevm # get a live snapshot snap1 qemu > savevm # snap2 qemu > loadvm 1 # This will steally create snap3 of the working VDI Which will result in following snapshot chain: base <-- snap1 <-- snap2 <-- snap3 ^ | working VDI snap3 was unnecessarily created and might be annoying users. This patch discard the unnecessary 'snap3' creation. and implement rollback(loadvm) operation to the specified snapshot by 1. switch to the snapshot 2. delete working VDI 3. rely on sd_create_branch to create a new working VDI based on the snapshot The snapshot chain for above example will be: base <-- snap1 <-- snap2 ^ | working VDI As a spin-off, boot from snapshot behave the same as 'loadvm' that discard current vm state. Cc: qemu-devel@nongnu.org Cc: MORITA Kazutaka Cc: Kevin Wolf Cc: Stefan Hajnoczi Signed-off-by: Liu Yuan --- v3: - let boot from snapshot behave like 'loadvm' v2: - use do_req() because sd_delete isn't in coroutine - don't break old behavior if we boot up on the snapshot by using s->reverted to indicate if we delete working VDI successfully - fix a subtle case that sd_create_branch() isn't called yet while another 'loadvm' is executed block/sheepdog.c | 46 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/block/sheepdog.c b/block/sheepdog.c index 9f30a87..019ccbe 100644 --- a/block/sheepdog.c +++ b/block/sheepdog.c @@ -36,6 +36,7 @@ #define SD_OP_GET_VDI_INFO 0x14 #define SD_OP_READ_VDIS 0x15 #define SD_OP_FLUSH_VDI 0x16 +#define SD_OP_DEL_VDI 0x17 #define SD_FLAG_CMD_WRITE 0x01 #define SD_FLAG_CMD_COW 0x02 @@ -1569,6 +1570,35 @@ out: sd_finish_aiocb(acb); } +/* Delete current working VDI on the snapshot chain */ +static bool sd_delete(BDRVSheepdogState *s) +{ + unsigned int wlen = SD_MAX_VDI_LEN, rlen = 0; + SheepdogVdiReq hdr = { + .opcode = SD_OP_DEL_VDI, + .vdi_id = s->inode.vdi_id, + .data_length = wlen, + .flags = SD_FLAG_CMD_WRITE, + }; + SheepdogVdiRsp *rsp = (SheepdogVdiRsp *)&hdr; + int fd, ret; + + fd = connect_to_sdog(s); + if (fd < 0) { + return false; + } + + ret = do_req(fd, (SheepdogReq *)&hdr, s->name, &wlen, &rlen); + closesocket(fd); + if (ret || (rsp->result != SD_RES_SUCCESS && + rsp->result != SD_RES_NO_VDI)) { + error_report("%s, %s", sd_strerror(rsp->result), s->name); + return false; + } + + return true; +} + /* * Create a writable VDI from a snapshot */ @@ -1577,12 +1607,20 @@ static int sd_create_branch(BDRVSheepdogState *s) int ret, fd; uint32_t vid; char *buf; + bool deleted; dprintf("%" PRIx32 " is snapshot.\n", s->inode.vdi_id); buf = g_malloc(SD_INODE_SIZE); - ret = do_sd_create(s, s->name, s->inode.vdi_size, s->inode.vdi_id, &vid, 1); + /* + * Even If deletion fails, we will just create extra snapshot based on + * the workding VDI which was supposed to be deleted. So no need to + * false bail out. + */ + deleted = sd_delete(s); + ret = do_sd_create(s, s->name, s->inode.vdi_size, s->inode.vdi_id, &vid, + !deleted); if (ret) { goto out; } @@ -1898,6 +1936,12 @@ cleanup: return ret; } +/* + * We implement rollback(loadvm) operation to the specified snapshot by + * 1) switch to the snapshot + * 2) rely on sd_create_branch to delete working VDI and + * 3) create a new working VDI based on the speicified snapshot + */ static int sd_snapshot_goto(BlockDriverState *bs, const char *snapshot_id) { BDRVSheepdogState *s = bs->opaque;