From patchwork Thu Dec 13 15:40:51 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Hrdina X-Patchwork-Id: 206186 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 794382C0086 for ; Fri, 14 Dec 2012 04:21:35 +1100 (EST) Received: from localhost ([::1]:48999 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TjAup-0002dL-UA for incoming@patchwork.ozlabs.org; Thu, 13 Dec 2012 10:41:39 -0500 Received: from eggs.gnu.org ([208.118.235.92]:47505) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TjAuV-0001t2-0b for qemu-devel@nongnu.org; Thu, 13 Dec 2012 10:41:23 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TjAuP-0005xW-1s for qemu-devel@nongnu.org; Thu, 13 Dec 2012 10:41:18 -0500 Received: from mx1.redhat.com ([209.132.183.28]:21232) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TjAuO-0005xO-Pw for qemu-devel@nongnu.org; Thu, 13 Dec 2012 10:41:12 -0500 Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id qBDFfB9c028465 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Thu, 13 Dec 2012 10:41:12 -0500 Received: from localhost.localdomain.com (dhcp-27-184.brq.redhat.com [10.34.27.184]) by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id qBDFeqvU030229; Thu, 13 Dec 2012 10:41:11 -0500 From: Pavel Hrdina To: qemu-devel@nongnu.org Date: Thu, 13 Dec 2012 16:40:51 +0100 Message-Id: <8d2408738c0924a14049e816d00a13711cc87325.1355404685.git.phrdina@redhat.com> In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.68 on 10.5.11.25 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: phrdina@redhat.com Subject: [Qemu-devel] [PATCH v2 17/17] vm-snapshot-save: add force parameter 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 HMP command "savevm" now takes extra optional force parameter to specifi whether replace existing snapshot or not. QMP command "vm-snapshot-save" has also extra optional force parameter and name parameter isn't optional anymore. Signed-off-by: Pavel Hrdina --- hmp-commands.hx | 16 ++++++++-------- hmp.c | 25 ++++++++++++++++++++++++- qapi-schema.json | 9 ++++++--- qmp-commands.hx | 15 +++++++++------ savevm.c | 34 +++++++++++++--------------------- 5 files changed, 60 insertions(+), 39 deletions(-) diff --git a/hmp-commands.hx b/hmp-commands.hx index 0b3d783..04cee55 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -307,19 +307,19 @@ ETEXI { .name = "savevm", - .args_type = "name:s?", - .params = "[tag|id]", - .help = "save a VM snapshot. If no tag or id are provided, a new snapshot is created", + .args_type = "force:-b,name:s?,", + .params = "[-f] [tag|id]", + .help = "save a VM snapshot. To replace existing snapshot use force flag.", .mhandler.cmd = hmp_vm_snapshot_save, }, STEXI -@item savevm [@var{tag}|@var{id}] +@item savevm [@var{-f}] [@var{tag}|@var{id}] @findex savevm -Create a snapshot of the whole virtual machine. If @var{tag} is -provided, it is used as human readable identifier. If there is already -a snapshot with the same @var{tag} or @var{id}, it is replaced. More info at -@ref{vm_snapshots}. +Create a snapshot of the whole virtual machine. Paramtere "name" is optional. +If @var{tag} is provided, it is used as human readable identifier. If there is +already a snapshot with the same @var{tag} or @var{id}, @var{-f} flag needs to +be specified. More info at @ref{vm_snapshots}. ETEXI { diff --git a/hmp.c b/hmp.c index 1983210..f5e7334 100644 --- a/hmp.c +++ b/hmp.c @@ -1372,9 +1372,32 @@ void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict) void hmp_vm_snapshot_save(Monitor *mon, const QDict *qdict) { const char *name = qdict_get_try_str(qdict, "name"); + char new_name[256]; + bool force = qdict_get_try_bool(qdict, "force", 0); Error *err = NULL; +#ifdef _WIN32 + struct _timeb tb; + struct tm *ptm; +#else + struct timeval tv; + struct tm tm; +#endif + + if (!name) { +#ifdef _WIN32 + time_t t = tb.time; + ptm = localtime(&t); + strftime(new_name, sizeof(new_name), "vm-%Y%m%d%H%M%S", ptm); +#else + /* cast below needed for OpenBSD where tv_sec is still 'long' */ + localtime_r((const time_t *)&tv.tv_sec, &tm); + strftime(new_name, sizeof(new_name), "vm-%Y%m%d%H%M%S", &tm); +#endif + } else { + pstrcpy(new_name, sizeof(new_name), name); + } - qmp_vm_snapshot_save(!!name, name, &err); + qmp_vm_snapshot_save(new_name, !!force, force, &err); hmp_handle_error(mon, &err); } diff --git a/qapi-schema.json b/qapi-schema.json index a8742a1..452b52b 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -3036,19 +3036,22 @@ # # Create a snapshot of the whole virtual machine. If tag is provided as @name, # it is used as human readable identifier. If there is already a snapshot -# with the same tag or ID, it is replaced. +# with the same tag or id, the force argument needs to be true to replace it. # # The VM is automatically stopped and resumed and saving a snapshot can take # a long time. # -# @name: #optional tag of new snapshot or tag|id of existing snapshot +# @name: tag of new snapshot or tag|id of existing snapshot +# +# @force: #optional specify whether existing snapshot is replaced or not, +# default is false # # Returns: Nothing on success # If an error occurs, GenericError with error message # # Since: 1.4.0 ## -{ 'command': 'vm-snapshot-save', 'data': {'*name': 'str'} } +{ 'command': 'vm-snapshot-save', 'data': {'name': 'str', '*force': 'bool'} } ## # @vm-snapshot-load: diff --git a/qmp-commands.hx b/qmp-commands.hx index f839c40..077276e 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -1349,9 +1349,9 @@ Example: EQMP { .name = "vm-snapshot-save", - .args_type = "name:s?", - .params = "name", - .help = "save a VM snapshot. If no tag or id are provided, a new snapshot is created", + .args_type = "name:s,force:b?", + .params = "name [force]", + .help = "save a VM snapshot. To replace existing snapshot use force parameter.", .mhandler.cmd_new = qmp_marshal_input_vm_snapshot_save }, @@ -1360,15 +1360,18 @@ vm-snapshot-save ------ Create a snapshot of the whole virtual machine. If tag is provided as name, -it is used as human readable identifier. If there is already a snapshot -with the same tag or id, it is replaced. +it is used as human readable identifier. If there is already a snapshot with +the same tag, the force argument needs to be true to replace it. The VM is automatically stopped and resumed and saving a snapshot can take a long time. Arguments: -- "name": tag of new snapshot or tag|id of existing snapshot (json-string, optional) +- "name": tag of new snapshot or tag|id of existing snapshot (json-string) + +- "force": specify whether existing snapshot is replaced or not, + default is false (json-bool, optional) Example: diff --git a/savevm.c b/savevm.c index 36ccc46..effb4df 100644 --- a/savevm.c +++ b/savevm.c @@ -2141,7 +2141,7 @@ static int del_existing_snapshots(const char *name, return 0; } -void qmp_vm_snapshot_save(bool has_name, const char *name, Error **errp) +void qmp_vm_snapshot_save(const char *name, bool has_force, bool force, Error **errp) { BlockDriverState *bs, *bs1; QEMUSnapshotInfo sn1, *sn = &sn1, old_sn1, *old_sn = &old_sn1; @@ -2151,10 +2151,8 @@ void qmp_vm_snapshot_save(bool has_name, const char *name, Error **errp) uint64_t vm_state_size; #ifdef _WIN32 struct _timeb tb; - struct tm *ptm; #else struct timeval tv; - struct tm tm; #endif /* Verify if there is a device that doesn't support snapshots and is writable */ @@ -2195,29 +2193,23 @@ void qmp_vm_snapshot_save(bool has_name, const char *name, Error **errp) #endif sn->vm_clock_nsec = qemu_get_clock_ns(vm_clock); - if (has_name) { - ret = bdrv_snapshot_find(bs, old_sn, name, NULL); - if (ret >= 0) { + ret = bdrv_snapshot_find(bs, old_sn, name, NULL); + if (ret >= 0) { + if (has_force && force) { pstrcpy(sn->name, sizeof(sn->name), old_sn->name); pstrcpy(sn->id_str, sizeof(sn->id_str), old_sn->id_str); + + del_existing_snapshots(name, errp); + if (error_is_set(errp)) { + goto the_end; + } } else { - pstrcpy(sn->name, sizeof(sn->name), name); + error_setg(errp, "Snapshot '%s' exist. For override specify " + "'force=yes'.", name); + goto the_end; } } else { -#ifdef _WIN32 - time_t t = tb.time; - ptm = localtime(&t); - strftime(sn->name, sizeof(sn->name), "vm-%Y%m%d%H%M%S", ptm); -#else - /* cast below needed for OpenBSD where tv_sec is still 'long' */ - localtime_r((const time_t *)&tv.tv_sec, &tm); - strftime(sn->name, sizeof(sn->name), "vm-%Y%m%d%H%M%S", &tm); -#endif - } - - /* Delete old snapshots of the same name */ - if (has_name && del_existing_snapshots(name, errp) < 0) { - goto the_end; + pstrcpy(sn->name, sizeof(sn->name), name); } /* save the VM state */