diff options
author | Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru> | 2016-09-26 11:08:10 +0300 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2016-09-27 11:57:30 +0200 |
commit | 306e196fa24c46d384577fb9c16e7cdb80f26d17 (patch) | |
tree | a2bc6992d9afc481a1121b8084584574bafc3941 | |
parent | f186d64d8fda4bb22c15beb8e45b7814fbd8b51e (diff) |
replay: vmstate for replay module
This patch introduces vmstate for replay data structures.
It allows saving and loading vmstate while replaying.
Signed-off-by: Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru>
Message-Id: <20160926080810.6992.68420.stgit@PASHA-ISP>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r-- | replay/Makefile.objs | 1 | ||||
-rw-r--r-- | replay/replay-internal.h | 9 | ||||
-rw-r--r-- | replay/replay-snapshot.c | 60 | ||||
-rw-r--r-- | replay/replay.c | 1 |
4 files changed, 71 insertions, 0 deletions
diff --git a/replay/Makefile.objs b/replay/Makefile.objs index fcb3f74d60..c8ad3ebb89 100644 --- a/replay/Makefile.objs +++ b/replay/Makefile.objs @@ -4,3 +4,4 @@ common-obj-y += replay-events.o common-obj-y += replay-time.o common-obj-y += replay-input.o common-obj-y += replay-char.o +common-obj-y += replay-snapshot.o diff --git a/replay/replay-internal.h b/replay/replay-internal.h index 9b02d7d6aa..e07eb7d45d 100644 --- a/replay/replay-internal.h +++ b/replay/replay-internal.h @@ -66,6 +66,8 @@ typedef struct ReplayState { unsigned int data_kind; /*! Flag which indicates that event is not processed yet. */ unsigned int has_unread_data; + /*! Temporary variable for saving current log offset. */ + uint64_t file_offset; } ReplayState; extern ReplayState replay_state; @@ -157,4 +159,11 @@ void replay_event_char_read_save(void *opaque); /*! Reads char event read from the file. */ void *replay_event_char_read_load(void); +/* VMState-related functions */ + +/* Registers replay VMState. + Should be called before virtual devices initialization + to make cached timers available for post_load functions. */ +void replay_vmstate_register(void); + #endif diff --git a/replay/replay-snapshot.c b/replay/replay-snapshot.c new file mode 100644 index 0000000000..a17e80e26c --- /dev/null +++ b/replay/replay-snapshot.c @@ -0,0 +1,60 @@ +/* + * replay-snapshot.c + * + * Copyright (c) 2010-2016 Institute for System Programming + * of the Russian Academy of Sciences. + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "sysemu/replay.h" +#include "replay-internal.h" +#include "sysemu/sysemu.h" +#include "monitor/monitor.h" +#include "qapi/qmp/qstring.h" +#include "qemu/error-report.h" +#include "migration/vmstate.h" + +static void replay_pre_save(void *opaque) +{ + ReplayState *state = opaque; + state->file_offset = ftell(replay_file); +} + +static int replay_post_load(void *opaque, int version_id) +{ + ReplayState *state = opaque; + fseek(replay_file, state->file_offset, SEEK_SET); + /* If this was a vmstate, saved in recording mode, + we need to initialize replay data fields. */ + replay_fetch_data_kind(); + + return 0; +} + +static const VMStateDescription vmstate_replay = { + .name = "replay", + .version_id = 1, + .minimum_version_id = 1, + .pre_save = replay_pre_save, + .post_load = replay_post_load, + .fields = (VMStateField[]) { + VMSTATE_INT64_ARRAY(cached_clock, ReplayState, REPLAY_CLOCK_COUNT), + VMSTATE_UINT64(current_step, ReplayState), + VMSTATE_INT32(instructions_count, ReplayState), + VMSTATE_UINT32(data_kind, ReplayState), + VMSTATE_UINT32(has_unread_data, ReplayState), + VMSTATE_UINT64(file_offset, ReplayState), + VMSTATE_END_OF_LIST() + }, +}; + +void replay_vmstate_register(void) +{ + vmstate_register(NULL, 0, &vmstate_replay, &replay_state); +} diff --git a/replay/replay.c b/replay/replay.c index cc2238d077..c797aeae8a 100644 --- a/replay/replay.c +++ b/replay/replay.c @@ -292,6 +292,7 @@ void replay_configure(QemuOpts *opts) exit(1); } + replay_vmstate_register(); replay_enable(fname, mode); out: |