replay additions
Subsystems (2)
v2 cover replay additions
This set of patches includes several fixes for replay and adds network record/replay for network devices. It also makes possible saving/restoring vmstate in replay mode.
Record and replay for network interactions is performed with the network filter. Each backend must have its own instance of the replay filter as follows:
-netdev user,id=net1 -device rtl8139,netdev=net1
-object filter-replay,id=replay,netdev=net1
This patches add overlay option for blkreplay block driver. Using persistent overlay file allows saving and reloading VM snapshots in replay mode. Replay mechanism automatically creates one snapshot named 'replay_init' to allow rewinding execution while replaying.
Overlay file may be specified as follows:
-drive file=disk.qcow,if=none,id=img-direct
-drive driver=blkreplay,if=none,image=img-direct,overlay=overlay.qcow2,id=img-blkreplay -device ide-hd,drive=img-blkreplay
This set of patches includes fixes and additions for icount and record/replay implementation:
- Enabling VM start/stop in replay mode
- Adding network interaction record/replay
- Adding overlay option for blkreplay filter
- Fixes of the vmstate for several virtual devices
---
Pavel Dovgalyuk (10):
record/replay: add network support
block: set snapshot option for block devices in blkreplay module
block: don't make snapshots for filters
replay: save/load initial state
replay: move internal data to the structure
replay: vmstate for replay module
replay: allow replay stopping and restarting
kvmvapic: fix state change handler
pcspk: adding vmstate for save/restore
integratorcp: adding vmstate for save/restore
block/blkreplay.c | 132 +++++++++++++++++++++++++++++++++++++++++++--- block/snapshot.c | 3 + cpus.c | 1 docs/replay.txt | 22 ++++++++ hw/arm/integratorcp.c | 62 ++++++++++++++++++++++ hw/audio/pcspk.c | 17 +++++- hw/i386/kvmvapic.c | 1 include/sysemu/replay.h | 26 +++++++++ net/Makefile.objs | 1 net/filter-replay.c | 90 +++++++++++++++++++++++++++++++ replay/Makefile.objs | 2 + replay/replay-events.c | 21 +++++++ replay/replay-internal.c | 19 +++---- replay/replay-internal.h | 26 +++++++-- replay/replay-net.c | 110 ++++++++++++++++++++++++++++++++++++++ replay/replay-snapshot.c | 72 +++++++++++++++++++++++++ replay/replay-time.c | 2 - replay/replay.c | 17 +++--- stubs/replay.c | 5 ++ vl.c | 9 ++- 20 files changed, 599 insertions(+), 39 deletions(-) create mode 100644 net/filter-replay.c create mode 100644 replay/replay-net.c create mode 100644 replay/replay-snapshot.c
Signature · 1 line
Pavel Dovgalyuk
PATCH v2 1/10 record/replay: add network support
This patch adds support of recording and replaying network packets in irount rr mode.
Record and replay for network interactions is performed with the network filter. Each backend must have its own instance of the replay filter as follows:
-netdev user,id=net1 -device rtl8139,netdev=net1
-object filter-replay,id=replay,netdev=net1
Replay network filter is used to record and replay network packets. While recording the virtual machine this filter puts all packets coming from the outer world into the log. In replay mode packets from the log are injected into the network device. All interactions with network backend in replay mode are disabled.
--- docs/replay.txt | 14 ++++++ include/sysemu/replay.h | 12 +++++ net/Makefile.objs | 1 net/filter-replay.c | 90 ++++++++++++++++++++++++++++++++++++++ replay/Makefile.objs | 1 replay/replay-events.c | 11 +++++ replay/replay-internal.h | 10 ++++ replay/replay-net.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++ replay/replay.c | 2 - vl.c | 3 + 10 files changed, 252 insertions(+), 2 deletions(-) create mode 100644 net/filter-replay.c create mode 100644 replay/replay-net.c
docs/replay.txt +14 -0
@@ -195,3 +195,17 @@ Queue is flushed at checkpoints and information about processed requests 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. + +Network devices +--------------- + +Record and replay for network interactions is performed with the network filter. +Each backend must have its own instance of the replay filter as follows: + -netdev user,id=net1 -device rtl8139,netdev=net1 + -object filter-replay,id=replay,netdev=net1 + +Replay network filter is used to record and replay network packets. While +recording the virtual machine this filter puts all packets coming from +the outer world into the log. In replay mode packets from the log are +injected into the network device. All interactions with network backend +in replay mode are disabled.
include/sysemu/replay.h +12 -0
@@ -39,6 +39,8 @@ enum ReplayCheckpoint { };typedef enum ReplayCheckpoint ReplayCheckpoint ; +typedef struct ReplayNetState ReplayNetState ; +extern ReplayMode replay_mode;/* Replay process control functions */
@@ -133,4 +135,14 @@ void replay_char_read_all_save_error(int res);/*! Writes character read_all execution result into the replay log. */ void replay_char_read_all_save_buf (uint8_t *buf,int offset); +/* Network */ + +/*! Registers replay network filter attached to some backend. */ +ReplayNetState *replay_register_net (NetFilterState *nfs); +/*! Unregisters replay network filter. */ +void replay_unregister_net (ReplayNetState *rns); +/*! Called to write network packet to the replay log. */ +void replay_net_packet_event (ReplayNetState *rns,unsigned flags, +const struct iovec *iov,int iovcnt); +#endif
net/Makefile.objs +1 -0
@@ -16,3 +16,4 @@ common-obj-$(CONFIG_NETMAP) += netmap.o common-obj-y += filter.o common-obj-y += filter-buffer.o common-obj-y += filter-mirror.o +common-obj-y += filter-replay.o
net/filter-replay.c new file +90 -0
90 lines not on this page · raw message
replay/Makefile.objs +1 -0
@@ -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-net.o
replay/replay-events.c +11 -0
@@ -54,6 +54,9 @@ static void replay_run_event(Event *event)case REPLAY_ASYNC_EVENT_BLOCK :aio_bh_call (event->opaque);break ; +case REPLAY_ASYNC_EVENT_NET : +replay_event_net_run (event->opaque); +break ;default :error_report ("Replay: invalid async event ID (%d) in the queue" , event->event_kind);
@@ -189,6 +192,9 @@ static void replay_save_event(Event *event, int checkpoint)case REPLAY_ASYNC_EVENT_BLOCK :replay_put_qword (event->id);break ; +case REPLAY_ASYNC_EVENT_NET : +replay_event_net_save (event->opaque); +break ;default :error_report ("Unknown ID %" PRId64" of replay event" , event->id);exit (1 );
@@ -252,6 +258,11 @@ static Event *replay_read_event(int checkpoint) read_id =replay_get_qword (); }break ; +case REPLAY_ASYNC_EVENT_NET : + event =g_malloc0 (sizeof (Event)); + event->event_kind = read_event_kind; + event->opaque =replay_event_net_load (); +return event;default :error_report ("Unknown ID %d of replay event" , read_event_kind);exit (1 );
replay/replay-internal.h +10 -0
@@ -50,6 +50,7 @@ enum ReplayAsyncEventKind {REPLAY_ASYNC_EVENT_INPUT_SYNC ,REPLAY_ASYNC_EVENT_CHAR_READ ,REPLAY_ASYNC_EVENT_BLOCK , +REPLAY_ASYNC_EVENT_NET , REPLAY_ASYNC_COUNT };
@@ -155,4 +156,13 @@ void replay_event_char_read_save(void *opaque);/*! Reads char event read from the file. */ void *replay_event_char_read_load (void ); +/* Network devices */ + +/*! Called to run network event. */ +void replay_event_net_run (void *opaque); +/*! Writes network event to the file. */ +void replay_event_net_save (void *opaque); +/*! Reads network from the file. */ +void *replay_event_net_load (void ); +#endif
replay/replay-net.c new file +110 -0
110 lines not on this page · raw message
replay/replay.c +1 -1
@@ -21,7 +21,7 @@/* Current version of the replay mechanism. Increase it when file format changes. */ -#define REPLAY_VERSION 0xe02004 +#define REPLAY_VERSION 0xe02005/* Size of replay log header */ #define HEADER_SIZE (sizeof(uint32_t) + sizeof(uint64_t))
vl.c +2 -1
@@ -2807,7 +2807,8 @@ static bool object_create_initial(const char *type)if (g_str_equal (type,"filter-buffer" ) ||g_str_equal (type,"filter-dump" ) ||g_str_equal (type,"filter-mirror" ) || -g_str_equal (type,"filter-redirector" )) { +g_str_equal (type,"filter-redirector" ) || +g_str_equal (type,"filter-replay" )) {return false; }
PATCH v2 2/10 block: set snapshot option for block devices in blkreplay module
In reply to Pavel DovgalyukThis patch adds overlay option for blkreplay filter.
It allows creating persistent overlay file for saving and reloading VM snapshots in record/replay modes.
--- block/blkreplay.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++ docs/replay.txt | 8 ++++ vl.c | 2 - 3 files changed, 128 insertions(+), 1 deletion(-)
block/blkreplay.c +119 -0
@@ -14,6 +14,7 @@#include "block/block_int.h" #include "sysemu/replay.h" #include "qapi/error.h" +#include "qapi/qmp/qstring.h" typedef struct Request { Coroutine *co;
@@ -25,11 +26,82 @@ typedef struct Request {block devices should not get overlapping ids. */ static uint64_t request_id; +static BlockDriverState *blkreplay_append_snapshot (BlockDriverState *bs, +int flags, +QDict *snapshot_options, +Error **errp) +{ +int ret; +BlockDriverState *bs_snapshot; + +/* Create temporary file, if needed */ +if ((flags &BDRV_O_TEMPORARY ) || replay_mode ==REPLAY_MODE_RECORD ) { +int64_t total_size; +QemuOpts *opts =NULL ; +const char *tmp_filename =qdict_get_str (snapshot_options, +"file.filename" ); + +/* Get the required size from the image */ + total_size =bdrv_getlength (bs); +if (total_size <0 ) { +error_setg_errno (errp, -total_size,"Could not get image size" ); + goto out; + } + + opts =qemu_opts_create (bdrv_qcow2.create_opts,NULL ,0 , + &error_abort); +qemu_opt_set_number (opts,BLOCK_OPT_SIZE , total_size, &error_abort); + ret =bdrv_create (&bdrv_qcow2, tmp_filename, opts, errp); +qemu_opts_del (opts); +if (ret <0 ) { +error_prepend (errp,"Could not create temporary overlay '%s': " , + tmp_filename); + goto out; + } + } + + bs_snapshot =bdrv_open (NULL ,NULL , snapshot_options, flags, errp); + snapshot_options =NULL ; +if (!bs_snapshot) { + ret = -EINVAL ; + goto out; + } + +/* bdrv_append() consumes a strong reference to bs_snapshot (i.e. it will +* call bdrv_unref() on it), so in order to be able to return one, we have +* to increase bs_snapshot's refcount here */ +bdrv_ref (bs_snapshot); +bdrv_append (bs_snapshot, bs); + +return bs_snapshot; + +out: +QDECREF (snapshot_options); +return NULL ; +} + +static QemuOptsList blkreplay_runtime_opts = { + .name ="quorum" , + .head =QTAILQ_HEAD_INITIALIZER (blkreplay_runtime_opts.head), + .desc = { + { + .name ="overlay" , + .type =QEMU_OPT_STRING , + .help ="Optional overlay file for snapshots" , + }, + {/* end of list */ } + }, +}; +static int blkreplay_open (BlockDriverState *bs,QDict *options,int flags,Error **errp) {Error *local_err =NULL ;int ret; +QDict *snapshot_options =qdict_new (); +int snapshot_flags =BDRV_O_RDWR ; +const char *snapshot; +QemuOpts *opts =NULL ;/* Open the image file */ bs->file = bdrv_open_child(NULL, options, "image",
@@ -40,6 +112,43 @@ static int blkreplay_open(BlockDriverState *bs, QDict *options, int flags, goto fail; } + opts =qemu_opts_create (&blkreplay_runtime_opts,NULL ,0 , &error_abort); +qemu_opts_absorb_qdict (opts, options, &local_err); +if (local_err) { + ret = -EINVAL ; + goto fail; + } + +/* Prepare options QDict for the overlay file */ +qdict_put (snapshot_options,"file.driver" , +qstring_from_str ("file" )); +qdict_put (snapshot_options,"driver" , +qstring_from_str ("qcow2" )); + + snapshot =qemu_opt_get (opts,"overlay" ); +if (snapshot) { +qdict_put (snapshot_options,"file.filename" , +qstring_from_str (snapshot)); + }else { +char tmp_filename[PATH_MAX +1 ]; + ret =get_tmp_filename (tmp_filename,PATH_MAX +1 ); +if (ret <0 ) { +error_setg_errno (errp, -ret,"Could not get temporary filename" ); + goto fail; + } +qdict_put (snapshot_options,"file.filename" , +qstring_from_str (tmp_filename)); + snapshot_flags |=BDRV_O_TEMPORARY ; + } + +/* Add temporary snapshot to preserve the image */ +if (!blkreplay_append_snapshot (bs->file->bs, snapshot_flags, + snapshot_options, &local_err)) { + ret = -EINVAL ; +error_propagate (errp, local_err); + goto fail; + } + ret =0 ; fail:if (ret <0 ) {
@@ -50,6 +159,7 @@ fail:static void blkreplay_close (BlockDriverState *bs) { +bdrv_unref (bs->file->bs); }static int64_t blkreplay_getlength (BlockDriverState *bs)
@@ -135,6 +245,12 @@ static int coroutine_fn blkreplay_co_flush(BlockDriverState *bs)return ret; } +static bool blkreplay_recurse_is_first_non_filter (BlockDriverState *bs, +BlockDriverState *candidate) +{ +return bdrv_recurse_is_first_non_filter (bs->file->bs, candidate); +} +static BlockDriver bdrv_blkreplay = { .format_name ="blkreplay" , .protocol_name ="blkreplay" ,
@@ -150,6 +266,9 @@ static BlockDriver bdrv_blkreplay = { .bdrv_co_pwrite_zeroes = blkreplay_co_pwrite_zeroes, .bdrv_co_pdiscard = blkreplay_co_pdiscard, .bdrv_co_flush = blkreplay_co_flush, + + .is_filter = true, + .bdrv_recurse_is_first_non_filter = blkreplay_recurse_is_first_non_filter, };static void bdrv_blkreplay_init (void )
docs/replay.txt +8 -0
@@ -196,6 +196,14 @@ 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. +blkdriver also supports overlay option, which allows creating persistent +overlay file for saving and reloading VM snapshots in record/replay modes. +Replay mechanism automatically creates one snapshot named 'replay_init' to +allow rewinding execution while replaying. +Overlay file may be specified as follows: + -drive driver=blkreplay,if=none,image=img-direct, + overlay=overlay.qcow2,id=img-blkreplay + Network devices ---------------
vl.c +1 -1
@@ -4409,7 +4409,7 @@ int main(int argc, char **argv, char **envp) }/* open the virtual block devices */ -if (snapshot || replay_mode !=REPLAY_MODE_NONE ) { +if (snapshot) {qemu_opts_foreach (qemu_find_opts ("drive" ), drive_enable_snapshot,NULL ,NULL ); }
Re: [Qemu-devel] [PATCH v2 02/10] block: set snapshot option for block devices in blkreplay module
Quoted 5 lines · Pavel Dovgalyuk
docs/replay.txt +0
-0
docs/replay.txt is recorded to the log. In replay phase the queue is matched with · line 205
Quoted 10 lines
docs/replay.txt +7
-0@@ -196,6 +196,14 @@ 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. +blkdriver also supports overlay option, which allows creating persistent +overlay file for saving and reloading VM snapshots in record/replay modes. +Replay mechanism automatically creates one snapshot named 'replay_init' to +allow rewinding execution while replaying. +Overlay file may be specified as follows: + -drive driver=blkreplay,if=none,image=img-direct, + overlay=overlay.qcow2,id=img-blkreplay
So in this case the image is actually overlay.qcow2, and it is created with img-direct as the backing file? Since you have to create overlay.qcow2 outside QEMU anyway, overlay.qcow2 might as well be the "image". That is, you could choose between:
-drive driver=blkreplay,if=none,image=overlay.qcow2,id=img-blkreplay \ -rr snapshot=replay_init,...
-drive driver=blkreplay,if=none,image=img-direct,id=img-blkreplay
The temporary snapshot would be created if there's no "-rr snapshot" option on the command line.
Does this make sense?
Paolo
docs/replay.txt is recorded to the log. In replay phase the queue is matched with · line 207
Quoted 3 lines
docs/replay.txt +2
-0+static QemuOptsList blkreplay_runtime_opts = { + .name = "quorum",
Pasto. ;)
Quoted 10 lines
docs/replay.txt +10
-0+ .head = QTAILQ_HEAD_INITIALIZER(blkreplay_runtime_opts.head), + .desc = { + { + .name = "overlay", + .type = QEMU_OPT_STRING, + .help = "Optional overlay file for snapshots", + }, + { /* end of list */ } + }, +};
Re: [Qemu-devel] [PATCH v2 02/10] block: set snapshot option for block devices in blkreplay module
Quoted 5 lines · Paolo Bonzini
So in this case the image is actually overlay.qcow2, and it is created with img-direct as the backing file? Since you have to create overlay.qcow2 outside QEMU anyway, overlay.qcow2 might as well be the "image". That is, you could choose between:
Quoted 7 lines
-drive driver=blkreplay,if=none,image=overlay.qcow2,id=img-blkreplay \ -rr snapshot=replay_init,...-drive driver=blkreplay,if=none,image=img-direct,id=img-blkreplay
The temporary snapshot would be created if there's no "-rr snapshot" option on the command line.
Sorry, that would be "-icount rrsnapshot=" of course.
Paolo
Re: [Qemu-devel] [PATCH v2 02/10] block: set snapshot option for block devices in blkreplay module
In reply to Paolo BonziniQuoted 10 lines
From: Paolo Bonzini [mailto:[email protected]]
Quoted 8 lines · Pavel Dovgalyuk
docs/replay.txt +0
-0@@ -196,6 +196,14 @@ 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.
Quoted 10 lines
docs/replay.txt is recorded to the log. In replay phase the queue is matched with · line 205
Quoted 7 lines
docs/replay.txt +7
-0+blkdriver also supports overlay option, which allows creating persistent +overlay file for saving and reloading VM snapshots in record/replay modes. +Replay mechanism automatically creates one snapshot named 'replay_init' to +allow rewinding execution while replaying. +Overlay file may be specified as follows: + -drive driver=blkreplay,if=none,image=img-direct, + overlay=overlay.qcow2,id=img-blkreplaySo in this case the image is actually overlay.qcow2, and it is created with img-direct as the backing file?
Right.
Quoted 7 lines
Since you have to create
overlay.qcow2 outside QEMU anyway, overlay.qcow2 might as well be the "image". That is, you could choose between:-drive driver=blkreplay,if=none,image=overlay.qcow2,id=img-blkreplay \ -rr snapshot=replay_init,...
Quoted 6 lines
-drive driver=blkreplay,if=none,image=img-direct,id=img-blkreplay
The temporary snapshot would be created if there's no "-rr snapshot" option on the command line.
Does this make sense?
There are two different parts:
- creating an overlay
- creating the snapshot
Overlay is needed to preserve the state of the original backing file. In the current version temporary overlay is always created at start of qemu. Then all changes are destroyed at exit and disk remain the same. It allows replaying the execution from the same disk state.
To allow reverse execution we have to create some snapshots, that will allow rewinding the execution. Snapshots have to be written on some non-temporary overlay.
I don't think that it is convenient forcing user to create overlay manually. Common debugging scenario includes multiple recording passes until the bug manifests itself. Every new execution recorded should be accompanied by creating an overlay to assure that the execution is started from the same disk state.
Specifying initial snapshot name makes sense if we want to suppress -loadvm option. Then replay may be started from any state without using -loadvm.
Pavel Dovgalyuk
Re: [Qemu-devel] [PATCH v2 02/10] block: set snapshot option for block devices in blkreplay module
Quoted 12 lines · Pavel Dovgalyuk
Quoted 12 lines
Since you have to create
overlay.qcow2 outside QEMU anyway, overlay.qcow2 might as well be the "image". That is, you could choose between:-drive driver=blkreplay,if=none,image=overlay.qcow2,id=img-blkreplay \ -rr snapshot=replay_init,...-drive driver=blkreplay,if=none,image=img-direct,id=img-blkreplay
The temporary snapshot would be created if there's no "-rr snapshot" option on the command line.
Quoted 8 lines
Quoted 1 line
Does this make sense?
There are two different parts:
- creating an overlay
- creating the snapshotOverlay is needed to preserve the state of the original backing file. In the current version temporary overlay is always created at start of qemu.
Yes, this would still be the default for rr mode.
Quoted 1 line
I don't think that it is convenient forcing user to create overlay manually.
Note that all I'm only saying that _only for the case where the user creates the overlay manually anyway_ there is no need to specify both image and overlay. (I also don't like particularly the hard-coded snapshot name replay_init, which can be overridden by -loadvm but not when saving).
So there are various possibilites:
First proposal:
- automatically created overlay is -icount rr=record|replay (then snapshot name doesn't matter, it can be replay_init)
- manually created overlay is -icount rr=record|replay,rrsnapshot=snapname (then snapshot name matters because you can have different snapshots in the same file)
If rr is enabled but rrsnapshot is absent, configure_icount can just set "snapshot = 1" to force creation of the temporary overlay. This requires no change to the blkreplay driver
Second proposal:
- automatically created overlay is -icount rr=record|replay -snapshot
- manually created overlay is -icount rr=record|replay and an rrsnapshot suboption can be added anyway if considered useful.
This requires no change to the blkreplay driver either. It's a little more verbose in the common case, but perhaps less surprising if you're already used to -snapshot.
Quoted 5 lines
Common debugging scenario includes multiple recording passes until the bug manifests itself. Every new execution recorded should be accompanied by creating an overlay to assure that the execution is started from the same disk state.
Specifying initial snapshot name makes sense if we want to suppress -loadvm option.
My rationale was to have similar command lines between record and replay modes (just changing rr=record to rr=replay).
Paolo
Quoted 6 lines
Then replay may be started from any state without using -loadvm.
Pavel Dovgalyuk
Re: [Qemu-devel] [PATCH v2 02/10] block: set snapshot option for block devices in blkreplay module
Quoted 25 lines
From: Paolo Bonzini [mailto:[email protected]] On Behalf Of Paolo Bonzini
Quoted 12 lines · Pavel Dovgalyuk
Quoted 12 lines
Since you have to create
overlay.qcow2 outside QEMU anyway, overlay.qcow2 might as well be the "image". That is, you could choose between:-drive driver=blkreplay,if=none,image=overlay.qcow2,id=img-blkreplay \ -rr snapshot=replay_init,...-drive driver=blkreplay,if=none,image=img-direct,id=img-blkreplay
The temporary snapshot would be created if there's no "-rr snapshot" option on the command line.
Quoted 8 lines
Quoted 1 line
Does this make sense?
There are two different parts:
- creating an overlay
- creating the snapshotOverlay is needed to preserve the state of the original backing file. In the current version temporary overlay is always created at start of qemu.
Yes, this would still be the default for rr mode.
Quoted 7 lines
Quoted 1 line
I don't think that it is convenient forcing user to create overlay manually.
Note that all I'm only saying that
_onlyfor the case where the user creates the overlay manuallyanyway_there is no need to specify both image and overlay. (I also don't like particularly the hard-coded snapshot namereplay_init, which can be overridden by -loadvm but not when saving).
Ok, this seems reasonable to fix.
Quoted 11 lines
So there are various possibilites:
First proposal:
- automatically created overlay is -icount rr=record|replay (then snapshot name doesn't matter, it can be
replay_init)- manually created overlay is -icount rr=record|replay,rrsnapshot=snapname (then snapshot name matters because you can have different snapshots in the same file)
We can't create overlay with icount suboptions, because there could be several block devices. Each one needs its own overlay.
Quoted 11 lines
If rr is enabled but rrsnapshot is absent,
configure_icountcan just set "snapshot = 1" to force creation of the temporary overlay. This requires no change to the blkreplay driverSecond proposal:
- automatically created overlay is -icount rr=record|replay -snapshot
- manually created overlay is -icount rr=record|replay and an rrsnapshot suboption can be added anyway if considered useful.
See above.
Quoted 3 lines
This requires no change to the blkreplay driver either. It's a little more verbose in the common case, but perhaps less surprising if you're already used to -snapshot.
Our internal version automatically creates overlays with generated names. But now I think, that it is inconvenient and manual name specification is better.
Quoted 8 lines
Quoted 5 lines
Common debugging scenario includes multiple recording passes until the bug manifests itself. Every new execution recorded should be accompanied by creating an overlay to assure that the execution is started from the same disk state.
Specifying initial snapshot name makes sense if we want to suppress -loadvm option.
My rationale was to have similar command lines between record and replay modes (just changing rr=record to rr=replay).
This seems reasonable, I'll try to fix this part.
Pavel Dovgalyuk
Re: [Qemu-devel] [PATCH v2 02/10] block: set snapshot option for block devices in blkreplay module
Quoted 43 lines · Pavel Dovgalyuk
Quoted 25 lines
From: Paolo Bonzini [mailto:[email protected]] On Behalf Of Paolo Bonzini
Quoted 12 lines · Pavel Dovgalyuk
Quoted 12 lines
Since you have to create
overlay.qcow2 outside QEMU anyway, overlay.qcow2 might as well be the "image". That is, you could choose between:-drive driver=blkreplay,if=none,image=overlay.qcow2,id=img-blkreplay \ -rr snapshot=replay_init,...-drive driver=blkreplay,if=none,image=img-direct,id=img-blkreplay
The temporary snapshot would be created if there's no "-rr snapshot" option on the command line.
Quoted 8 lines
Quoted 1 line
Does this make sense?
There are two different parts:
- creating an overlay
- creating the snapshotOverlay is needed to preserve the state of the original backing file. In the current version temporary overlay is always created at start of qemu.
Yes, this would still be the default for rr mode.
Quoted 7 lines
Quoted 1 line
I don't think that it is convenient forcing user to create overlay manually.
Note that all I'm only saying that
_onlyfor the case where the user creates the overlay manuallyanyway_there is no need to specify both image and overlay. (I also don't like particularly the hard-coded snapshot namereplay_init, which can be overridden by -loadvm but not when saving).Ok, this seems reasonable to fix.
Quoted 8 lines
So there are various possibilites:
First proposal:
- automatically created overlay is -icount rr=record|replay (then snapshot name doesn't matter, it can be
replay_init)
Quoted 6 lines
Quoted 3 lines
- manually created overlay is -icount rr=record|replay,rrsnapshot=snapname (then snapshot name matters because you can have different snapshots in the same file)
We can't create overlay with icount suboptions, because there could be several block devices. Each one needs its own overlay.
Right, so the overlay name is specified in each -drive option the blkreplay image. rrsnapshot is just the name of the first snapshot that is created (for rr=record, instead of requiring manual interaction with the monitor) or loaded (for rr=replay; in this case it's a convenience only).
Paolo
PATCH v2 3/10 block: don't make snapshots for filters
In reply to Pavel DovgalyukThis patch disables snapshotting for block driver filters. It is needed, because snapshots should be created in underlying disk images, not in filters itself.
--- block/snapshot.c | 3 +++ 1 file changed, 3 insertions(+)
block/snapshot.c +3 -0
@@ -184,6 +184,9 @@ int bdrv_snapshot_goto(BlockDriverState *bs,if (!drv) {return -ENOMEDIUM ; } +if (drv->is_filter) { +return 0 ; + }if (drv->bdrv_snapshot_goto) {return drv->bdrv_snapshot_goto (bs, snapshot_id); }
PATCH v2 4/10 replay: save/load initial state
In reply to Pavel DovgalyukThis patch implements initial vmstate creation or loading at the start of record/replay. It is needed for rewinding the execution in the replay mode.
--- include/sysemu/replay.h | 6 ++++++ replay/Makefile.objs | 1 + replay/replay-snapshot.c | 31 +++++++++++++++++++++++++++++++ vl.c | 2 ++ 4 files changed, 40 insertions(+) create mode 100644 replay/replay-snapshot.c
include/sysemu/replay.h +6 -0
@@ -145,4 +145,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
replay/Makefile.objs +1 -0
@@ -5,3 +5,4 @@ common-obj-y += replay-time.o common-obj-y += replay-input.o common-obj-y += replay-char.o common-obj-y += replay-net.o +common-obj-y += replay-snapshot.o
replay/replay-snapshot.c new file +31 -0
@@ -0,0 +1,31 @@ +/* +* 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" + +void replay_vmstate_init (void ) +{ +if (replay_mode ==REPLAY_MODE_RECORD ) { +QDict *opts =qdict_new (); +qdict_put (opts,"name" ,qstring_from_str ("replay_init" )); +hmp_savevm (cur_mon, opts); +QDECREF (opts); + }else if (replay_mode ==REPLAY_MODE_PLAY ) { +load_vmstate ("replay_init" ); + } +}
vl.c +2 -0
@@ -4593,6 +4593,8 @@ int main(int argc, char **argv, char **envp)if (load_vmstate (loadvm) <0 ) { autostart =0 ; } + }else { +replay_vmstate_init (); }qdev_prop_check_globals ();
Re: [Qemu-devel] [PATCH v2 04/10] replay: save/load initial state
replay/replay-snapshot.c line 29
Quoted 8 lines · Pavel Dovgalyuk
replay/replay-snapshot.c new file +8
-0+{ +if (replay_mode ==REPLAY_MODE_RECORD ) { +QDict *opts =qdict_new (); +qdict_put (opts,"name" ,qstring_from_str ("replay_init" )); +hmp_savevm (cur_mon, opts); +QDECREF (opts); + }else if (replay_mode ==REPLAY_MODE_PLAY ) { +load_vmstate ("replay_init" );
See my other message about a suggestion to remove the hardcoded snapshot name.
Also, I think the return value of load_vmstate and hmp_savevm should be checked.
vl.c int main(int argc, char **argv, char **envp) · line 4598
Quoted 13 lines
replay/replay-snapshot.c new file +2
-0+ } +}vl.c +2
-0@@ -4593,6 +4593,8 @@ int main(int argc, char **argv, char **envp)if (load_vmstate (loadvm) <0 ) { autostart =0 ; } + }else { +replay_vmstate_init (); }
Should -loadvm be incompatible with -rr?
Paolo
Re: [Qemu-devel] [PATCH v2 04/10] replay: save/load initial state
Quoted 11 lines
From: Paolo Bonzini [mailto:[email protected]]
replay/replay-snapshot.c line 29
Quoted 8 lines · Pavel Dovgalyuk
replay/replay-snapshot.c new file +8
-0+{ +if (replay_mode ==REPLAY_MODE_RECORD ) { +QDict *opts =qdict_new (); +qdict_put (opts,"name" ,qstring_from_str ("replay_init" )); +hmp_savevm (cur_mon, opts); +QDECREF (opts); + }else if (replay_mode ==REPLAY_MODE_PLAY ) { +load_vmstate ("replay_init" );
Quoted 5 lines
See my other message about a suggestion to remove the hardcoded snapshot name.
Also, I think the return value of
load_vmstateandhmp_savevmshould be checked.
Load may be unsuccessful when the system is started with temporary overlay file. This is ok.
Quoted 7 lines
Quoted 7 lines
replay/replay-snapshot.c new file +2
-0+ } +}vl.c +0
-0@@ -4593,6 +4593,8 @@ int main(int argc, char **argv, char **envp)
Quoted 8 lines
vl.c int main(int argc, char **argv, char **envp) · line 4598
Quoted 6 lines
vl.c +2
-0if (load_vmstate (loadvm) <0 ) { autostart =0 ; } + }else { +replay_vmstate_init (); }Should -loadvm be incompatible with -rr?
User either loads some initial state or relies on replay which uses 'replay_init'.
Pavel Dovgalyuk
Re: [Qemu-devel] [PATCH v2 04/10] replay: save/load initial state
Quoted 9 lines · Pavel Dovgalyuk
Quoted 9 lines
Quoted 9 lines
Quoted 8 lines
Quoted 8 lines
replay/replay-snapshot.c new file +8
-0+{ +if (replay_mode ==REPLAY_MODE_RECORD ) { +QDict *opts =qdict_new (); +qdict_put (opts,"name" ,qstring_from_str ("replay_init" )); +hmp_savevm (cur_mon, opts); +QDECREF (opts); + }else if (replay_mode ==REPLAY_MODE_PLAY ) { +load_vmstate ("replay_init" );
Quoted 8 lines
Quoted 5 lines
Quoted 5 lines
See my other message about a suggestion to remove the hardcoded snapshot name.
Also, I think the return value of
load_vmstateandhmp_savevmshould be checked.Load may be unsuccessful when the system is started with temporary overlay file. This is ok.
This seems to be in favor of using a rrsnapshot option instead. Using rrsnapshot for temporary overlay would make little sense.
Paolo
PATCH v2 5/10 replay: move internal data to the structure
In reply to Pavel DovgalyukThis patch moves replay static variables into the structure to allow saving and loading them with savevm/loadvm.
--- replay/replay-events.c | 2 +- replay/replay-internal.c | 19 ++++++++----------- replay/replay-internal.h | 8 +++++--- replay/replay-time.c | 2 +- replay/replay.c | 15 ++++++++------- 5 files changed, 23 insertions(+), 23 deletions(-)
replay/replay-events.c +1 -1
@@ -290,7 +290,7 @@ static Event *replay_read_event(int checkpoint)/* Called with replay mutex locked */ void replay_read_events (int checkpoint) { -while (replay_data_kind ==EVENT_ASYNC ) { +while (replay_state.data_kind ==EVENT_ASYNC ) {Event *event =replay_read_event (checkpoint);if (!event) {break ;
replay/replay-internal.c +8 -11
@@ -16,11 +16,8 @@#include "qemu/error-report.h" #include "sysemu/sysemu.h" -unsigned int replay_data_kind =-1 ; -static unsigned int replay_has_unread_data; -/* Mutex to protect reading and writing events to the log. -replay_data_kind and replay_has_unread_data are also protected +data_kind and has_unread_data are also protected by this mutex. It also protects replay events queue which stores events to be written or read to the log. */
@@ -150,15 +147,15 @@ void replay_check_error(void)void replay_fetch_data_kind (void ) {if (replay_file) { -if (!replay_has_unread_data) { - replay_data_kind =replay_get_byte (); -if (replay_data_kind ==EVENT_INSTRUCTION ) { +if (!replay_state.has_unread_data) { + replay_state.data_kind =replay_get_byte (); +if (replay_state.data_kind ==EVENT_INSTRUCTION ) { replay_state.instructions_count =replay_get_dword (); }replay_check_error (); - replay_has_unread_data =1 ; -if (replay_data_kind >=EVENT_COUNT ) { -error_report ("Replay: unknown event kind %d" , replay_data_kind); + replay_state.has_unread_data =1 ; +if (replay_state.data_kind >=EVENT_COUNT ) { +error_report ("Replay: unknown event kind %d" , replay_state.data_kind);exit (1 ); } }
@@ -167,7 +164,7 @@ void replay_fetch_data_kind(void)void replay_finish_event (void ) { - replay_has_unread_data =0 ; + replay_state.has_unread_data =0 ;replay_fetch_data_kind (); }
replay/replay-internal.h +5 -3
@@ -63,11 +63,13 @@ typedef struct ReplayState {uint64_t current_step;/*! Number of instructions to be executed before other events happen. */ int instructions_count; +/*! Type of the currently executed event. */ +unsigned int data_kind; +/*! Flag which indicates that event is not processed yet. */ +unsigned int has_unread_data; } ReplayState;extern ReplayState replay_state; -extern unsigned int replay_data_kind; -/* File for replay writing */ extern FILE *replay_file;
@@ -99,7 +101,7 @@ void replay_check_error(void);the next event from the log. */ void replay_finish_event (void );/*! Reads data type from the file and stores it in the -replay_data_kind variable. */ +data_kind variable. */ void replay_fetch_data_kind (void );/*! Saves queued events (like instructions and sound). */
replay/replay-time.c +1 -1
@@ -31,7 +31,7 @@ int64_t replay_save_clock(ReplayClockKind kind, int64_t clock)void replay_read_next_clock (ReplayClockKind kind) { -unsigned int read_kind = replay_data_kind -EVENT_CLOCK ; +unsigned int read_kind = replay_state.data_kind -EVENT_CLOCK ;assert (read_kind == kind);
replay/replay.c +8 -7
@@ -38,15 +38,15 @@ bool replay_next_event_is(int event)/* nothing to skip - not all instructions used */ if (replay_state.instructions_count !=0 ) { -assert (replay_data_kind ==EVENT_INSTRUCTION ); +assert (replay_state.data_kind ==EVENT_INSTRUCTION );return event ==EVENT_INSTRUCTION ; }while (true) { -if (event == replay_data_kind) { +if (event == replay_state.data_kind) { res = true; } -switch (replay_data_kind) { +switch (replay_state.data_kind) {case EVENT_SHUTDOWN :replay_finish_event ();qemu_system_shutdown_request ();
@@ -85,7 +85,7 @@ void replay_account_executed_instructions(void) replay_state.instructions_count -= count; replay_state.current_step += count;if (replay_state.instructions_count ==0 ) { -assert (replay_data_kind ==EVENT_INSTRUCTION ); +assert (replay_state.data_kind ==EVENT_INSTRUCTION );replay_finish_event ();/* Wake up iothread. This is required because timers will not expire until clock counters
@@ -188,7 +188,7 @@ bool replay_checkpoint(ReplayCheckpoint checkpoint)if (replay_mode ==REPLAY_MODE_PLAY ) {if (replay_next_event_is (EVENT_CHECKPOINT + checkpoint)) {replay_finish_event (); - }else if (replay_data_kind !=EVENT_ASYNC ) { + }else if (replay_state.data_kind !=EVENT_ASYNC ) { res = false; goto out; }
@@ -196,7 +196,7 @@ bool replay_checkpoint(ReplayCheckpoint checkpoint)/* replay_read_events may leave some unread events. Return false if not all of the events associated with checkpoint were processed */ - res = replay_data_kind !=EVENT_ASYNC ; + res = replay_state.data_kind !=EVENT_ASYNC ; }else if (replay_mode ==REPLAY_MODE_RECORD ) {replay_put_event (EVENT_CHECKPOINT + checkpoint);replay_save_events (checkpoint);
@@ -237,9 +237,10 @@ static void replay_enable(const char *fname, int mode) replay_filename =g_strdup (fname); replay_mode = mode; - replay_data_kind =-1 ; + replay_state.data_kind =-1 ; replay_state.instructions_count =0 ; replay_state.current_step =0 ; + replay_state.has_unread_data =0 ;/* skip file header for RECORD and check it for PLAY */ if (replay_mode ==REPLAY_MODE_RECORD ) {
Re: [Qemu-devel] [PATCH v2 05/10] replay: move internal data to the structure
Quoted 168 lines · Pavel Dovgalyuk
This patch moves replay static variables into the structure to allow saving and loading them with savevm/loadvm.
Signed-off-by Pavel Dovgalyuk <[email protected]>--- replay/replay-events.c | 2 +- replay/replay-internal.c | 19 ++++++++----------- replay/replay-internal.h | 8 +++++--- replay/replay-time.c | 2 +- replay/replay.c | 15 ++++++++------- 5 files changed, 23 insertions(+), 23 deletions(-)replay/replay-events.c +1
-1@@ -290,7 +290,7 @@ static Event *replay_read_event(int checkpoint)/* Called with replay mutex locked */ void replay_read_events (int checkpoint) { -while (replay_data_kind ==EVENT_ASYNC ) { +while (replay_state.data_kind ==EVENT_ASYNC ) {Event *event =replay_read_event (checkpoint);if (!event) {break ;replay/replay-internal.c +8
-11@@ -16,11 +16,8 @@#include "qemu/error-report.h" #include "sysemu/sysemu.h" -unsigned int replay_data_kind =-1 ; -static unsigned int replay_has_unread_data; -/* Mutex to protect reading and writing events to the log. -replay_data_kind and replay_has_unread_data are also protected +data_kind and has_unread_data are also protected by this mutex. It also protects replay events queue which stores events to be written or read to the log. */ @@ -150,15 +147,15 @@ void replay_check_error(void)void replay_fetch_data_kind (void ) {if (replay_file) { -if (!replay_has_unread_data) { - replay_data_kind =replay_get_byte (); -if (replay_data_kind ==EVENT_INSTRUCTION ) { +if (!replay_state.has_unread_data) { + replay_state.data_kind =replay_get_byte (); +if (replay_state.data_kind ==EVENT_INSTRUCTION ) { replay_state.instructions_count =replay_get_dword (); }replay_check_error (); - replay_has_unread_data =1 ; -if (replay_data_kind >=EVENT_COUNT ) { -error_report ("Replay: unknown event kind %d" , replay_data_kind); + replay_state.has_unread_data =1 ; +if (replay_state.data_kind >=EVENT_COUNT ) { +error_report ("Replay: unknown event kind %d" , replay_state.data_kind);exit (1 ); } }@@ -167,7 +164,7 @@ void replay_fetch_data_kind(void)void replay_finish_event (void ) { - replay_has_unread_data =0 ; + replay_state.has_unread_data =0 ;replay_fetch_data_kind (); }replay/replay-internal.h +5
-3@@ -63,11 +63,13 @@ typedef struct ReplayState {uint64_t current_step;/*! Number of instructions to be executed before other events happen. */ int instructions_count; +/*! Type of the currently executed event. */ +unsigned int data_kind; +/*! Flag which indicates that event is not processed yet. */ +unsigned int has_unread_data; } ReplayState;extern ReplayState replay_state; -extern unsigned int replay_data_kind; -/* File for replay writing */ extern FILE *replay_file;@@ -99,7 +101,7 @@ void replay_check_error(void);the next event from the log. */ void replay_finish_event (void );/*! Reads data type from the file and stores it in the -replay_data_kind variable. */ +data_kind variable. */ void replay_fetch_data_kind (void );/*! Saves queued events (like instructions and sound). */ replay/replay-time.c +1
-1@@ -31,7 +31,7 @@ int64_t replay_save_clock(ReplayClockKind kind, int64_t clock)void replay_read_next_clock (ReplayClockKind kind) { -unsigned int read_kind = replay_data_kind -EVENT_CLOCK ; +unsigned int read_kind = replay_state.data_kind -EVENT_CLOCK ;assert (read_kind == kind);replay/replay.c +6
-6@@ -38,15 +38,15 @@ bool replay_next_event_is(int event)/* nothing to skip - not all instructions used */ if (replay_state.instructions_count !=0 ) { -assert (replay_data_kind ==EVENT_INSTRUCTION ); +assert (replay_state.data_kind ==EVENT_INSTRUCTION );return event ==EVENT_INSTRUCTION ; }while (true) { -if (event == replay_data_kind) { +if (event == replay_state.data_kind) { res = true; } -switch (replay_data_kind) { +switch (replay_state.data_kind) {case EVENT_SHUTDOWN :replay_finish_event ();qemu_system_shutdown_request ();@@ -85,7 +85,7 @@ void replay_account_executed_instructions(void) replay_state.instructions_count -= count; replay_state.current_step += count;if (replay_state.instructions_count ==0 ) { -assert (replay_data_kind ==EVENT_INSTRUCTION ); +assert (replay_state.data_kind ==EVENT_INSTRUCTION );replay_finish_event ();/* Wake up iothread. This is required because timers will not expire until clock counters @@ -188,7 +188,7 @@ bool replay_checkpoint(ReplayCheckpoint checkpoint)if (replay_mode ==REPLAY_MODE_PLAY ) {if (replay_next_event_is (EVENT_CHECKPOINT + checkpoint)) {replay_finish_event (); - }else if (replay_data_kind !=EVENT_ASYNC ) { + }else if (replay_state.data_kind !=EVENT_ASYNC ) { res = false; goto out; }@@ -196,7 +196,7 @@ bool replay_checkpoint(ReplayCheckpoint checkpoint)/* replay_read_events may leave some unread events. Return false if not all of the events associated with checkpoint were processed */ - res = replay_data_kind !=EVENT_ASYNC ; + res = replay_state.data_kind !=EVENT_ASYNC ; }else if (replay_mode ==REPLAY_MODE_RECORD ) {replay_put_event (EVENT_CHECKPOINT + checkpoint);replay_save_events (checkpoint);@@ -237,9 +237,10 @@ static void replay_enable(const char *fname, int mode) replay_filename =g_strdup (fname);
replay/replay.c static void replay_enable(const char *fname, int mode) · line 246
Quoted 10 lines
replay/replay.c +2
-1replay_mode = mode; - replay_data_kind =-1 ; + replay_state.data_kind =-1 ; replay_state.instructions_count =0 ; replay_state.current_step =0 ; + replay_state.has_unread_data =0 ;/* skip file header for RECORD and check it for PLAY */ if (replay_mode ==REPLAY_MODE_RECORD ) {
PATCH v2 6/10 replay: vmstate for replay module
In reply to Pavel DovgalyukThis patch introduces vmstate for replay data structures. It allows saving and loading vmstate while replaying.
--- include/sysemu/replay.h | 4 ++++ replay/replay-internal.h | 2 ++ replay/replay-snapshot.c | 40 ++++++++++++++++++++++++++++++++++++++++ vl.c | 1 + 4 files changed, 47 insertions(+)
include/sysemu/replay.h +4 -0
@@ -147,6 +147,10 @@ void replay_net_packet_event(ReplayNetState *rns, unsigned flags,/* VM state operations */ +/* Registers replay VMState. +Should be called before virtual devices initialization +to make cached timers available for post_load functions. */ +void replay_vmstate_register (void );/*! Called at the start of execution. Loads or saves initial vmstate depending on execution mode. */ void replay_vmstate_init (void );
replay/replay-internal.h +2 -0
@@ -67,6 +67,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;
replay/replay-snapshot.c +40 -0
@@ -17,6 +17,46 @@#include "sysemu/sysemu.h" #include "monitor/monitor.h" #include "qapi/qmp/qstring.h" +#include "migration/vmstate.h" + +static void replay_pre_save (void *opaque) +{ +ReplayState *state = opaque; + state->file_offset =ftello64 (replay_file); +} + +static int replay_post_load (void *opaque,int version_id) +{ +ReplayState *state = opaque; +fseeko64 (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); +}void replay_vmstate_init (void ) {
vl.c +1 -0
@@ -4361,6 +4361,7 @@ int main(int argc, char **argv, char **envp)configure_icount (icount_opts, &error_abort);qemu_opts_del (icount_opts); } +replay_vmstate_register ();if (default_net) {QemuOptsList *net =qemu_find_opts ("net" );
Re: [Qemu-devel] [PATCH v2 06/10] replay: vmstate for replay module
Quoted 16 lines · Pavel Dovgalyuk
This patch introduces vmstate for replay data structures. It allows saving and loading vmstate while replaying.
Signed-off-by Pavel Dovgalyuk <[email protected]>--- include/sysemu/replay.h | 4 ++++ replay/replay-internal.h | 2 ++ replay/replay-snapshot.c | 40 ++++++++++++++++++++++++++++++++++++++++ vl.c | 1 + 4 files changed, 47 insertions(+)include/sysemu/replay.h +0
-0
include/sysemu/replay.h void replay_net_packet_event(ReplayNetState *rns, unsigned flags, · line 153
Quoted 7 lines
include/sysemu/replay.h +4
-0@@ -147,6 +147,10 @@ void replay_net_packet_event(ReplayNetState *rns, unsigned flags,/* VM state operations */ +/* Registers replay VMState. +Should be called before virtual devices initialization +to make cached timers available for post_load functions. */ +void replay_vmstate_register (void );
Can this be done simply in replay_configure?
Paolo
Quoted 82 lines
include/sysemu/replay.h +0
-0/*! Called at the start of execution. Loads or saves initial vmstate depending on execution mode. */ void replay_vmstate_init (void );replay/replay-internal.h +2
-0@@ -67,6 +67,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;replay/replay-snapshot.c +40
-0@@ -17,6 +17,46 @@#include "sysemu/sysemu.h" #include "monitor/monitor.h" #include "qapi/qmp/qstring.h" +#include "migration/vmstate.h" + +static void replay_pre_save (void *opaque) +{ +ReplayState *state = opaque; + state->file_offset =ftello64 (replay_file); +} + +static int replay_post_load (void *opaque,int version_id) +{ +ReplayState *state = opaque; +fseeko64 (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); +}void replay_vmstate_init (void ) {vl.c +1
-0@@ -4361,6 +4361,7 @@ int main(int argc, char **argv, char **envp)configure_icount (icount_opts, &error_abort);qemu_opts_del (icount_opts); } +replay_vmstate_register ();if (default_net) {QemuOptsList *net =qemu_find_opts ("net" );
Re: [Qemu-devel] [PATCH v2 06/10] replay: vmstate for replay module
Quoted 19 lines
From: Paolo Bonzini [mailto:[email protected]] On Behalf Of Paolo Bonzini
Quoted 17 lines · Pavel Dovgalyuk
This patch introduces vmstate for replay data structures. It allows saving and loading vmstate while replaying.
Signed-off-by Pavel Dovgalyuk <[email protected]>--- include/sysemu/replay.h | 4 ++++ replay/replay-internal.h | 2 ++ replay/replay-snapshot.c | 40 ++++++++++++++++++++++++++++++++++++++++ vl.c | 1 + 4 files changed, 47 insertions(+)include/sysemu/replay.h +0
-0@@ -147,6 +147,10 @@ void replay_net_packet_event(ReplayNetState *rns, unsigned flags,
Quoted 8 lines
include/sysemu/replay.h void replay_net_packet_event(ReplayNetState *rns, unsigned flags, · line 153
Quoted 6 lines
include/sysemu/replay.h +4
-0/* VM state operations */ +/* Registers replay VMState. +Should be called before virtual devices initialization +to make cached timers available for post_load functions. */ +void replay_vmstate_register (void );Can this be done simply in
replay_configure?
I guess it can. Configuring is performed early enough to allow vmsd be added first into the list.
Pavel Dovgalyuk
PATCH v2 7/10 replay: allow replay stopping and restarting
In reply to Pavel DovgalyukThis patch fixes bug with stopping and restarting replay through monitor.
--- block/blkreplay.c | 15 +++++---------- cpus.c | 1 + include/sysemu/replay.h | 4 ++++ replay/replay-events.c | 8 ++++++++ replay/replay-internal.h | 6 ++++-- replay/replay-snapshot.c | 1 + stubs/replay.c | 5 +++++ vl.c | 1 + 8 files changed, 29 insertions(+), 12 deletions(-)
block/blkreplay.c +5 -10
@@ -21,11 +21,6 @@ typedef struct Request {QEMUBH *bh; } Request; -/* Next request id. -This counter is global, because requests from different -block devices should not get overlapping ids. */ -static uint64_t request_id; - static BlockDriverState *blkreplay_append_snapshot(BlockDriverState *bs, int flags, QDict *snapshot_options,
@@ -194,7 +189,7 @@ static void block_request_create(uint64_t reqid, BlockDriverState *bs, static int coroutine_fn blkreplay_co_preadv(BlockDriverState *bs,uint64_t offset,uint64_t bytes,QEMUIOVector *qiov,int flags) { -uint64_t reqid = request_id++; +uint64_t reqid =blkreplay_next_id ();int ret =bdrv_co_preadv (bs->file, offset, bytes, qiov, flags);block_request_create (reqid, bs,qemu_coroutine_self ());qemu_coroutine_yield ();
@@ -205,7 +200,7 @@ static int coroutine_fn blkreplay_co_preadv(BlockDriverState *bs, static int coroutine_fn blkreplay_co_pwritev(BlockDriverState *bs,uint64_t offset,uint64_t bytes,QEMUIOVector *qiov,int flags) { -uint64_t reqid = request_id++; +uint64_t reqid =blkreplay_next_id ();int ret =bdrv_co_pwritev (bs->file, offset, bytes, qiov, flags);block_request_create (reqid, bs,qemu_coroutine_self ());qemu_coroutine_yield ();
@@ -216,7 +211,7 @@ static int coroutine_fn blkreplay_co_pwritev(BlockDriverState *bs, static int coroutine_fn blkreplay_co_pwrite_zeroes(BlockDriverState *bs,int64_t offset,int count,BdrvRequestFlags flags) { -uint64_t reqid = request_id++; +uint64_t reqid =blkreplay_next_id ();int ret =bdrv_co_pwrite_zeroes (bs->file, offset, count, flags);block_request_create (reqid, bs,qemu_coroutine_self ());qemu_coroutine_yield ();
@@ -227,7 +222,7 @@ static int coroutine_fn blkreplay_co_pwrite_zeroes(BlockDriverState *bs, static int coroutine_fn blkreplay_co_pdiscard(BlockDriverState *bs,int64_t offset,int count) { -uint64_t reqid = request_id++; +uint64_t reqid =blkreplay_next_id ();int ret =bdrv_co_pdiscard (bs->file->bs, offset, count);block_request_create (reqid, bs,qemu_coroutine_self ());qemu_coroutine_yield ();
@@ -237,7 +232,7 @@ static int coroutine_fn blkreplay_co_pdiscard(BlockDriverState *bs, static int coroutine_fn blkreplay_co_flush(BlockDriverState *bs) { -uint64_t reqid = request_id++; +uint64_t reqid =blkreplay_next_id ();int ret =bdrv_co_flush (bs->file->bs);block_request_create (reqid, bs,qemu_coroutine_self ());qemu_coroutine_yield ();
cpus.c +1 -0
@@ -745,6 +745,7 @@ static int do_vm_stop(RunState state) }bdrv_drain_all (); +replay_disable_events (); ret =blk_flush_all ();return ret;
include/sysemu/replay.h +4 -0
@@ -107,6 +107,8 @@ bool replay_checkpoint(ReplayCheckpoint checkpoint);/*! Disables storing events in the queue */ void replay_disable_events (void ); +/*! Enables storing events in the queue */ +void replay_enable_events (void );/*! Returns true when saving events is enabled */ bool replay_events_enabled (void );/*! Adds bottom half event to the queue */
@@ -117,6 +119,8 @@ void replay_input_event(QemuConsole *src, InputEvent *evt);void replay_input_sync_event (void );/*! Adds block layer event to the queue */ void replay_block_event (QEMUBH *bh,uint64_t id); +/*! Returns ID for the next block event */ +uint64_t blkreplay_next_id (void );/* Character device */
replay/replay-events.c +8 -0
@@ -320,3 +320,11 @@ bool replay_events_enabled(void) {return events_enabled; } + +uint64_t blkreplay_next_id (void ) +{ +if (replay_events_enabled ()) { +return replay_state.block_request_id++; + } +return 0 ; +}
replay/replay-internal.h +4 -2
@@ -69,6 +69,10 @@ typedef struct ReplayState {unsigned int has_unread_data;/*! Temporary variable for saving current log offset. */ uint64_t file_offset; +/*! Next block operation id. +This counter is global, because requests from different +block devices should not get overlapping ids. */ +uint64_t block_request_id; } ReplayState;extern ReplayState replay_state;
@@ -124,8 +128,6 @@ void replay_read_next_clock(unsigned int kind);void replay_init_events (void );/*! Clears internal data structures for events handling */ void replay_finish_events (void ); -/*! Enables storing events in the queue */ -void replay_enable_events (void );/*! Flushes events queue */ void replay_flush_events (void );/*! Clears events list before loading new VM state */
replay/replay-snapshot.c +1 -0
@@ -49,6 +49,7 @@ static const VMStateDescription vmstate_replay = { VMSTATE_UINT32(data_kind, ReplayState), VMSTATE_UINT32(has_unread_data, ReplayState), VMSTATE_UINT64(file_offset, ReplayState), + VMSTATE_UINT64(block_request_id, ReplayState),VMSTATE_END_OF_LIST () }, };
stubs/replay.c +5 -0
@@ -67,3 +67,8 @@ void replay_char_read_all_save_buf(uint8_t *buf, int offset)void replay_block_event (QEMUBH *bh,uint64_t id) { } + +uint64_t blkreplay_next_id (void ) +{ +return 0 ; +}
vl.c +1 -0
@@ -746,6 +746,7 @@ void vm_start(void)if (runstate_is_running ()) {qapi_event_send_stop (&error_abort); }else { +replay_enable_events ();cpu_enable_ticks ();runstate_set (RUN_STATE_RUNNING );vm_state_notify (1 ,RUN_STATE_RUNNING );
Re: [Qemu-devel] [PATCH v2 07/10] replay: allow replay stopping and restarting
Quoted 180 lines · Pavel Dovgalyuk
This patch fixes bug with stopping and restarting replay through monitor.
Signed-off-by Pavel Dovgalyuk <[email protected]>--- block/blkreplay.c | 15 +++++---------- cpus.c | 1 + include/sysemu/replay.h | 4 ++++ replay/replay-events.c | 8 ++++++++ replay/replay-internal.h | 6 ++++-- replay/replay-snapshot.c | 1 + stubs/replay.c | 5 +++++ vl.c | 1 + 8 files changed, 29 insertions(+), 12 deletions(-)block/blkreplay.c +5
-10@@ -21,11 +21,6 @@ typedef struct Request {QEMUBH *bh; } Request; -/* Next request id. -This counter is global, because requests from different -block devices should not get overlapping ids. */ -static uint64_t request_id; - static BlockDriverState *blkreplay_append_snapshot(BlockDriverState *bs, int flags, QDict *snapshot_options,@@ -194,7 +189,7 @@ static void block_request_create(uint64_t reqid, BlockDriverState *bs, static int coroutine_fn blkreplay_co_preadv(BlockDriverState *bs,uint64_t offset,uint64_t bytes,QEMUIOVector *qiov,int flags) { -uint64_t reqid = request_id++; +uint64_t reqid =blkreplay_next_id ();int ret =bdrv_co_preadv (bs->file, offset, bytes, qiov, flags);block_request_create (reqid, bs,qemu_coroutine_self ());qemu_coroutine_yield ();@@ -205,7 +200,7 @@ static int coroutine_fn blkreplay_co_preadv(BlockDriverState *bs, static int coroutine_fn blkreplay_co_pwritev(BlockDriverState *bs,uint64_t offset,uint64_t bytes,QEMUIOVector *qiov,int flags) { -uint64_t reqid = request_id++; +uint64_t reqid =blkreplay_next_id ();int ret =bdrv_co_pwritev (bs->file, offset, bytes, qiov, flags);block_request_create (reqid, bs,qemu_coroutine_self ());qemu_coroutine_yield ();@@ -216,7 +211,7 @@ static int coroutine_fn blkreplay_co_pwritev(BlockDriverState *bs, static int coroutine_fn blkreplay_co_pwrite_zeroes(BlockDriverState *bs,int64_t offset,int count,BdrvRequestFlags flags) { -uint64_t reqid = request_id++; +uint64_t reqid =blkreplay_next_id ();int ret =bdrv_co_pwrite_zeroes (bs->file, offset, count, flags);block_request_create (reqid, bs,qemu_coroutine_self ());qemu_coroutine_yield ();@@ -227,7 +222,7 @@ static int coroutine_fn blkreplay_co_pwrite_zeroes(BlockDriverState *bs, static int coroutine_fn blkreplay_co_pdiscard(BlockDriverState *bs,int64_t offset,int count) { -uint64_t reqid = request_id++; +uint64_t reqid =blkreplay_next_id ();int ret =bdrv_co_pdiscard (bs->file->bs, offset, count);block_request_create (reqid, bs,qemu_coroutine_self ());qemu_coroutine_yield ();@@ -237,7 +232,7 @@ static int coroutine_fn blkreplay_co_pdiscard(BlockDriverState *bs, static int coroutine_fn blkreplay_co_flush(BlockDriverState *bs) { -uint64_t reqid = request_id++; +uint64_t reqid =blkreplay_next_id ();int ret =bdrv_co_flush (bs->file->bs);block_request_create (reqid, bs,qemu_coroutine_self ());qemu_coroutine_yield ();cpus.c +1
-0@@ -745,6 +745,7 @@ static int do_vm_stop(RunState state) }bdrv_drain_all (); +replay_disable_events (); ret =blk_flush_all ();return ret;include/sysemu/replay.h +4
-0@@ -107,6 +107,8 @@ bool replay_checkpoint(ReplayCheckpoint checkpoint);/*! Disables storing events in the queue */ void replay_disable_events (void ); +/*! Enables storing events in the queue */ +void replay_enable_events (void );/*! Returns true when saving events is enabled */ bool replay_events_enabled (void );/*! Adds bottom half event to the queue */ @@ -117,6 +119,8 @@ void replay_input_event(QemuConsole *src, InputEvent *evt);void replay_input_sync_event (void );/*! Adds block layer event to the queue */ void replay_block_event (QEMUBH *bh,uint64_t id); +/*! Returns ID for the next block event */ +uint64_t blkreplay_next_id (void );/* Character device */ replay/replay-events.c +8
-0@@ -320,3 +320,11 @@ bool replay_events_enabled(void) {return events_enabled; } + +uint64_t blkreplay_next_id (void ) +{ +if (replay_events_enabled ()) { +return replay_state.block_request_id++; + } +return 0 ; +}replay/replay-internal.h +4
-2@@ -69,6 +69,10 @@ typedef struct ReplayState {unsigned int has_unread_data;/*! Temporary variable for saving current log offset. */ uint64_t file_offset; +/*! Next block operation id. +This counter is global, because requests from different +block devices should not get overlapping ids. */ +uint64_t block_request_id; } ReplayState;extern ReplayState replay_state;@@ -124,8 +128,6 @@ void replay_read_next_clock(unsigned int kind);void replay_init_events (void );/*! Clears internal data structures for events handling */ void replay_finish_events (void ); -/*! Enables storing events in the queue */ -void replay_enable_events (void );/*! Flushes events queue */ void replay_flush_events (void );/*! Clears events list before loading new VM state */ replay/replay-snapshot.c +1
-0@@ -49,6 +49,7 @@ static const VMStateDescription vmstate_replay = { VMSTATE_UINT32(data_kind, ReplayState), VMSTATE_UINT32(has_unread_data, ReplayState), VMSTATE_UINT64(file_offset, ReplayState), + VMSTATE_UINT64(block_request_id, ReplayState),VMSTATE_END_OF_LIST () }, };stubs/replay.c +5
-0@@ -67,3 +67,8 @@ void replay_char_read_all_save_buf(uint8_t *buf, int offset)void replay_block_event (QEMUBH *bh,uint64_t id) { } + +uint64_t blkreplay_next_id (void ) +{ +return 0 ; +}vl.c +0
-0
vl.c void vm_start(void) · line 749
Quoted 4 lines
vl.c +1
-0@@ -746,6 +746,7 @@ void vm_start(void)if (runstate_is_running ()) {qapi_event_send_stop (&error_abort); }else { +replay_enable_events ();
Can this be done with a change state notifier?
Paolo
Quoted 6 lines
vl.c +0
-0cpu_enable_ticks ();runstate_set (RUN_STATE_RUNNING );vm_state_notify (1 ,RUN_STATE_RUNNING );
Re: [Qemu-devel] [PATCH v2 07/10] replay: allow replay stopping and restarting
Quoted 5 lines
From: Paolo Bonzini [mailto:[email protected]] On Behalf Of Paolo Bonzini
Quoted 3 lines · Pavel Dovgalyuk
This patch fixes bug with stopping and restarting replay through monitor.
Quoted 13 lines
vl.c void vm_start(void) · line 749
Quoted 11 lines
Signed-off-by Pavel Dovgalyuk <[email protected]>---
vl.c +1
-0@@ -746,6 +746,7 @@ void vm_start(void)if (runstate_is_running ()) {qapi_event_send_stop (&error_abort); }else { +replay_enable_events ();Can this be done with a change state notifier?
We have to be sure that events are enabled before any of the callbacks will try to use events subsystem. Therefore enabling events must be the first thing to do.
Pavel Dovgalyuk
Re: [Qemu-devel] [PATCH v2 07/10] replay: allow replay stopping and restarting
Quoted 19 lines · Pavel Dovgalyuk
Quoted 5 lines
From: Paolo Bonzini [mailto:[email protected]] On Behalf Of Paolo Bonzini
Quoted 3 lines · Pavel Dovgalyuk
This patch fixes bug with stopping and restarting replay through monitor.
Quoted 13 lines
vl.c void vm_start(void) · line 749
Quoted 11 lines
Signed-off-by Pavel Dovgalyuk <[email protected]>---
vl.c +1
-0@@ -746,6 +746,7 @@ void vm_start(void)if (runstate_is_running ()) {qapi_event_send_stop (&error_abort); }else { +replay_enable_events ();Can this be done with a change state notifier?
Quoted 2 lines
We have to be sure that events are enabled before any of the callbacks will try to use events subsystem. Therefore enabling events must be the first thing to do.
Ok.
Paolo
PATCH v2 8/10 kvmvapic: fix state change handler
In reply to Pavel DovgalyukThis patch fixes kvmvapic state change handler.
It clears vmsentry field to allow recreating it
at further vmstate loads.
--- hw/i386/kvmvapic.c | 1 + 1 file changed, 1 insertion(+)
hw/i386/kvmvapic.c +1 -0
@@ -768,6 +768,7 @@ static void kvmvapic_vm_state_change(void *opaque, int running, }qemu_del_vm_change_state_handler (s->vmsentry); + s->vmsentry =NULL ; }static int vapic_post_load (void *opaque,int version_id)
PATCH v2 9/10 pcspk: adding vmstate for save/restore
In reply to Pavel DovgalyukVMState added by this patch preserves correct
loading of the PC speaker device state.
--- hw/audio/pcspk.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-)
hw/audio/pcspk.c +15 -2
@@ -52,8 +52,8 @@ typedef struct {unsigned int pit_count;unsigned int samples;unsigned int play_pos; -int data_on; -int dummy_refresh_clock; +uint8_t data_on; +uint8_t dummy_refresh_clock; } PCSpkState;static const char *s_spk ="pcspk" ;
@@ -187,6 +187,18 @@ static void pcspk_realizefn(DeviceState *dev, Error **errp) pcspk_state = s; } +static const VMStateDescription vmstate_spk = { + .name ="pcspk" , + .version_id =1 , + .minimum_version_id =1 , + .minimum_version_id_old =1 , + .fields = (VMStateField []) { +VMSTATE_UINT8 (data_on, PCSpkState), +VMSTATE_UINT8 (dummy_refresh_clock, PCSpkState), +VMSTATE_END_OF_LIST () + } +}; +static Property pcspk_properties[] = {DEFINE_PROP_UINT32 ("iobase" , PCSpkState, iobase,-1 ),DEFINE_PROP_END_OF_LIST (),
@@ -198,6 +210,7 @@ static void pcspk_class_initfn(ObjectClass *klass, void *data) dc->realize = pcspk_realizefn;set_bit (DEVICE_CATEGORY_SOUND , dc->categories); + dc->vmsd = &vmstate_spk; dc->props = pcspk_properties;/* Reason: realize sets global pcspk_state */ dc->cannot_instantiate_with_device_add_yet = true;
PATCH v2 10/10 integratorcp: adding vmstate for save/restore
In reply to Pavel DovgalyukFrom: Pavel Dovgalyuk <[email protected]>
VMState added by this patch preserves correct
loading of the integratorcp device state.
--- hw/arm/integratorcp.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+)
hw/arm/integratorcp.c +62 -0
@@ -53,6 +53,27 @@ static uint8_t integrator_spd[128] = {0xe ,4 ,0x1c ,1 ,2 ,0x20 ,0xc0 ,0 ,0 ,0 ,0 ,0x30 ,0x28 ,0x30 ,0x28 ,0x40 }; +static const VMStateDescription vmstate_integratorcm = { + .name ="integratorcm" , + .version_id =1 , + .minimum_version_id =1 , + .minimum_version_id_old =1 , + .fields = (VMStateField []) { +VMSTATE_UINT32 (cm_osc, IntegratorCMState), +VMSTATE_UINT32 (cm_ctrl, IntegratorCMState), +VMSTATE_UINT32 (cm_lock, IntegratorCMState), +VMSTATE_UINT32 (cm_auxosc, IntegratorCMState), +VMSTATE_UINT32 (cm_sdram, IntegratorCMState), +VMSTATE_UINT32 (cm_init, IntegratorCMState), +VMSTATE_UINT32 (cm_flags, IntegratorCMState), +VMSTATE_UINT32 (cm_nvflags, IntegratorCMState), +VMSTATE_UINT32 (int_level, IntegratorCMState), +VMSTATE_UINT32 (irq_enabled, IntegratorCMState), +VMSTATE_UINT32 (fiq_enabled, IntegratorCMState), +VMSTATE_END_OF_LIST () + } +}; +static uint64_t integratorcm_read (void *opaque,hwaddr offset,unsigned size) {
@@ -303,6 +324,19 @@ typedef struct icp_pic_state {qemu_irq parent_fiq; } icp_pic_state; +static const VMStateDescription vmstate_icp_pic = { + .name ="icp_pic" , + .version_id =1 , + .minimum_version_id =1 , + .minimum_version_id_old =1 , + .fields = (VMStateField []) { +VMSTATE_UINT32 (level, icp_pic_state), +VMSTATE_UINT32 (irq_enabled, icp_pic_state), +VMSTATE_UINT32 (fiq_enabled, icp_pic_state), +VMSTATE_END_OF_LIST () + } +}; +static void icp_pic_update (icp_pic_state *s) {uint32_t flags;
@@ -432,6 +466,17 @@ typedef struct ICPCtrlRegsState {#define ICP_INTREG_WPROT (1 << 0)#define ICP_INTREG_CARDIN (1 << 3) +static const VMStateDescription vmstate_icp_control = { + .name ="icp_control" , + .version_id =1 , + .minimum_version_id =1 , + .minimum_version_id_old =1 , + .fields = (VMStateField []) { +VMSTATE_UINT32 (intreg_state, ICPCtrlRegsState), +VMSTATE_END_OF_LIST () + } +}; +static uint64_t icp_control_read (void *opaque,hwaddr offset,unsigned size) {
@@ -633,6 +678,21 @@ static void core_class_init(ObjectClass *klass, void *data)DeviceClass *dc =DEVICE_CLASS (klass); dc->props = core_properties; + dc->vmsd = &vmstate_integratorcm; +} + +static void icp_pic_class_init (ObjectClass *klass,void *data) +{ +DeviceClass *dc =DEVICE_CLASS (klass); + + dc->vmsd = &vmstate_icp_pic; +} + +static void icp_control_class_init (ObjectClass *klass,void *data) +{ +DeviceClass *dc =DEVICE_CLASS (klass); + + dc->vmsd = &vmstate_icp_control; }static const TypeInfo core_info = {
@@ -648,6 +708,7 @@ static const TypeInfo icp_pic_info = { .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(icp_pic_state), .instance_init = icp_pic_init, + .class_init = icp_pic_class_init, };static const TypeInfo icp_ctrl_regs_info = {
@@ -655,6 +716,7 @@ static const TypeInfo icp_ctrl_regs_info = { .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(ICPCtrlRegsState), .instance_init = icp_control_init, + .class_init = icp_control_class_init, };static void integratorcp_register_types (void )
Paolo Bonzini
AppliedQuoted 18 lines · Pavel Dovgalyuk
This set of patches includes several fixes for replay and adds network record/replay for network devices. It also makes possible saving/restoring vmstate in replay mode.
Record and replay for network interactions is performed with the network filter. Each backend must have its own instance of the replay filter as follows:
-netdev user,id=net1 -device rtl8139,netdev=net1
-object filter-replay,id=replay,netdev=net1This patches add overlay option for blkreplay block driver. Using persistent overlay file allows saving and reloading VM snapshots in replay mode. Replay mechanism automatically creates one snapshot named '
replay_init' to allow rewinding execution while replaying.
Overlay file may be specified as follows:
-drive file=disk.qcow,if=none,id=img-direct
-drive driver=blkreplay,if=none,image=img-direct,overlay=overlay.qcow2,id=img-blkreplay -device ide-hd,drive=img-blkreplay
Quoted 6 lines
This set of patches includes fixes and additions for icount and record/replay implementation:
- Enabling VM start/stop in replay mode
- Adding network interaction record/replay
- Adding overlay option for blkreplay filter
- Fixes of the vmstate for several virtual devices
Queued patches 8 and 9. Patch 9 will break migration from 2.8 to 2.7, unfortunately, same as what happened for parallel in the past.
Paolo
Quoted 40 lines
---
Pavel Dovgalyuk (10):
record/replay: add network support
block: set snapshot option for block devices in blkreplay module
block: don't make snapshots for filters
replay: save/load initial state
replay: move internal data to the structure
replay: vmstate for replay module
replay: allow replay stopping and restarting
kvmvapic: fix state change handler
pcspk: adding vmstate for save/restore
integratorcp: adding vmstate for save/restoreblock/blkreplay.c | 132 +++++++++++++++++++++++++++++++++++++++++++--- block/snapshot.c | 3 + cpus.c | 1 docs/replay.txt | 22 ++++++++ hw/arm/integratorcp.c | 62 ++++++++++++++++++++++ hw/audio/pcspk.c | 17 +++++- hw/i386/kvmvapic.c | 1 include/sysemu/replay.h | 26 +++++++++ net/Makefile.objs | 1 net/filter-replay.c | 90 +++++++++++++++++++++++++++++++ replay/Makefile.objs | 2 + replay/replay-events.c | 21 +++++++ replay/replay-internal.c | 19 +++---- replay/replay-internal.h | 26 +++++++-- replay/replay-net.c | 110 ++++++++++++++++++++++++++++++++++++++ replay/replay-snapshot.c | 72 +++++++++++++++++++++++++ replay/replay-time.c | 2 - replay/replay.c | 17 +++--- stubs/replay.c | 5 ++ vl.c | 9 ++- 20 files changed, 599 insertions(+), 39 deletions(-) create mode 100644 net/filter-replay.c create mode 100644 replay/replay-net.c create mode 100644 replay/replay-snapshot.c