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);