From patchwork Wed Apr 24 16:47:59 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Liu Yuan X-Patchwork-Id: 239281 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 BC30E2C00EB for ; Thu, 25 Apr 2013 02:48:53 +1000 (EST) Received: from localhost ([::1]:35863 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UV2sG-0003aZ-2S for incoming@patchwork.ozlabs.org; Wed, 24 Apr 2013 12:48:52 -0400 Received: from eggs.gnu.org ([208.118.235.92]:51861) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UV2rr-0003ZS-Bm for qemu-devel@nongnu.org; Wed, 24 Apr 2013 12:48:34 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UV2rg-0006iS-2s for qemu-devel@nongnu.org; Wed, 24 Apr 2013 12:48:27 -0400 Received: from mail-pd0-f182.google.com ([209.85.192.182]:63887) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UV2rf-0006i2-MN for qemu-devel@nongnu.org; Wed, 24 Apr 2013 12:48:15 -0400 Received: by mail-pd0-f182.google.com with SMTP id 3so1248749pdj.27 for ; Wed, 24 Apr 2013 09:48:14 -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; bh=BM1LfA/avtrUieiKrFM5eTP2tgJOR1aFdp5FZOH1JYE=; b=ZrF+sgTtQXz1XWJYxhsCjKQh2TdBN3mUkvE3q6cFhEHxQjhYtEn1s2YqVDAeNqQ5DF I0ZXjEIWmAb/d1jKzXtgw8wd8XpDJlF0s+qx06bYkJb6p4HVJg/4FYw+wtfg3dgZHU3k kg21iV8P1cRPCZKtTblCvji8WlpI1KHcZajb2JKeyKmHNKXEZ642I5K8l50UComNxNFu IW9TBMH0VQ2rOkKio+FgyqK5LgERI7k9rb/kZs/kmiOxer1ZboxoiUzvk/XuVQHQW86E sEyh2axFxnPtwiR/Hy6Qii8AJ4e0OSdd1PcRTBSBs99NZgLTXq0oWcPtGfNE5lOR0/ne iULA== X-Received: by 10.68.13.168 with SMTP id i8mr48695917pbc.86.1366822094817; Wed, 24 Apr 2013 09:48:14 -0700 (PDT) Received: from localhost.localdomain ([125.34.213.223]) by mx.google.com with ESMTPSA id lo7sm4288841pab.19.2013.04.24.09.48.10 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 24 Apr 2013 09:48:13 -0700 (PDT) From: Liu Yuan To: sheepdog@lists.wpkg.org Date: Thu, 25 Apr 2013 00:47:59 +0800 Message-Id: <1366822079-6582-1-git-send-email-namei.unix@gmail.com> X-Mailer: git-send-email 1.7.9.5 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 209.85.192.182 Cc: Kevin Wolf , Stefan Hajnoczi , qemu-devel@nongnu.org, MORITA Kazutaka Subject: [Qemu-devel] [PATCH v2] 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 Cc: qemu-devel@nongnu.org Cc: MORITA Kazutaka Cc: Kevin Wolf Cc: Stefan Hajnoczi Signed-off-by: Liu Yuan --- 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 | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/block/sheepdog.c b/block/sheepdog.c index 2fe0783..43829a7 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 @@ -301,6 +302,7 @@ typedef struct BDRVSheepdogState { bool is_snapshot; uint32_t cache_flags; bool discard_supported; + bool reverted; char *host_spec; bool is_unix; @@ -1553,7 +1555,9 @@ static int sd_create_branch(BDRVSheepdogState *s) buf = g_malloc(SD_INODE_SIZE); - ret = do_sd_create(s, s->name, s->inode.vdi_size, s->inode.vdi_id, &vid, 1); + /* If reverted, we create a working VDI otherwise go snapshot-create */ + ret = do_sd_create(s, s->name, s->inode.vdi_size, s->inode.vdi_id, &vid, + !s->reverted); if (ret) { goto out; } @@ -1578,6 +1582,7 @@ static int sd_create_branch(BDRVSheepdogState *s) memcpy(&s->inode, buf, sizeof(s->inode)); s->is_snapshot = false; + s->reverted = false; ret = 0; dprintf("%" PRIx32 " was newly created.\n", s->inode.vdi_id); @@ -1869,6 +1874,41 @@ cleanup: return ret; } +/* Delete current working VDI by the name */ +static int sd_delete(BDRVSheepdogState *s, char *name) +{ + 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 fd; + } + + ret = do_req(fd, (SheepdogReq *)&hdr, 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), name); + return -1; + } + + return 0; +} + +/* + * We 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 + */ static int sd_snapshot_goto(BlockDriverState *bs, const char *snapshot_id) { BDRVSheepdogState *s = bs->opaque; @@ -1924,6 +1964,16 @@ static int sd_snapshot_goto(BlockDriverState *bs, const char *snapshot_id) s->is_snapshot = true; + /* + * 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. + */ + ret = sd_delete(s, vdi); + if (!ret) { + s->reverted = true; + } + g_free(buf); g_free(old_s);