aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel P. Berrangé <berrange@redhat.com>2021-02-04 12:48:29 +0000
committerDr. David Alan Gilbert <dgilbert@redhat.com>2021-02-08 11:19:51 +0000
commitf781f84189e3e325da0b0c6a241b77d54b7ea26c (patch)
tree441b7862ce9b5c8209602ea1be5792d78358a674
parent3d3e9b1f669b60d9d3cb857edbfc3d54cbb9c0ef (diff)
migration: control whether snapshots are ovewritten
The traditional HMP "savevm" command will overwrite an existing snapshot if it already exists with the requested name. This new flag allows this to be controlled allowing for safer behaviour with a future QMP command. Reviewed-by: Eric Blake <eblake@redhat.com> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> Message-Id: <20210204124834.774401-8-berrange@redhat.com> Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
-rw-r--r--include/migration/snapshot.h3
-rw-r--r--migration/savevm.c19
-rw-r--r--monitor/hmp-cmds.c2
-rw-r--r--replay/replay-debugging.c2
-rw-r--r--replay/replay-snapshot.c2
5 files changed, 21 insertions, 7 deletions
diff --git a/include/migration/snapshot.h b/include/migration/snapshot.h
index d7d210820c..d8c22d343c 100644
--- a/include/migration/snapshot.h
+++ b/include/migration/snapshot.h
@@ -18,11 +18,12 @@
/**
* save_snapshot: Save an internal snapshot.
* @name: name of internal snapshot
+ * @overwrite: replace existing snapshot with @name
* @errp: pointer to error object
* On success, return %true.
* On failure, store an error through @errp and return %false.
*/
-bool save_snapshot(const char *name, Error **errp);
+bool save_snapshot(const char *name, bool overwrite, Error **errp);
/**
* load_snapshot: Load an internal snapshot.
diff --git a/migration/savevm.c b/migration/savevm.c
index a2a842d067..0ae8e4798c 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -2764,7 +2764,7 @@ int qemu_load_device_state(QEMUFile *f)
return 0;
}
-bool save_snapshot(const char *name, Error **errp)
+bool save_snapshot(const char *name, bool overwrite, Error **errp)
{
BlockDriverState *bs;
QEMUSnapshotInfo sn1, *sn = &sn1;
@@ -2792,8 +2792,21 @@ bool save_snapshot(const char *name, Error **errp)
/* Delete old snapshots of the same name */
if (name) {
- if (bdrv_all_delete_snapshot(name, false, NULL, errp) < 0) {
- return false;
+ if (overwrite) {
+ if (bdrv_all_delete_snapshot(name, false, NULL, errp) < 0) {
+ return false;
+ }
+ } else {
+ ret2 = bdrv_all_has_snapshot(name, false, NULL, errp);
+ if (ret2 < 0) {
+ return false;
+ }
+ if (ret2 == 1) {
+ error_setg(errp,
+ "Snapshot '%s' already exists in one or more devices",
+ name);
+ return false;
+ }
}
}
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
index f795261f77..1fff33f14a 100644
--- a/monitor/hmp-cmds.c
+++ b/monitor/hmp-cmds.c
@@ -1149,7 +1149,7 @@ void hmp_savevm(Monitor *mon, const QDict *qdict)
{
Error *err = NULL;
- save_snapshot(qdict_get_try_str(qdict, "name"), &err);
+ save_snapshot(qdict_get_try_str(qdict, "name"), true, &err);
hmp_handle_error(mon, err);
}
diff --git a/replay/replay-debugging.c b/replay/replay-debugging.c
index 098ef8e0f5..0ae6785b3b 100644
--- a/replay/replay-debugging.c
+++ b/replay/replay-debugging.c
@@ -327,7 +327,7 @@ void replay_gdb_attached(void)
*/
if (replay_mode == REPLAY_MODE_PLAY
&& !replay_snapshot) {
- if (!save_snapshot("start_debugging", NULL)) {
+ if (!save_snapshot("start_debugging", true, NULL)) {
/* Can't create the snapshot. Continue conventional debugging. */
}
}
diff --git a/replay/replay-snapshot.c b/replay/replay-snapshot.c
index b289365937..31c5a8702b 100644
--- a/replay/replay-snapshot.c
+++ b/replay/replay-snapshot.c
@@ -77,7 +77,7 @@ void replay_vmstate_init(void)
if (replay_snapshot) {
if (replay_mode == REPLAY_MODE_RECORD) {
- if (!save_snapshot(replay_snapshot, &err)) {
+ if (!save_snapshot(replay_snapshot, true, &err)) {
error_report_err(err);
error_report("Could not create snapshot for icount record");
exit(1);