events read from the log. Therefore block devices requests are processed
deterministically.
+Snapshotting
+------------
+
+New VM snapshots may be created in replay mode. They can be used later
+to recover the desired VM state. All VM states created in replay mode
+are associated with the moment of time in the replay scenario.
+After recovering the VM state replay will start from that position.
+
+Default starting snapshot name may be specified with icount field
+rrsnapshot as follows:
+ -icount shift=7,rr=record,rrfile=replay.bin,rrsnapshot=snapshot_name
+
+This snapshot is created at start of recording and restored at start
+of replaying. It also can be loaded while replaying to roll back
+the execution.
+
Network devices
---------------
extern ReplayMode replay_mode;
+/* Name of the initial VM snapshot */
+extern char *replay_snapshot;
+
/* Replay process control functions */
/*! Enables recording or saving event log with specified parameters */
void replay_net_packet_event(ReplayNetState *rns, unsigned flags,
const struct iovec *iov, int iovcnt);
+/* VM state operations */
+
+/*! Called at the start of execution.
+ Loads or saves initial vmstate depending on execution mode. */
+void replay_vmstate_init(void);
+
#endif
ETEXI
DEF("icount", HAS_ARG, QEMU_OPTION_icount, \
- "-icount [shift=N|auto][,align=on|off][,sleep=on|off,rr=record|replay,rrfile=<filename>]\n" \
+ "-icount [shift=N|auto][,align=on|off][,sleep=on|off,rr=record|replay,rrfile=<filename>,rrsnapshot=<snapshot>]\n" \
" enable virtual instruction counter with 2^N clock ticks per\n" \
" instruction, enable aligning the host and virtual clocks\n" \
" or disable real time cpu sleeping\n", QEMU_ARCH_ALL)
STEXI
-@item -icount [shift=@var{N}|auto][,rr=record|replay,rrfile=@var{filename}]
+@item -icount [shift=@var{N}|auto][,rr=record|replay,rrfile=@var{filename},rrsnapshot=@var{snapshot}]
@findex -icount
Enable virtual instruction counter. The virtual cpu will execute one
instruction every 2^@var{N} ns of virtual time. If @code{auto} is specified
When @option{rr} option is specified deterministic record/replay is enabled.
Replay log is written into @var{filename} file in record mode and
read from this file in replay mode.
+
+Option rrsnapshot is used to create new vm snapshot named @var{snapshot}
+at the start of execution recording. In replay mode this option is used
+to load the initial VM state.
ETEXI
DEF("watchdog", HAS_ARG, QEMU_OPTION_watchdog, \
{
vmstate_register(NULL, 0, &vmstate_replay, &replay_state);
}
+
+void replay_vmstate_init(void)
+{
+ if (replay_snapshot) {
+ if (replay_mode == REPLAY_MODE_RECORD) {
+ if (save_vmstate(cur_mon, replay_snapshot) != 0) {
+ error_report("Could not create snapshot for icount record");
+ exit(1);
+ }
+ } else if (replay_mode == REPLAY_MODE_PLAY) {
+ if (load_vmstate(replay_snapshot) != 0) {
+ error_report("Could not load snapshot for icount replay");
+ exit(1);
+ }
+ }
+ }
+}
#define HEADER_SIZE (sizeof(uint32_t) + sizeof(uint64_t))
ReplayMode replay_mode = REPLAY_MODE_NONE;
+char *replay_snapshot;
/* Name of replay file */
static char *replay_filename;
exit(1);
}
+ replay_snapshot = g_strdup(qemu_opt_get(opts, "rrsnapshot"));
replay_vmstate_register();
replay_enable(fname, mode);
replay_filename = NULL;
}
+ g_free(replay_snapshot);
+ replay_snapshot = NULL;
+
replay_finish_events();
replay_mutex_destroy();
}
}, {
.name = "rrfile",
.type = QEMU_OPT_STRING,
+ }, {
+ .name = "rrsnapshot",
+ .type = QEMU_OPT_STRING,
},
{ /* end of list */ }
},
replay_checkpoint(CHECKPOINT_RESET);
qemu_system_reset(VMRESET_SILENT);
register_global_state();
- if (loadvm) {
+ if (replay_mode != REPLAY_MODE_NONE) {
+ replay_vmstate_init();
+ } else if (loadvm) {
if (load_vmstate(loadvm) < 0) {
autostart = 0;
}