From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:56090) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1T1YFG-00063Z-NB for qemu-devel@nongnu.org; Wed, 15 Aug 2012 03:42:28 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1T1YFF-00006M-3a for qemu-devel@nongnu.org; Wed, 15 Aug 2012 03:42:26 -0400 Received: from mx1.redhat.com ([209.132.183.28]:39570) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1T1YFE-00006C-RJ for qemu-devel@nongnu.org; Wed, 15 Aug 2012 03:42:25 -0400 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q7F7gOnM022281 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Wed, 15 Aug 2012 03:42:24 -0400 From: Pavel Hrdina Date: Wed, 15 Aug 2012 09:41:59 +0200 Message-Id: <582c2debbce809a86fe62d6a998d42bee8ef274c.1345016001.git.phrdina@redhat.com> In-Reply-To: References: In-Reply-To: References: Subject: [Qemu-devel] [PATCH 18/18] vm-snapshot-save: add force parameter List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Pavel Hrdina 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 | 14 +++++++------- hmp.c | 25 ++++++++++++++++++++++++- qapi-schema.json | 12 +++++++----- qmp-commands.hx | 16 +++++++++------- savevm.c | 35 ++++++++++++++--------------------- 5 files changed, 61 insertions(+), 41 deletions(-) diff --git a/hmp-commands.hx b/hmp-commands.hx index d6cd94c..58fd1f2 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -264,19 +264,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 = "name:s?,force:b?", + .params = "[tag|id] [on|off]", + .help = "save a VM snapshot. To replace existing snapshot use force parameter.", .mhandler.cmd = hmp_vm_snapshot_save, }, STEXI @item savevm [@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 tag or ID, it is replaced. More info at -@ref{vm_snapshots}. +Create a snapshot of the whole virtual machine. Parameter "name" is optional. +If @var{tag} is provided, it is used as human readable identifier. If there is +already a snapshot with the same tag, force argument need to be "yes" to +replace it. More info at @ref{vm_snapshots}. ETEXI { diff --git a/hmp.c b/hmp.c index cf0e036..14df8f1 100644 --- a/hmp.c +++ b/hmp.c @@ -1139,9 +1139,32 @@ void hmp_closefd(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 763b51e..e68b259 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -2394,21 +2394,23 @@ ## # @vm-snapshot-save: # -# Create a snapshot of the whole virtual machine. If 'tag' is provided, -# it is used as human readable identifier. If there is already a snapshot -# with the same tag or ID, it is replaced. +# Create a snapshot of the whole virtual machine. Provided 'tag' is used as +# human readable identifier. If there is already a snapshot with the same tag, +# force argument need to be "yes" to replace it. # # The VM is automatically stopped and resumed and saving a snapshot can take # a long time. # -# @name: tag or id of new or existing snapshot +# @name: tag of new or existing snapshot +# +# @force: specify whether existing snapshot is replaced or not # # Returns: Nothing on success # If an error occurs, GenericError with error message # # Since: 1.2 ## -{ '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 3609de8..c86ceb5 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -1112,9 +1112,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 }, @@ -1122,16 +1122,18 @@ SQMP vm-snapshot-save ------ -Create a snapshot of the whole virtual machine. If 'tag' is provided, -it is used as human readable identifier. If there is already a snapshot -with the same tag or ID, it is replaced. +Create a snapshot of the whole virtual machine. Provided 'tag' is used as +human readable identifier. If there is already a snapshot with the same tag, +force argument need to be "yes" to replace it. The VM is automatically stopped and resumed and saving a snapshot can take a long time. Arguments: -- "name": tag or id of new or existing snapshot +- "name": tag of new or existing snapshot + +- "force": specify whether existing snapshot is replaced or not Example: diff --git a/savevm.c b/savevm.c index ca7448d..4ec7663 100644 --- a/savevm.c +++ b/savevm.c @@ -2100,7 +2100,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; @@ -2110,10 +2110,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 */ @@ -2153,29 +2151,24 @@ 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_set(errp, ERROR_CLASS_GENERIC_ERROR, + "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 */ -- 1.7.11.2