replay: allow loading any snapshots before recording

This patch enables using -loadvm in recording mode to allow starting
the execution recording from any of the available snapshots.
It also fixes loading of the record/replay state, therefore snapshots
created in replay mode may also be used for starting the new recording.

Signed-off-by: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>
Message-Id: <20180912081939.3228.56131.stgit@pasha-VirtualBox>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Pavel Dovgalyuk 2018-09-12 11:19:39 +03:00 committed by Paolo Bonzini
parent f9f1f56e4d
commit bb3d7702e8
2 changed files with 16 additions and 8 deletions

View file

@ -33,11 +33,18 @@ static int replay_pre_save(void *opaque)
static int replay_post_load(void *opaque, int version_id) static int replay_post_load(void *opaque, int version_id)
{ {
ReplayState *state = opaque; ReplayState *state = opaque;
fseek(replay_file, state->file_offset, SEEK_SET); if (replay_mode == REPLAY_MODE_PLAY) {
qemu_clock_set_last(QEMU_CLOCK_HOST, state->host_clock_last); fseek(replay_file, state->file_offset, SEEK_SET);
/* If this was a vmstate, saved in recording mode, qemu_clock_set_last(QEMU_CLOCK_HOST, state->host_clock_last);
we need to initialize replay data fields. */ /* If this was a vmstate, saved in recording mode,
replay_fetch_data_kind(); we need to initialize replay data fields. */
replay_fetch_data_kind();
} else if (replay_mode == REPLAY_MODE_RECORD) {
/* This is only useful for loading the initial state.
Therefore reset all the counters. */
state->instructions_count = 0;
state->block_request_id = 0;
}
return 0; return 0;
} }

7
vl.c
View file

@ -4535,9 +4535,7 @@ int main(int argc, char **argv, char **envp)
replay_checkpoint(CHECKPOINT_RESET); replay_checkpoint(CHECKPOINT_RESET);
qemu_system_reset(SHUTDOWN_CAUSE_NONE); qemu_system_reset(SHUTDOWN_CAUSE_NONE);
register_global_state(); register_global_state();
if (replay_mode != REPLAY_MODE_NONE) { if (loadvm) {
replay_vmstate_init();
} else if (loadvm) {
Error *local_err = NULL; Error *local_err = NULL;
if (load_snapshot(loadvm, &local_err) < 0) { if (load_snapshot(loadvm, &local_err) < 0) {
error_report_err(local_err); error_report_err(local_err);
@ -4545,6 +4543,9 @@ int main(int argc, char **argv, char **envp)
exit(1); exit(1);
} }
} }
if (replay_mode != REPLAY_MODE_NONE) {
replay_vmstate_init();
}
qdev_prop_check_globals(); qdev_prop_check_globals();
if (vmstate_dump_file) { if (vmstate_dump_file) {