From patchwork Tue Nov 3 16:34:37 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Wolf X-Patchwork-Id: 37517 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id C1CE6B7BDD for ; Wed, 4 Nov 2009 03:37:58 +1100 (EST) Received: from localhost ([127.0.0.1]:59776 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1N5MOJ-0003E5-Vl for incoming@patchwork.ozlabs.org; Tue, 03 Nov 2009 11:37:55 -0500 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1N5MMJ-0002gC-Ga for qemu-devel@nongnu.org; Tue, 03 Nov 2009 11:35:51 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1N5MME-0002eB-IP for qemu-devel@nongnu.org; Tue, 03 Nov 2009 11:35:51 -0500 Received: from [199.232.76.173] (port=43440 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1N5MME-0002e4-BQ for qemu-devel@nongnu.org; Tue, 03 Nov 2009 11:35:46 -0500 Received: from mx1.redhat.com ([209.132.183.28]:49228) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1N5MMD-0006FV-NO for qemu-devel@nongnu.org; Tue, 03 Nov 2009 11:35:46 -0500 Received: from int-mx04.intmail.prod.int.phx2.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.17]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id nA3GZhT3001910 for ; Tue, 3 Nov 2009 11:35:43 -0500 Received: from localhost.localdomain (dhcp-5-175.str.redhat.com [10.32.5.175]) by int-mx04.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id nA3GZf2V026863; Tue, 3 Nov 2009 11:35:42 -0500 From: Kevin Wolf To: qemu-devel@nongnu.org Date: Tue, 3 Nov 2009 17:34:37 +0100 Message-Id: <1257266077-9984-1-git-send-email-kwolf@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.17 X-detected-operating-system: by monty-python.gnu.org: Genre and OS details not recognized. Cc: Kevin Wolf , quintela@redhat.com Subject: [Qemu-devel] [PATCH] savevm: Delete existing snapshots in all images X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org When creating a snapshot we can run into the situation that the first disk doesn't have a snapshot, but the second one does have one with the same name as the new snapshot. In this case, qemu doesn't recognize that there is a snapshot to be overwritten, so it starts to save the new snapshot and errors out later when it tries to snapshot the second image. With this patch, snapshots on secondary images are overwritten just like on the first image. Reported-by: Juan Quintela Signed-off-by: Kevin Wolf --- savevm.c | 58 +++++++++++++++++++++++++++++++++++++++------------------- 1 files changed, 39 insertions(+), 19 deletions(-) diff --git a/savevm.c b/savevm.c index b7abf43..20f9a4d 100644 --- a/savevm.c +++ b/savevm.c @@ -1530,12 +1530,40 @@ static int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info, return ret; } +/* + * Deletes snapshots of a given name in all opened images. + */ +static int del_existing_snapshots(Monitor *mon, const char *name) +{ + BlockDriverState *bs; + DriveInfo *dinfo; + QEMUSnapshotInfo sn1, *snapshot = &sn1; + int ret; + + QTAILQ_FOREACH(dinfo, &drives, next) { + bs = dinfo->bdrv; + if (bdrv_can_snapshot(bs) && + bdrv_snapshot_find(bs, snapshot, name) >= 0) + { + ret = bdrv_snapshot_delete(bs, name); + if (ret < 0) { + monitor_printf(mon, + "Error while deleting snapshot on '%s'\n", + bdrv_get_device_name(bs)); + return -1; + } + } + } + + return 0; +} + void do_savevm(Monitor *mon, const QDict *qdict) { DriveInfo *dinfo; BlockDriverState *bs, *bs1; QEMUSnapshotInfo sn1, *sn = &sn1, old_sn1, *old_sn = &old_sn1; - int must_delete, ret; + int ret; QEMUFile *f; int saved_vm_running; uint32_t vm_state_size; @@ -1558,20 +1586,15 @@ void do_savevm(Monitor *mon, const QDict *qdict) saved_vm_running = vm_running; vm_stop(0); - must_delete = 0; + memset(sn, 0, sizeof(*sn)); if (name) { ret = bdrv_snapshot_find(bs, old_sn, name); if (ret >= 0) { - must_delete = 1; - } - } - memset(sn, 0, sizeof(*sn)); - if (must_delete) { - pstrcpy(sn->name, sizeof(sn->name), old_sn->name); - pstrcpy(sn->id_str, sizeof(sn->id_str), old_sn->id_str); - } else { - if (name) + pstrcpy(sn->name, sizeof(sn->name), old_sn->name); + pstrcpy(sn->id_str, sizeof(sn->id_str), old_sn->id_str); + } else { pstrcpy(sn->name, sizeof(sn->name), name); + } } /* fill auxiliary fields */ @@ -1586,6 +1609,11 @@ void do_savevm(Monitor *mon, const QDict *qdict) #endif sn->vm_clock_nsec = qemu_get_clock(vm_clock); + /* Delete old snapshots of the same name */ + if (del_existing_snapshots(mon, name) < 0) { + goto the_end; + } + /* save the VM state */ f = qemu_fopen_bdrv(bs, 1); if (!f) { @@ -1605,14 +1633,6 @@ void do_savevm(Monitor *mon, const QDict *qdict) QTAILQ_FOREACH(dinfo, &drives, next) { bs1 = dinfo->bdrv; if (bdrv_has_snapshot(bs1)) { - if (must_delete) { - ret = bdrv_snapshot_delete(bs1, old_sn->id_str); - if (ret < 0) { - monitor_printf(mon, - "Error while deleting snapshot on '%s'\n", - bdrv_get_device_name(bs1)); - } - } /* Write VM state size only to the image that contains the state */ sn->vm_state_size = (bs == bs1 ? vm_state_size : 0); ret = bdrv_snapshot_create(bs1, sn);