Skip to content

Commit

Permalink
replay: save/load initial state
Browse files Browse the repository at this point in the history
This patch implements initial vmstate creation or loading at the start
of record/replay. It is needed for rewinding the execution in the replay mode.

v4 changes:
 - snapshots are not created by default anymore

v3 changes:
 - added rrsnapshot option

Signed-off-by: Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru>
Message-Id: <20170124071746.4572.61449.stgit@PASHA-ISP>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
  • Loading branch information
Dovgalyuk authored and bonzini committed Jan 27, 2017
1 parent ac8c19b commit 9c2037d
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 3 deletions.
16 changes: 16 additions & 0 deletions docs/replay.txt
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,22 @@ is recorded to the log. In replay phase the queue is matched with
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
---------------

Expand Down
9 changes: 9 additions & 0 deletions include/sysemu/replay.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ typedef struct ReplayNetState ReplayNetState;

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 */
Expand Down Expand Up @@ -149,4 +152,10 @@ void replay_unregister_net(ReplayNetState *rns);
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
8 changes: 6 additions & 2 deletions qemu-options.hx
Original file line number Diff line number Diff line change
Expand Up @@ -3400,12 +3400,12 @@ re-inject them.
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
Expand Down Expand Up @@ -3438,6 +3438,10 @@ when the shift value is high (how high depends on the host machine).
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, \
Expand Down
17 changes: 17 additions & 0 deletions replay/replay-snapshot.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,20 @@ void replay_vmstate_register(void)
{
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);
}
}
}
}
5 changes: 5 additions & 0 deletions replay/replay.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#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;
Expand Down Expand Up @@ -292,6 +293,7 @@ void replay_configure(QemuOpts *opts)
exit(1);
}

replay_snapshot = g_strdup(qemu_opt_get(opts, "rrsnapshot"));
replay_vmstate_register();
replay_enable(fname, mode);

Expand Down Expand Up @@ -346,6 +348,9 @@ void replay_finish(void)
replay_filename = NULL;
}

g_free(replay_snapshot);
replay_snapshot = NULL;

replay_finish_events();
replay_mutex_destroy();
}
Expand Down
7 changes: 6 additions & 1 deletion vl.c
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,9 @@ static QemuOptsList qemu_icount_opts = {
}, {
.name = "rrfile",
.type = QEMU_OPT_STRING,
}, {
.name = "rrsnapshot",
.type = QEMU_OPT_STRING,
},
{ /* end of list */ }
},
Expand Down Expand Up @@ -4634,7 +4637,9 @@ int main(int argc, char **argv, char **envp)
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;
}
Expand Down

0 comments on commit 9c2037d

Please sign in to comment.