replay additions
Subsystems (2)
v5 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 rrsnapshot option for icount. rrshapshot option creates start snapshot at record and loads it at replay. It allows preserving the state of disk images used by virtual machine. This vm state can also use used to roll back the execution while replaying.
This set of patches includes fixes and additions for icount and record/replay implementation:
- VM start/stop in replay mode
- Network interaction record/replay
- overlay option for blkreplay filter
- rrsnapshot option for record/replay
- vmstate fix for integratorcp ARM platform
v5 changes:
- Recording is stopped when initial snapshot cannot be created
- Minor changes
v4 changes:
- Overlay option is removed from blkreplay driver (as suggested by Paolo Bonzini)
- Minor changes
v3 changes:
- Added rrsnapshot option for specifying the initial snapshot name (as suggested by Paolo Bonzini)
- Minor changes
---
Pavel Dovgalyuk (9):
replay: move internal data to the structure
replay: vmstate for replay module
replay: allow replay stopping and restarting record/replay: add network support
savevm: add public save_vmstate function
replay: save/load initial state
block: don't make snapshots for filters
block: implement bdrv_recurse_is_first_non_filter for blkreplay
integratorcp: adding vmstate for save/restore
block/blkreplay.c | 24 ++++++----- block/snapshot.c | 3 + cpus.c | 1 docs/replay.txt | 30 ++++++++++++++ hw/arm/integratorcp.c | 62 ++++++++++++++++++++++++++++ include/sysemu/replay.h | 25 +++++++++++ include/sysemu/sysemu.h | 1 migration/savevm.c | 33 ++++++++++----- net/Makefile.objs | 1 net/filter-replay.c | 92 +++++++++++++++++++++++++++++++++++++++++ qemu-options.hx | 8 +++- replay/Makefile.objs | 2 + replay/replay-events.c | 21 +++++++++ replay/replay-internal.c | 20 ++++----- replay/replay-internal.h | 33 +++++++++++++-- replay/replay-net.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++ replay/replay-snapshot.c | 78 +++++++++++++++++++++++++++++++++++ replay/replay-time.c | 2 - replay/replay.c | 23 +++++++--- stubs/replay.c | 5 ++ vl.c | 14 +++++- 21 files changed, 528 insertions(+), 52 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 v5 1/9 replay: move internal data to the structure
This 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 | 20 +++++++++----------- replay/replay-internal.h | 8 +++++--- replay/replay-time.c | 2 +- replay/replay.c | 15 ++++++++------- 5 files changed, 24 insertions(+), 23 deletions(-)
replay/replay-events.c +1 -1
@@ -279,7 +279,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 +9 -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,16 @@ 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 +165,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
@@ -62,11 +62,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;
@@ -98,7 +100,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 ) {
PATCH v5 2/9 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.
--- replay/Makefile.objs | 1 + replay/replay-internal.h | 9 +++++++ replay/replay-snapshot.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++ replay/replay.c | 1 + 4 files changed, 71 insertions(+) create mode 100644 replay/replay-snapshot.c
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-snapshot.o
replay/replay-internal.h +9 -0
@@ -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
replay/replay-snapshot.c new file +60 -0
60 lines not on this page · raw message
replay/replay.c +1 -0
@@ -292,6 +292,7 @@ void replay_configure(QemuOpts *opts)exit (1 ); } +replay_vmstate_register ();replay_enable (fname, mode); out:
PATCH v5 3/9 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
@@ -20,11 +20,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 int blkreplay_open (BlockDriverState *bs,QDict *options,int flags,Error **errp) {
@@ -84,7 +79,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 ();
@@ -95,7 +90,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 ();
@@ -106,7 +101,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 ();
@@ -117,7 +112,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 ();
@@ -127,7 +122,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
@@ -751,6 +751,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
@@ -105,6 +105,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 */
@@ -115,6 +117,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
@@ -309,3 +309,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
@@ -68,6 +68,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;
@@ -123,8 +127,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
@@ -50,6 +50,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 );
PATCH v5 4/9 record/replay: add network support
In reply to Pavel DovgalyukThis 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.
v5 changes:
- using iov_to_buf function instead of loop
--- docs/replay.txt | 14 ++++++ include/sysemu/replay.h | 12 +++++ net/Makefile.objs | 1 net/filter-replay.c | 92 +++++++++++++++++++++++++++++++++++++++++ replay/Makefile.objs | 1 replay/replay-events.c | 11 +++++ replay/replay-internal.h | 10 +++++ replay/replay-net.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++ replay/replay.c | 2 - vl.c | 3 + 10 files changed, 246 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 */
@@ -137,4 +139,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 +92 -0
92 lines not on this page · raw message
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-snapshot.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 };
@@ -161,6 +162,15 @@ 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 ); +/* VMState-related functions */ /* Registers replay VMState.
replay/replay-net.c new file +102 -0
102 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
@@ -2808,7 +2808,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; }
Re: [Qemu-devel] [PATCH v5 4/9] record/replay: add network support
Quoted 14 lines · Pavel Dovgalyuk
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=net1Replay 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.
Quoted 5 lines
v5 changes:
- usingiov_to_buffunction instead of loopSigned-off-by Pavel Dovgalyuk<[email protected]>---
Re: [Qemu-devel] [PATCH v5 4/9] record/replay: add network support
Quoted 18 lines · Jason Wang
Quoted 15 lines · Pavel Dovgalyuk
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=net1Replay 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.
Quoted 7 lines
Quoted 5 lines
v5 changes:
- usingiov_to_buffunction instead of loopSigned-off-by Pavel Dovgalyuk<[email protected]>---
Reviewed-by Jason Wang <[email protected]>
Jason,
please merge this yourself through the net tree.
Thanks,
Paolo
Re: [Qemu-devel] [PATCH v5 4/9] record/replay: add network support
Quoted 24 lines · Paolo Bonzini
Quoted 22 lines · Jason Wang
Quoted 20 lines · Pavel Dovgalyuk
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=net1Replay 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.
v5 changes:
- usingiov_to_buffunction instead of loopSigned-off-by Pavel Dovgalyuk<[email protected]>---
Quoted 9 lines
Quoted 1 line
Reviewed-by Jason Wang <[email protected]>Jason,
please merge this yourself through the net tree.
Thanks,
Paolo
Picked in net.
Thanks
PATCH v5 5/9 savevm: add public save_vmstate function
In reply to Pavel DovgalyukThis patch introduces save_vmstate function to allow saving and loading vmstates from the replay module.
--- include/sysemu/sysemu.h | 1 + migration/savevm.c | 33 ++++++++++++++++++++++----------- 2 files changed, 23 insertions(+), 11 deletions(-)
include/sysemu/sysemu.h +1 -0
@@ -78,6 +78,7 @@ void qemu_add_machine_init_done_notifier(Notifier *notify);void qemu_remove_machine_init_done_notifier (Notifier *notify);void hmp_savevm (Monitor *mon,const QDict *qdict); +int save_vmstate (Monitor *mon,const char *name);int load_vmstate (const char *name);void hmp_delvm (Monitor *mon,const QDict *qdict);void hmp_info_snapshots (Monitor *mon,const QDict *qdict);
migration/savevm.c +22 -11
@@ -1958,38 +1958,40 @@ int qemu_loadvm_state(QEMUFile *f)return ret; } -void hmp_savevm (Monitor *mon,const QDict *qdict) +int save_vmstate (Monitor *mon,const char *name) {BlockDriverState *bs, *bs1;QEMUSnapshotInfo sn1, *sn = &sn1, old_sn1, *old_sn = &old_sn1; -int ret; +int ret =-1 ;QEMUFile *f;int saved_vm_running;uint64_t vm_state_size;qemu_timeval tv;struct tm tm; -const char *name =qdict_get_try_str (qdict,"name" );Error *local_err =NULL ;AioContext *aio_context;if (!bdrv_all_can_snapshot (&bs)) {monitor_printf (mon,"Device '%s' is writable but does not " "support snapshots.\n" ,bdrv_get_device_name (bs)); -return ; +return ret; }/* Delete old snapshots of the same name */ -if (name &&bdrv_all_delete_snapshot (name, &bs1, &local_err) <0 ) { -error_reportf_err (local_err, -"Error while deleting snapshot on device '%s': " , -bdrv_get_device_name (bs1)); -return ; +if (name) { + ret =bdrv_all_delete_snapshot (name, &bs1, &local_err); +if (ret <0 ) { +error_reportf_err (local_err, +"Error while deleting snapshot on device '%s': " , +bdrv_get_device_name (bs1)); +return ret; + } } bs =bdrv_all_find_vmstate_bs ();if (bs ==NULL ) {monitor_printf (mon,"No block device can accept snapshots\n" ); -return ; +return ret; } aio_context =bdrv_get_aio_context (bs);
@@ -1998,7 +2000,7 @@ void hmp_savevm(Monitor *mon, const QDict *qdict) ret =global_state_store ();if (ret) {monitor_printf (mon,"Error saving global state\n" ); -return ; +return ret; }vm_stop (RUN_STATE_SAVE_VM );
@@ -2044,13 +2046,22 @@ void hmp_savevm(Monitor *mon, const QDict *qdict)if (ret <0 ) {monitor_printf (mon,"Error while creating snapshot on '%s'\n" ,bdrv_get_device_name (bs)); + goto the_end; } + ret =0 ; + the_end:aio_context_release (aio_context);if (saved_vm_running) {vm_start (); } +return ret; +} + +void hmp_savevm (Monitor *mon,const QDict *qdict) +{ +save_vmstate (mon,qdict_get_try_str (qdict,"name" )); }void qmp_xen_save_devices_state (const char *filename,Error **errp)
Re: [Qemu-devel] [PATCH v5 5/9] savevm: add public save_vmstate function
migration/savevm.c int qemu_loadvm_state(QEMUFile *f) · line 1961
Quoted 2 lines · Pavel Dovgalyuk
migration/savevm.c +1
-1-void hmp_savevm (Monitor *mon,const QDict *qdict) +int save_vmstate (Monitor *mon,const char *name)
Please change this to return an Error **.
Paolo
Quoted 43 lines
{ BlockDriverState *bs, *bs1; QEMUSnapshotInfo sn1, *sn = &sn1, old_sn1, *old_sn = &old_sn1;migration/savevm.c +11
-9-int ret; +int ret =-1 ;QEMUFile *f;int saved_vm_running;uint64_t vm_state_size;qemu_timeval tv;struct tm tm; -const char *name =qdict_get_try_str (qdict,"name" );Error *local_err =NULL ;AioContext *aio_context;if (!bdrv_all_can_snapshot (&bs)) {monitor_printf (mon,"Device '%s' is writable but does not " "support snapshots.\n" ,bdrv_get_device_name (bs)); -return ; +return ret; }/* Delete old snapshots of the same name */ -if (name &&bdrv_all_delete_snapshot (name, &bs1, &local_err) <0 ) { -error_reportf_err (local_err, -"Error while deleting snapshot on device '%s': " , -bdrv_get_device_name (bs1)); -return ; +if (name) { + ret =bdrv_all_delete_snapshot (name, &bs1, &local_err); +if (ret <0 ) { +error_reportf_err (local_err, +"Error while deleting snapshot on device '%s': " , +bdrv_get_device_name (bs1)); +return ret; + } } bs =bdrv_all_find_vmstate_bs ();if (bs ==NULL ) {monitor_printf (mon,"No block device can accept snapshots\n" ); -return ; +return ret; }
PATCH v5 6/9 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.
v4 changes:
- snapshots are not created by default anymore
v3 changes:
- added rrsnapshot option
--- docs/replay.txt | 16 ++++++++++++++++ include/sysemu/replay.h | 9 +++++++++ qemu-options.hx | 8 ++++++-- replay/replay-snapshot.c | 17 +++++++++++++++++ replay/replay.c | 5 +++++ vl.c | 10 ++++++++-- 6 files changed, 61 insertions(+), 4 deletions(-)
docs/replay.txt +16 -0
@@ -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 ---------------
include/sysemu/replay.h +9 -0
@@ -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 */
@@ -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
qemu-options.hx +6 -2
@@ -3367,12 +3367,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
@@ -3405,6 +3405,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, \
replay/replay-snapshot.c +17 -0
@@ -58,4 +58,21 @@ static const VMStateDescription vmstate_replay = {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 ); + } + } + } }
replay/replay.c +5 -0
@@ -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;
@@ -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);
@@ -346,6 +348,9 @@ void replay_finish(void) replay_filename =NULL ; } +g_free (replay_snapshot); + replay_snapshot =NULL ; +replay_finish_events ();replay_mutex_destroy (); }
vl.c +8 -2
@@ -460,6 +460,9 @@ static QemuOptsList qemu_icount_opts = { }, { .name = "rrfile", .type = QEMU_OPT_STRING, + }, { + .name = "rrsnapshot", + .type = QEMU_OPT_STRING, }, {/* end of list */ } },
@@ -4411,7 +4414,8 @@ int main(int argc, char **argv, char **envp) }/* open the virtual block devices */ -if (snapshot || replay_mode !=REPLAY_MODE_NONE ) { +if (snapshot + || (replay_mode !=REPLAY_MODE_NONE && !replay_snapshot)) {qemu_opts_foreach (qemu_find_opts ("drive" ), drive_enable_snapshot,NULL ,NULL ); }
@@ -4591,7 +4595,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 ; }
PATCH v5 7/9 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); }
Re: [Qemu-devel] [PATCH v5 7/9] block: don't make snapshots for filters
Am 26.09.2016 um 10:08 hat Pavel Dovgalyuk geschrieben:
Quoted 5 lines
This patch disables snapshotting for block driver filters. It is needed, because snapshots should be created in underlying disk images, not in filters itself.
Signed-off-by Pavel Dovgalyuk <[email protected]>
But that's exactly what the existing code implements? If a driver doesn't provide .bdrv_snapshot_goto, the request is redirected to bs->file.
Quoted 8 lines
block/snapshot.c | 3 +++ 1 file changed, 3 insertions(+)block/snapshot.c +0
-0
block/snapshot.c int bdrv_snapshot_goto(BlockDriverState *bs, · line 189
Quoted 6 lines
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 ; + }
This, on the other hand, doesn't redirect the request, but silently ignores it. That is, loading the snapshot will apparently succeed, but it wouldn't actually load anything and the disk would stay in its current state.
block/snapshot.c int bdrv_snapshot_goto(BlockDriverState *bs, · line 192
Quoted 3 lines
block/snapshot.c +0
-0if (drv->bdrv_snapshot_goto) {return drv->bdrv_snapshot_goto (bs, snapshot_id); }
Kevin
Re: [Qemu-devel] [PATCH v5 7/9] block: don't make snapshots for filters
Quoted 15 lines
From: Kevin Wolf [mailto:[email protected]]
Am 26.09.2016 um 10:08 hat Pavel Dovgalyuk geschrieben:Quoted 5 lines
This patch disables snapshotting for block driver filters. It is needed, because snapshots should be created in underlying disk images, not in filters itself.
Signed-off-by Pavel Dovgalyuk <[email protected]>But that's exactly what the existing code implements? If a driver doesn't provide .bdrv_snapshot_goto, the request is redirected to
bs->file.Quoted 3 lines
block/snapshot.c | 3 +++ 1 file changed, 3 insertions(+)
Quoted 16 lines
block/snapshot.c int bdrv_snapshot_goto(BlockDriverState *bs, · line 189
Quoted 11 lines
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 ; + }This, on the other hand, doesn't redirect the request, but silently ignores it. That is, loading the snapshot will apparently succeed, but it wouldn't actually load anything and the disk would stay in its current state.
In my use case bdrv_all_goto_snapshot iterates all block drivers, including filters and disk images. Therefore skipping goto for images is ok.
Maybe I should move this check to bdrv_can_snapshot?
Quoted 4 lines
block/snapshot.c int bdrv_snapshot_goto(BlockDriverState *bs, · line 192
Quoted 4 lines
block/snapshot.c +0
-0if (drv->bdrv_snapshot_goto) {return drv->bdrv_snapshot_goto (bs, snapshot_id); }
Pavel Dovgalyuk
Re: [Qemu-devel] [PATCH v5 7/9] block: don't make snapshots for filters
Am 26.09.2016 um 11:51 hat Pavel Dovgalyuk geschrieben:
Quoted 32 lines
Quoted 15 lines
From: Kevin Wolf [mailto:[email protected]]
Am 26.09.2016 um 10:08 hat Pavel Dovgalyuk geschrieben:Quoted 5 lines
This patch disables snapshotting for block driver filters. It is needed, because snapshots should be created in underlying disk images, not in filters itself.
Signed-off-by Pavel Dovgalyuk <[email protected]>But that's exactly what the existing code implements? If a driver doesn't provide .bdrv_snapshot_goto, the request is redirected to
bs->file.Quoted 3 lines
block/snapshot.c | 3 +++ 1 file changed, 3 insertions(+)Quoted 16 lines
block/snapshot.c int bdrv_snapshot_goto(BlockDriverState *bs, · line 189
Quoted 11 lines
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 ; + }This, on the other hand, doesn't redirect the request, but silently ignores it. That is, loading the snapshot will apparently succeed, but it wouldn't actually load anything and the disk would stay in its current state.
Quoted 2 lines
In my use case
bdrv_all_goto_snapshotiterates all block drivers, including filters and disk images. Therefore skipping goto for images is ok.
Hm, this can happy today indeed.
Originally, we only called bdrv_goto_snapshot() for all _top level_ BDSes, and this is still what you normally get. However, if you explicitly create a BDS (e.g. with its own -drive option), it is considered a top level BDS without actually being top level for the guest, and therefore the snapshotting function is called for it.
Of course, this is highly inefficient because the goto_snapshot request is passed by the filter driver and then called another time for the lower node, effectively loading the snapshot a second time.
On the other hand if you use a single -drive option to create both the qcow2 BDS and the blkreplay filter, we do need to pass down the goto_snapshot request because it won't be called for the qcow2 layer otherwise.
I'm not completely sure yet what the right behaviour would be here.
Kevin
Re: [Qemu-devel] [PATCH v5 7/9] block: don't make snapshots for filters
Quoted 45 lines
From: Kevin Wolf [mailto:[email protected]]
Am 26.09.2016 um 11:51 hat Pavel Dovgalyuk geschrieben:Quoted 32 lines
Quoted 15 lines
From: Kevin Wolf [mailto:[email protected]]
Am 26.09.2016 um 10:08 hat Pavel Dovgalyuk geschrieben:Quoted 5 lines
This patch disables snapshotting for block driver filters. It is needed, because snapshots should be created in underlying disk images, not in filters itself.
Signed-off-by Pavel Dovgalyuk <[email protected]>But that's exactly what the existing code implements? If a driver doesn't provide .bdrv_snapshot_goto, the request is redirected to
bs->file.Quoted 3 lines
block/snapshot.c | 3 +++ 1 file changed, 3 insertions(+)Quoted 16 lines
block/snapshot.c int bdrv_snapshot_goto(BlockDriverState *bs, · line 189
Quoted 11 lines
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 ; + }This, on the other hand, doesn't redirect the request, but silently ignores it. That is, loading the snapshot will apparently succeed, but it wouldn't actually load anything and the disk would stay in its current state.
Quoted 2 lines
In my use case
bdrv_all_goto_snapshotiterates all block drivers, including filters and disk images. Therefore skipping goto for images is ok.Hm, this can happy today indeed.
Originally, we only called
bdrv_goto_snapshot()for all_toplevel_BDSes, and this is still what you normally get. However, if you explicitly create a BDS (e.g. with its own -drive option), it is considered a top level BDS without actually being top level for the guest, and therefore the snapshotting function is called for it.
Quoted 8 lines
Of course, this is highly inefficient because the
goto_snapshotrequest is passed by the filter driver and then called another time for the lower node, effectively loading the snapshot a second time.On the other hand if you use a single -drive option to create both the qcow2 BDS and the blkreplay filter, we do need to pass down the
goto_snapshotrequest because it won't be called for the qcow2 layer otherwise.
How this can be specified in command line? I believed that separate -drive option is required.
Quoted 2 lines
I'm not completely sure yet what the right behaviour would be here.
Pavel Dovgalyuk
Re: [Qemu-devel] [PATCH v5 7/9] block: don't make snapshots for filters
Am 27.09.2016 um 16:06 hat Pavel Dovgalyuk geschrieben:
Quoted 49 lines
Quoted 49 lines
From: Kevin Wolf [mailto:[email protected]]
Am 26.09.2016 um 11:51 hat Pavel Dovgalyuk geschrieben:Quoted 32 lines
Quoted 15 lines
From: Kevin Wolf [mailto:[email protected]]
Am 26.09.2016 um 10:08 hat Pavel Dovgalyuk geschrieben:Quoted 5 lines
This patch disables snapshotting for block driver filters. It is needed, because snapshots should be created in underlying disk images, not in filters itself.
Signed-off-by Pavel Dovgalyuk <[email protected]>But that's exactly what the existing code implements? If a driver doesn't provide .bdrv_snapshot_goto, the request is redirected to
bs->file.Quoted 3 lines
block/snapshot.c | 3 +++ 1 file changed, 3 insertions(+)Quoted 16 lines
block/snapshot.c int bdrv_snapshot_goto(BlockDriverState *bs, · line 189
Quoted 11 lines
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 ; + }This, on the other hand, doesn't redirect the request, but silently ignores it. That is, loading the snapshot will apparently succeed, but it wouldn't actually load anything and the disk would stay in its current state.
Quoted 2 lines
In my use case
bdrv_all_goto_snapshotiterates all block drivers, including filters and disk images. Therefore skipping goto for images is ok.Hm, this can happy today indeed.
Originally, we only called
bdrv_goto_snapshot()for all_toplevel_BDSes, and this is still what you normally get. However, if you explicitly create a BDS (e.g. with its own -drive option), it is considered a top level BDS without actually being top level for the guest, and therefore the snapshotting function is called for it.Of course, this is highly inefficient because the
goto_snapshotrequest is passed by the filter driver and then called another time for the lower node, effectively loading the snapshot a second time.
Quoted 7 lines
Quoted 4 lines
On the other hand if you use a single -drive option to create both the qcow2 BDS and the blkreplay filter, we do need to pass down the
goto_snapshotrequest because it won't be called for the qcow2 layer otherwise.How this can be specified in command line? I believed that separate -drive option is required.
Something like this:
-drive driver=blkreplay,image.driver=file,image.filename=test.img
Kevin
Re: [Qemu-devel] [PATCH v5 7/9] block: don't make snapshots for filters
Quoted 15 lines
From: Kevin Wolf [mailto:[email protected]]
Am 27.09.2016 um 16:06 hat Pavel Dovgalyuk geschrieben:Quoted 13 lines
Quoted 13 lines
From: Kevin Wolf [mailto:[email protected]]
Am 26.09.2016 um 11:51 hat Pavel Dovgalyuk geschrieben:Quoted 2 lines
Quoted 2 lines
From: Kevin Wolf [mailto:[email protected]]
Am 26.09.2016 um 10:08 hat Pavel Dovgalyuk geschrieben:Originally, we only called
bdrv_goto_snapshot()for all_toplevel_BDSes, and this is still what you normally get. However, if you explicitly create a BDS (e.g. with its own -drive option), it is considered a top level BDS without actually being top level for the guest, and therefore the snapshotting function is called for it.Of course, this is highly inefficient because the
goto_snapshotrequest is passed by the filter driver and then called another time for the lower node, effectively loading the snapshot a second time.
Maybe double-saving/loading does the smallest damage then? And we should just document how to use blkreplay effectively?
Quoted 6 lines
Quoted 6 lines
Quoted 5 lines
On the other hand if you use a single -drive option to create both the qcow2 BDS and the blkreplay filter, we do need to pass down the
goto_snapshotrequest because it won't be called for the qcow2 layer otherwise.
Quoted 7 lines
Quoted 2 lines
How this can be specified in command line? I believed that separate -drive option is required.
Something like this:
-drive driver=blkreplay,image.driver=file,image.filename=test.img
I tried the following command line, but VM does not detect the hard drive and cannot boot.
-drive driver=blkreplay,if=none,image.driver=file,image.filename=testdisk.qcow,id=img-blkreplay -device ide-hd,drive=img-blkreplay
Pavel Dovgalyuk
Re: [Qemu-devel] [PATCH v5 7/9] block: don't make snapshots for filters
Am 28.09.2016 um 11:32 hat Pavel Dovgalyuk geschrieben:
Quoted 36 lines
Quoted 15 lines
From: Kevin Wolf [mailto:[email protected]]
Am 27.09.2016 um 16:06 hat Pavel Dovgalyuk geschrieben:Quoted 13 lines
Quoted 13 lines
From: Kevin Wolf [mailto:[email protected]]
Am 26.09.2016 um 11:51 hat Pavel Dovgalyuk geschrieben:Quoted 2 lines
Quoted 2 lines
From: Kevin Wolf [mailto:[email protected]]
Am 26.09.2016 um 10:08 hat Pavel Dovgalyuk geschrieben:Originally, we only called
bdrv_goto_snapshot()for all_toplevel_BDSes, and this is still what you normally get. However, if you explicitly create a BDS (e.g. with its own -drive option), it is considered a top level BDS without actually being top level for the guest, and therefore the snapshotting function is called for it.Of course, this is highly inefficient because the
goto_snapshotrequest is passed by the filter driver and then called another time for the lower node, effectively loading the snapshot a second time.Maybe double-saving/loading does the smallest damage then? And we should just document how to use blkreplay effectively?
Quoted 6 lines
Quoted 6 lines
Quoted 5 lines
On the other hand if you use a single -drive option to create both the qcow2 BDS and the blkreplay filter, we do need to pass down the
goto_snapshotrequest because it won't be called for the qcow2 layer otherwise.Quoted 7 lines
Quoted 2 lines
How this can be specified in command line? I believed that separate -drive option is required.
Something like this:
-drive driver=blkreplay,image.driver=file,image.filename=test.img
I tried the following command line, but VM does not detect the hard drive and cannot boot.
Review
Quoted 2 lines
(quoted diff) +0
-2-drive driver=blkreplay,if=none,image.driver=file,image.filename=testdisk.qcow,id=img-blkreplay -device ide-hd,drive=img-blkreplay
My command line was assuming a raw image. It looks like you're using a qcow (hopefully qcow2?) image. If so, then you need to include the qcow2 driver:
-drive driver=blkreplay,if=none,image.driver=qcow2,\
image.file.driver=file,image.file.filename=testdisk.qcow,id=img-blkreplay
Kevin
Re: [Qemu-devel] [PATCH v5 7/9] block: don't make snapshots for filters
Quoted 40 lines
From: Kevin Wolf [mailto:[email protected]]
Am 28.09.2016 um 11:32 hat Pavel Dovgalyuk geschrieben:Quoted 30 lines
Quoted 15 lines
From: Kevin Wolf [mailto:[email protected]]
Am 27.09.2016 um 16:06 hat Pavel Dovgalyuk geschrieben:Quoted 13 lines
Quoted 13 lines
From: Kevin Wolf [mailto:[email protected]]
Am 26.09.2016 um 11:51 hat Pavel Dovgalyuk geschrieben:Quoted 2 lines
Quoted 2 lines
From: Kevin Wolf [mailto:[email protected]]
Am 26.09.2016 um 10:08 hat Pavel Dovgalyuk geschrieben:Originally, we only called
bdrv_goto_snapshot()for all_toplevel_BDSes, and this is still what you normally get. However, if you explicitly create a BDS (e.g. with its own -drive option), it is considered a top level BDS without actually being top level for the guest, and therefore the snapshotting function is called for it.Of course, this is highly inefficient because the
goto_snapshotrequest is passed by the filter driver and then called another time for the lower node, effectively loading the snapshot a second time.Maybe double-saving/loading does the smallest damage then? And we should just document how to use blkreplay effectively?
Quoted 11 lines
Quoted 8 lines
Quoted 5 lines
On the other hand if you use a single -drive option to create both the qcow2 BDS and the blkreplay filter, we do need to pass down the
goto_snapshotrequest because it won't be called for the qcow2 layer otherwise.How this can be specified in command line? I believed that separate -drive option is required.
Something like this:
Quoted 7 lines
Quoted 2 lines
-drive driver=blkreplay,image.driver=file,image.filename=test.img
I tried the following command line, but VM does not detect the hard drive and cannot boot.
-drive driver=blkreplay,if=none,image.driver=file,image.filename=testdisk.qcow,id=img-
blkreplay
Quoted 8 lines
Quoted 1 line
-device ide-hd,drive=img-blkreplay
My command line was assuming a raw image. It looks like you're using a qcow (hopefully qcow2?) image. If so, then you need to include the qcow2 driver:
-drive driver=blkreplay,if=none,image.driver=qcow2,\
image.file.driver=file,image.file.filename=testdisk.qcow,id=img-blkreplay
This doesn't work for some reason. Replay just hangs at some moment.
Maybe there exists some internal difference between command line with one or two -drive options?
Pavel Dovgalyuk
Re: [Qemu-devel] [PATCH v5 7/9] block: don't make snapshots for filters
Am 28.09.2016 um 14:49 hat Pavel Dovgalyuk geschrieben:
Quoted 46 lines
Quoted 46 lines
From: Kevin Wolf [mailto:[email protected]]
Am 28.09.2016 um 11:32 hat Pavel Dovgalyuk geschrieben:Quoted 30 lines
Quoted 15 lines
From: Kevin Wolf [mailto:[email protected]]
Am 27.09.2016 um 16:06 hat Pavel Dovgalyuk geschrieben:Quoted 13 lines
Quoted 13 lines
From: Kevin Wolf [mailto:[email protected]]
Am 26.09.2016 um 11:51 hat Pavel Dovgalyuk geschrieben:Quoted 2 lines
Quoted 2 lines
From: Kevin Wolf [mailto:[email protected]]
Am 26.09.2016 um 10:08 hat Pavel Dovgalyuk geschrieben:Originally, we only called
bdrv_goto_snapshot()for all_toplevel_BDSes, and this is still what you normally get. However, if you explicitly create a BDS (e.g. with its own -drive option), it is considered a top level BDS without actually being top level for the guest, and therefore the snapshotting function is called for it.Of course, this is highly inefficient because the
goto_snapshotrequest is passed by the filter driver and then called another time for the lower node, effectively loading the snapshot a second time.Maybe double-saving/loading does the smallest damage then? And we should just document how to use blkreplay effectively?
Quoted 11 lines
Quoted 8 lines
Quoted 5 lines
On the other hand if you use a single -drive option to create both the qcow2 BDS and the blkreplay filter, we do need to pass down the
goto_snapshotrequest because it won't be called for the qcow2 layer otherwise.How this can be specified in command line? I believed that separate -drive option is required.
Something like this:
Quoted 7 lines
Quoted 2 lines
-drive driver=blkreplay,image.driver=file,image.filename=test.img
I tried the following command line, but VM does not detect the hard drive and cannot boot.
-drive driver=blkreplay,if=none,image.driver=file,image.filename=testdisk.qcow,id=img-
blkreplay
Quoted 1 line
-device ide-hd,drive=img-blkreplay
My command line was assuming a raw image. It looks like you're using a qcow (hopefully qcow2?) image. If so, then you need to include the qcow2 driver:
Quoted 6 lines
Quoted 2 lines
-drive driver=blkreplay,if=none,image.driver=qcow2,\
image.file.driver=file,image.file.filename=testdisk.qcow,id=img-blkreplayThis doesn't work for some reason. Replay just hangs at some moment.
Maybe there exists some internal difference between command line with one or two -drive options?
There are some subtle differences that affect the management of the block driver nodes, but they shouldn't make a difference for the I/O path. But I don't know the replay code well, so maybe it makes a difference there (which would be a bug).
If you have two separate -drive options, a BlockBackend is created for each of them. The lower layer one wouldn't be used normally, but if you iterate over all BlockBackends somewhere, you would see it. Both BBs are owned by the monitor, and if you remove the top layer, the monitor reference will keep the lower layer alive.
In contrast, with a single -drive option, only the top layer (blkreplay) has a BlockBackend attached, but the qcow2 layer doesn't. If the blkreplay BlockBackend is deleted, the qcow2 layer automatically goes away as well because the monitor doesn't hold a reference to it.
I think these are the most important (and possibly the only) differences.
Kevin
Re: [Qemu-devel] [PATCH v5 7/9] block: don't make snapshots for filters
In reply to Pavel DovgalyukKevin,
Quoted 47 lines
From: Pavel Dovgalyuk [mailto:[email protected]]
Quoted 46 lines
From: Kevin Wolf [mailto:[email protected]]
Am 28.09.2016 um 11:32 hat Pavel Dovgalyuk geschrieben:Quoted 30 lines
Quoted 15 lines
From: Kevin Wolf [mailto:[email protected]]
Am 27.09.2016 um 16:06 hat Pavel Dovgalyuk geschrieben:Quoted 13 lines
Quoted 13 lines
From: Kevin Wolf [mailto:[email protected]]
Am 26.09.2016 um 11:51 hat Pavel Dovgalyuk geschrieben:Quoted 2 lines
Quoted 2 lines
From: Kevin Wolf [mailto:[email protected]]
Am 26.09.2016 um 10:08 hat Pavel Dovgalyuk geschrieben:Originally, we only called
bdrv_goto_snapshot()for all_toplevel_BDSes, and this is still what you normally get. However, if you explicitly create a BDS (e.g. with its own -drive option), it is considered a top level BDS without actually being top level for the guest, and therefore the snapshotting function is called for it.Of course, this is highly inefficient because the
goto_snapshotrequest is passed by the filter driver and then called another time for the lower node, effectively loading the snapshot a second time.Maybe double-saving/loading does the smallest damage then? And we should just document how to use blkreplay effectively?
Quoted 11 lines
Quoted 8 lines
Quoted 5 lines
On the other hand if you use a single -drive option to create both the qcow2 BDS and the blkreplay filter, we do need to pass down the
goto_snapshotrequest because it won't be called for the qcow2 layer otherwise.How this can be specified in command line? I believed that separate -drive option is required.
Something like this:
Quoted 7 lines
Quoted 2 lines
-drive driver=blkreplay,image.driver=file,image.filename=test.img
I tried the following command line, but VM does not detect the hard drive and cannot boot.
-drive driver=blkreplay,if=none,image.driver=file,image.filename=testdisk.qcow,id=img-
blkreplay
Quoted 1 line
-device ide-hd,drive=img-blkreplay
My command line was assuming a raw image. It looks like you're using a qcow (hopefully qcow2?) image. If so, then you need to include the qcow2 driver:
Quoted 7 lines
Quoted 2 lines
-drive driver=blkreplay,if=none,image.driver=qcow2,\
image.file.driver=file,image.file.filename=testdisk.qcow,id=img-blkreplayThis doesn't work for some reason. Replay just hangs at some moment.
Maybe there exists some internal difference between command line with one or two -drive options?
I've investigated this issue.
This command line works ok:
-drive driver=blkreplay,if=none,image.driver=file,image.filename=testdisk.qcow,id=img-blkreplay -device ide-hd,drive=img-blkreplay
And this does not:
-drive
driver=blkreplay,if=none,image.driver=qcow2,image.file.driver=file,image.file.filename=testdisk.qcow ,id=img-blkreplay
-device ide-hd,drive=img-blkreplay
QEMU hangs at some moment of replay.
I found that some dma requests do not pass through the blkreplay driver due to the following line in block-backend.c:
return bdrv_co_preadv(blk->root, offset, bytes, qiov, flags);
This line passes read request directly to qcow driver and blkreplay cannot process it to make deterministic.
Pavel Dovgalyuk
Re: [Qemu-devel] [PATCH v5 7/9] block: don't make snapshots for filters
Quoted 14 lines
I've investigated this issue.
This command line works ok:
-drive driver=blkreplay,if=none,image.driver=file,image.filename=testdisk.qcow,id=img-blkreplay -device ide-hd,drive=img-blkreplayAnd this does not:
-drive
driver=blkreplay,if=none,image.driver=qcow2,image.file.driver=file,image.file.filename=testdisk.qcow ,id=img-blkreplay
-device ide-hd,drive=img-blkreplay
Quoted 8 lines
QEMU hangs at some moment of replay.
I found that some dma requests do not pass through the blkreplay driver due to the following line in
block-backend.c:return bdrv_co_preadv(blk->root, offset, bytes, qiov, flags);This line passes read request directly to qcow driver and blkreplay cannot process it to make deterministic.
I don't understand, blk->root should be the blkreplay here.
Paolo
Re: [Qemu-devel] [PATCH v5 7/9] block: don't make snapshots for filters
Quoted 17 lines
From: Paolo Bonzini [mailto:[email protected]]
Quoted 9 lines
I've investigated this issue.
This command line works ok:
-drive driver=blkreplay,if=none,image.driver=file,image.filename=testdisk.qcow,id=img-blkreplay -device ide-hd,drive=img-blkreplayAnd this does not:
-drivedriver=blkreplay,if=none,image.driver=qcow2,image.file.driver=file,image.file.filename=testdis k.qcow
Quoted 5 lines
,id=img-blkreplay
-device ide-hd,drive=img-blkreplayQEMU hangs at some moment of replay.
Quoted 8 lines
Quoted 6 lines
I found that some dma requests do not pass through the blkreplay driver due to the following line in
block-backend.c:return bdrv_co_preadv(blk->root, offset, bytes, qiov, flags);This line passes read request directly to qcow driver and blkreplay cannot process it to make deterministic.
I don't understand,
blk->rootshould be the blkreplay here.
I've got some more logs. I used the disk image which references the backing file. It seems that some weird things happen with both command lines.
== For the first command line (blkreplay separated from image):blk_co_preadv(img-blkreplay)
-> bdrv_co_preadv(qcow2, temp_overlay1)
-> bdrv_co_preadv(blkreplay, temp_overlay)
-> bdrv_co_preadv(qcow2, temp_overlay2)
-> bdrv_co_preadv(qcow2, image_overlay)
-> bdrv_co_preadv(qcow2, image_backing)
-> bdrv_co_preadv(file, image_backing)
But sometimes it changes to:blk_co_preadv(img-blkreplay)
-> bdrv_co_preadv(qcow2, temp_overlay1)
-> bdrv_co_preadv(file, temp_overlay1)
== For the second command line (blkreplay combined with image):
In most cases we have the following call stack:blk_co_preadv(img-blkreplay)
-> bdrv_co_preadv(qcow2, temp_overlay)
-> bdrv_co_preadv(blkreplay, image_overlay)
-> bdrv_co_preadv(qcow2, image_overlay)
-> bdrv_co_preadv(qcow2, image_backing)
-> bdrv_co_preadv(file, image_backing)
But sometimes it changes to:blk_co_preadv(img-blkreplay)
-> bdrv_co_preadv(qcow2, temp overlay)
-> bdrv_co_preadv(file, temp overlay)
========
It seems, that temporary overlay is created over blkreplay, which it intended to work as a simple filter. Is that correct?
Pavel Dovgalyuk
Re: [Qemu-devel] [PATCH v5 7/9] block: don't make snapshots for filters
In reply to Pavel DovgalyukAm 16.11.2016 um 10:49 hat Pavel Dovgalyuk geschrieben:
Quoted 25 lines
Quoted 6 lines
From: Pavel Dovgalyuk [mailto:[email protected]]
Quoted 5 lines
From: Kevin Wolf [mailto:[email protected]]
My command line was assuming a raw image. It looks like you're using a qcow (hopefully qcow2?) image. If so, then you need to include the qcow2 driver:Quoted 7 lines
Quoted 2 lines
-drive driver=blkreplay,if=none,image.driver=qcow2,\
image.file.driver=file,image.file.filename=testdisk.qcow,id=img-blkreplayThis doesn't work for some reason. Replay just hangs at some moment.
Maybe there exists some internal difference between command line with one or two -drive options?
I've investigated this issue.
This command line works ok:
-drive driver=blkreplay,if=none,image.driver=file,image.filename=testdisk.qcow,id=img-blkreplay -device ide-hd,drive=img-blkreplayAnd this does not:
-drive
driver=blkreplay,if=none,image.driver=qcow2,image.file.driver=file,image.file.filename=testdisk.qcow ,id=img-blkreplay
-device ide-hd,drive=img-blkreplay
Quoted 8 lines
QEMU hangs at some moment of replay.
I found that some dma requests do not pass through the blkreplay driver due to the following line in
block-backend.c:return bdrv_co_preadv(blk->root, offset, bytes, qiov, flags);This line passes read request directly to qcow driver and blkreplay cannot process it to make deterministic.
How does that bypass blkreplay? blk->root is supposed to be the blkreply node, do you see something different? If it were the qcow2 node, then I would expect that no requests at all go through the blkreplay layer.
Kevin
Re: [Qemu-devel] [PATCH v5 7/9] block: don't make snapshots for filters
Quoted 24 lines
From: Kevin Wolf [mailto:[email protected]]
Am 16.11.2016 um 10:49 hat Pavel Dovgalyuk geschrieben:Quoted 5 lines
Quoted 1 line
From: Pavel Dovgalyuk [mailto:[email protected]]
I've investigated this issue.
This command line works ok:
-drive driver=blkreplay,if=none,image.driver=file,image.filename=testdisk.qcow,id=img-blkreplay
Quoted 5 lines
-device ide-hd,drive=img-blkreplay
And this does not:
-drivedriver=blkreplay,if=none,image.driver=qcow2,image.file.driver=file,image.file.filename=testdis k.qcow
Quoted 9 lines
,id=img-blkreplay
-device ide-hd,drive=img-blkreplayQEMU hangs at some moment of replay.
I found that some dma requests do not pass through the blkreplay driver due to the following line in
block-backend.c:return bdrv_co_preadv(blk->root, offset, bytes, qiov, flags);
Quoted 6 lines
Quoted 2 lines
This line passes read request directly to qcow driver and blkreplay cannot process it to make deterministic.
How does that bypass blkreplay?
blk->rootis supposed to be the blkreply node, do you see something different? If it were the qcow2 node, then I would expect that no requests at all go through the blkreplay layer.
It seems, that the problem is in -snapshot option.
We have one of the following block layers depending on command line:
tmp_overlay1 -> blkreplay -> tmp_overlay2 -> disk_image tmp_overlay1 -> blkreplay -> disk_image
But the correct scheme is intended to be the following:
blkreplay -> tmp_overlay1 -> disk_image
How can we fix it?
Maybe we should add blkreplay automatically to all block devices and not to specify it in the command line?
Pavel Dovgalyuk
Re: [Qemu-devel] [PATCH v5 7/9] block: don't make snapshots for filters
Am 21.11.2016 um 13:22 hat Pavel Dovgalyuk geschrieben:
Quoted 36 lines
Quoted 24 lines
From: Kevin Wolf [mailto:[email protected]]
Am 16.11.2016 um 10:49 hat Pavel Dovgalyuk geschrieben:Quoted 5 lines
Quoted 1 line
From: Pavel Dovgalyuk [mailto:[email protected]]
I've investigated this issue.
This command line works ok:
-drive driver=blkreplay,if=none,image.driver=file,image.filename=testdisk.qcow,id=img-blkreplay
Quoted 5 lines
-device ide-hd,drive=img-blkreplay
And this does not:
-drivedriver=blkreplay,if=none,image.driver=qcow2,image.file.driver=file,image.file.filename=testdis k.qcow
Quoted 9 lines
,id=img-blkreplay
-device ide-hd,drive=img-blkreplayQEMU hangs at some moment of replay.
I found that some dma requests do not pass through the blkreplay driver due to the following line in
block-backend.c:return bdrv_co_preadv(blk->root, offset, bytes, qiov, flags);Quoted 6 lines
Quoted 2 lines
This line passes read request directly to qcow driver and blkreplay cannot process it to make deterministic.
How does that bypass blkreplay?
blk->rootis supposed to be the blkreply node, do you see something different? If it were the qcow2 node, then I would expect that no requests at all go through the blkreplay layer.It seems, that the problem is in -snapshot option.
We have one of the following block layers depending on command line:
tmp_overlay1-> blkreplay ->tmp_overlay2->disk_imagetmp_overlay1-> blkreplay ->disk_image
Quoted 6 lines
But the correct scheme is intended to be the following:
blkreplay ->tmp_overlay1->disk_imageHow can we fix it?
Maybe we should add blkreplay automatically to all block devices and not to specify it in the command line?
I think you found a pretty fundamental design problem with "global" drive options that add a filter node such as -snapshot and replay mode (replay mode isn't one of them today, but your suggestion to make it automatic would turn it into one).
At the core of the problem I think we have two questions:
1. Which block nodes should be affected and get a filter node added, and which nodes shouldn't get one? In your case, disl_image is defined with a -drive option, but shouldn't get the snapshot.
2. In which order should filter nodes be added?
Both of these questions feel hard. As long as we haven't thought through the concept as such (rather than discussing one-off hacks) and we're not completely certain what the right answer to the questions is, we shouldn't add more automatic filter nodes, because chances are that we get it wrong and would regret it.
The obvious answer for a workaround would be: Make everything manual, i.e. don't use -snapshot, but create a qcow2 overlay manually.
For getting the automatic thing right, please give me some time to think about the design. I'll also meet Markus (CCed) in person end of next week and I think this is a design question that would be useful to discuss with him then.
Kevin
Re: [Qemu-devel] [PATCH v5 7/9] block: don't make snapshots for filters
Paolo,
Quoted 59 lines
From: Kevin Wolf [mailto:[email protected]]
Am 21.11.2016 um 13:22 hat Pavel Dovgalyuk geschrieben:Quoted 7 lines
Quoted 7 lines
From: Kevin Wolf [mailto:[email protected]]
Am 16.11.2016 um 10:49 hat Pavel Dovgalyuk geschrieben:Quoted 5 lines
Quoted 1 line
From: Pavel Dovgalyuk [mailto:[email protected]]
I've investigated this issue.
This command line works ok:
-drive driver=blkreplay,if=none,image.driver=file,image.filename=testdisk.qcow,id=img-Quoted 7 lines
Quoted 7 lines
blkreplay
Quoted 5 lines
-device ide-hd,drive=img-blkreplay
And this does not:
-drivedriver=blkreplay,if=none,image.driver=qcow2,image.file.driver=file,image.file.filename=testdis
Quoted 22 lines
Quoted 10 lines
k.qcow
Quoted 9 lines
,id=img-blkreplay
-device ide-hd,drive=img-blkreplayQEMU hangs at some moment of replay.
I found that some dma requests do not pass through the blkreplay driver due to the following line in
block-backend.c:return bdrv_co_preadv(blk->root, offset, bytes, qiov, flags);Quoted 6 lines
Quoted 2 lines
This line passes read request directly to qcow driver and blkreplay cannot process it to make deterministic.
How does that bypass blkreplay?
blk->rootis supposed to be the blkreply node, do you see something different? If it were the qcow2 node, then I would expect that no requests at all go through the blkreplay layer.It seems, that the problem is in -snapshot option.
We have one of the following block layers depending on command line:
tmp_overlay1-> blkreplay ->tmp_overlay2->disk_imagetmp_overlay1-> blkreplay ->disk_imageQuoted 6 lines
But the correct scheme is intended to be the following:
blkreplay ->tmp_overlay1->disk_imageHow can we fix it?
Maybe we should add blkreplay automatically to all block devices and not to specify it in the command line?I think you found a pretty fundamental design problem with "global" drive options that add a filter node such as -snapshot and replay mode (replay mode isn't one of them today, but your suggestion to make it automatic would turn it into one).
At the core of the problem I think we have two questions:
1. Which block nodes should be affected and get a filter node added, and which nodes shouldn't get one? In your case,
disl_imageis defined with a -drive option, but shouldn't get the snapshot.2. In which order should filter nodes be added?
Quoted 8 lines
Both of these questions feel hard. As long as we haven't thought through the concept as such (rather than discussing one-off hacks) and we're not completely certain what the right answer to the questions is, we shouldn't add more automatic filter nodes, because chances are that we get it wrong and would regret it.
The obvious answer for a workaround would be: Make everything manual, i.e. don't use -snapshot, but create a qcow2 overlay manually.
What about to switching to manual overlay creation by default? We can make rrsnapshot option mandatory.
Therefore user will have to create snapshot in image or overlay and the disk image will not be corrupted.
It is not very convenient, but we could disable rrsnapshot again when the solution for -snapshot will be found.
Quoted 4 lines
For getting the automatic thing right, please give me some time to think about the design. I'll also meet Markus (CCed) in person end of next week and I think this is a design question that would be useful to discuss with him then.
Pavel Dovgalyuk
Re: [Qemu-devel] [PATCH v5 7/9] block: don't make snapshots for filters
Am 05.12.2016 um 08:43 hat Pavel Dovgalyuk geschrieben:
Quoted 70 lines
Paolo,
Quoted 59 lines
From: Kevin Wolf [mailto:[email protected]]
Am 21.11.2016 um 13:22 hat Pavel Dovgalyuk geschrieben:Quoted 7 lines
Quoted 7 lines
From: Kevin Wolf [mailto:[email protected]]
Am 16.11.2016 um 10:49 hat Pavel Dovgalyuk geschrieben:Quoted 5 lines
Quoted 1 line
From: Pavel Dovgalyuk [mailto:[email protected]]
I've investigated this issue.
This command line works ok:
-drive driver=blkreplay,if=none,image.driver=file,image.filename=testdisk.qcow,id=img-Quoted 7 lines
Quoted 7 lines
blkreplay
Quoted 5 lines
-device ide-hd,drive=img-blkreplay
And this does not:
-drivedriver=blkreplay,if=none,image.driver=qcow2,image.file.driver=file,image.file.filename=testdis
Quoted 22 lines
Quoted 10 lines
k.qcow
Quoted 9 lines
,id=img-blkreplay
-device ide-hd,drive=img-blkreplayQEMU hangs at some moment of replay.
I found that some dma requests do not pass through the blkreplay driver due to the following line in
block-backend.c:return bdrv_co_preadv(blk->root, offset, bytes, qiov, flags);Quoted 6 lines
Quoted 2 lines
This line passes read request directly to qcow driver and blkreplay cannot process it to make deterministic.
How does that bypass blkreplay?
blk->rootis supposed to be the blkreply node, do you see something different? If it were the qcow2 node, then I would expect that no requests at all go through the blkreplay layer.It seems, that the problem is in -snapshot option.
We have one of the following block layers depending on command line:
tmp_overlay1-> blkreplay ->tmp_overlay2->disk_imagetmp_overlay1-> blkreplay ->disk_imageQuoted 6 lines
But the correct scheme is intended to be the following:
blkreplay ->tmp_overlay1->disk_imageHow can we fix it?
Maybe we should add blkreplay automatically to all block devices and not to specify it in the command line?I think you found a pretty fundamental design problem with "global" drive options that add a filter node such as -snapshot and replay mode (replay mode isn't one of them today, but your suggestion to make it automatic would turn it into one).
At the core of the problem I think we have two questions:
1. Which block nodes should be affected and get a filter node added, and which nodes shouldn't get one? In your case,
disl_imageis defined with a -drive option, but shouldn't get the snapshot.2. In which order should filter nodes be added?
Quoted 8 lines
Both of these questions feel hard. As long as we haven't thought through the concept as such (rather than discussing one-off hacks) and we're not completely certain what the right answer to the questions is, we shouldn't add more automatic filter nodes, because chances are that we get it wrong and would regret it.
The obvious answer for a workaround would be: Make everything manual, i.e. don't use -snapshot, but create a qcow2 overlay manually.
Quoted 7 lines
What about to switching to manual overlay creation by default? We can make rrsnapshot option mandatory.
Therefore user will have to create snapshot in image or overlay and the disk image will not be corrupted.It is not very convenient, but we could disable rrsnapshot again when the solution for -snapshot will be found.
Hm, what is this rrsnapshot option? git grep can't find it.
Anyway, it seems that doing things manually is the safe way as long as we don't know the final solution, so I think I agree.
For a slightly more convenient way, one of the problems to solve seems to be that snapshot=on always affects the top level node and you can't create a temporary snapshot in the middle of the chain. Perhaps we should introduce a 'temporary-overlay' driver or something like that, so that you could specify things like this:
-drive if=none,driver=file,filename=test.img,id=orig -drive if=none,driver=temporary-overlay,file=orig,id=snap -drive if=none,driver=blkreplay,image=snap
Which makes me wonder... Is blkreplay usable without the temporary snapshot or is this pretty much a requirement? Because if it has to be there, the next step could be that blkreplay creates temporary-overlay internally in its .bdrv_open().
Kevin
Re: [Qemu-devel] [PATCH v5 7/9] block: don't make snapshots for filters
Quoted 52 lines
From: Kevin Wolf [mailto:[email protected]]
Am 05.12.2016 um 08:43 hat Pavel Dovgalyuk geschrieben:Quoted 50 lines
Paolo,
Quoted 34 lines
From: Kevin Wolf [mailto:[email protected]]
Am 21.11.2016 um 13:22 hat Pavel Dovgalyuk geschrieben:Quoted 12 lines
Quoted 6 lines
From: Kevin Wolf [mailto:[email protected]]
Am 16.11.2016 um 10:49 hat Pavel Dovgalyuk geschrieben:How does that bypass blkreplay?
blk->rootis supposed to be the blkreply node, do you see something different? If it were the qcow2 node, then I would expect that no requests at all go through the blkreplay layer.It seems, that the problem is in -snapshot option.
We have one of the following block layers depending on command line:
tmp_overlay1-> blkreplay ->tmp_overlay2->disk_imagetmp_overlay1-> blkreplay ->disk_imageQuoted 6 lines
But the correct scheme is intended to be the following:
blkreplay ->tmp_overlay1->disk_imageHow can we fix it?
Maybe we should add blkreplay automatically to all block devices and not to specify it in the command line?I think you found a pretty fundamental design problem with "global" drive options that add a filter node such as -snapshot and replay mode (replay mode isn't one of them today, but your suggestion to make it automatic would turn it into one).
At the core of the problem I think we have two questions:
1. Which block nodes should be affected and get a filter node added, and which nodes shouldn't get one? In your case,
disl_imageis defined with a -drive option, but shouldn't get the snapshot.2. In which order should filter nodes be added?
Quoted 8 lines
Both of these questions feel hard. As long as we haven't thought through the concept as such (rather than discussing one-off hacks) and we're not completely certain what the right answer to the questions is, we shouldn't add more automatic filter nodes, because chances are that we get it wrong and would regret it.
The obvious answer for a workaround would be: Make everything manual, i.e. don't use -snapshot, but create a qcow2 overlay manually.
What about to switching to manual overlay creation by default? We can make rrsnapshot option mandatory.
Therefore user will have to create snapshot in image or overlay and the disk image will not be corrupted.
Quoted 4 lines
Quoted 2 lines
It is not very convenient, but we could disable rrsnapshot again when the solution for -snapshot will be found.
Hm, what is this rrsnapshot option? git grep can't find it.
It was a patch that was not included yet.
This option creates/loads vm snapshot in record/replay mode leaving original disk image unchanged.
Record/replay without this option uses '-snapshot' to preserve the state of the disk images.
Quoted 9 lines
Anyway, it seems that doing things manually is the safe way as long as we don't know the final solution, so I think I agree.
For a slightly more convenient way, one of the problems to solve seems to be that snapshot=on always affects the top level node and you can't create a temporary snapshot in the middle of the chain. Perhaps we should introduce a 'temporary-overlay' driver or something like that, so that you could specify things like this:
Quoted 3 lines
-drive if=none,driver=file,filename=test.img,id=orig -drive if=none,driver=temporary-overlay,file=orig,id=snap -drive if=none,driver=blkreplay,image=snap
This seems reasonable for manual way.
Quoted 2 lines
Which makes me wonder... Is blkreplay usable without the temporary snapshot or is this pretty much a requirement?
It's not a requirement. But to make replay deterministic we have to start with the same image every time. As I know, this may be achieved by:
1. Restoring original disk image manually
2. Using vm snapshot to start execution from
3. Using -snapshot option
4. Not using disks at all
Quoted 3 lines
Because if it has to be
there, the next step could be that blkreplay creates temporary-overlay internally in its .bdrv_open().
Here is your answer about such an approach :)
https://lists.gnu.org/archive/html/qemu-devel/2016-09/msg04687.html
Pavel Dovgalyuk
Re: [Qemu-devel] [PATCH v5 7/9] block: don't make snapshots for filters
Am 05.12.2016 um 12:49 hat Pavel Dovgalyuk geschrieben:
Quoted 52 lines
Quoted 52 lines
From: Kevin Wolf [mailto:[email protected]]
Am 05.12.2016 um 08:43 hat Pavel Dovgalyuk geschrieben:Quoted 50 lines
Paolo,
Quoted 34 lines
From: Kevin Wolf [mailto:[email protected]]
Am 21.11.2016 um 13:22 hat Pavel Dovgalyuk geschrieben:Quoted 12 lines
Quoted 6 lines
From: Kevin Wolf [mailto:[email protected]]
Am 16.11.2016 um 10:49 hat Pavel Dovgalyuk geschrieben:How does that bypass blkreplay?
blk->rootis supposed to be the blkreply node, do you see something different? If it were the qcow2 node, then I would expect that no requests at all go through the blkreplay layer.It seems, that the problem is in -snapshot option.
We have one of the following block layers depending on command line:
tmp_overlay1-> blkreplay ->tmp_overlay2->disk_imagetmp_overlay1-> blkreplay ->disk_imageQuoted 6 lines
But the correct scheme is intended to be the following:
blkreplay ->tmp_overlay1->disk_imageHow can we fix it?
Maybe we should add blkreplay automatically to all block devices and not to specify it in the command line?I think you found a pretty fundamental design problem with "global" drive options that add a filter node such as -snapshot and replay mode (replay mode isn't one of them today, but your suggestion to make it automatic would turn it into one).
At the core of the problem I think we have two questions:
1. Which block nodes should be affected and get a filter node added, and which nodes shouldn't get one? In your case,
disl_imageis defined with a -drive option, but shouldn't get the snapshot.2. In which order should filter nodes be added?
Quoted 8 lines
Both of these questions feel hard. As long as we haven't thought through the concept as such (rather than discussing one-off hacks) and we're not completely certain what the right answer to the questions is, we shouldn't add more automatic filter nodes, because chances are that we get it wrong and would regret it.
The obvious answer for a workaround would be: Make everything manual, i.e. don't use -snapshot, but create a qcow2 overlay manually.
What about to switching to manual overlay creation by default? We can make rrsnapshot option mandatory.
Therefore user will have to create snapshot in image or overlay and the disk image will not be corrupted.
Quoted 8 lines
Quoted 4 lines
Quoted 2 lines
It is not very convenient, but we could disable rrsnapshot again when the solution for -snapshot will be found.
Hm, what is this rrsnapshot option? git grep can't find it.
It was a patch that was not included yet.
This option creates/loads vm snapshot in record/replay mode leaving original disk image unchanged.
You mean internal qcow2 snapshots? Ok.
Quoted 12 lines
Record/replay without this option uses '-snapshot' to preserve the state of the disk images.
Quoted 9 lines
Anyway, it seems that doing things manually is the safe way as long as we don't know the final solution, so I think I agree.
For a slightly more convenient way, one of the problems to solve seems to be that snapshot=on always affects the top level node and you can't create a temporary snapshot in the middle of the chain. Perhaps we should introduce a 'temporary-overlay' driver or something like that, so that you could specify things like this:
Quoted 5 lines
Quoted 3 lines
-drive if=none,driver=file,filename=test.img,id=orig -drive if=none,driver=temporary-overlay,file=orig,id=snap -drive if=none,driver=blkreplay,image=snap
This seems reasonable for manual way.
Maybe another, easier to implement option could be something like this:
-drive if=none,driver=file,filename=test.img,snapshot=on,overlay.node-name=snap -drive if=none,driver=blkreplay,image=snap
It would require that we implement support for overlay.* options like we already support backing.* options. Allowing to specify options for the overlay node is probably nice to have anyway.
However, there could be a few tricky parts there. For example, what happens if someone uses overlay.backing=something-else? Perhaps completely disallowing backing and backing.* for overlays would already solve this.
Quoted 10 lines
Quoted 2 lines
Which makes me wonder... Is blkreplay usable without the temporary snapshot or is this pretty much a requirement?
It's not a requirement. But to make replay deterministic we have to start with the same image every time. As I know, this may be achieved by:
1. Restoring original disk image manually
2. Using vm snapshot to start execution from
3. Using -snapshot option
4. Not using disks at all
Quoted 6 lines
Quoted 3 lines
Because if it has to be
there, the next step could be that blkreplay creates temporary-overlay internally in its .bdrv_open().Here is your answer about such an approach :)
https://lists.gnu.org/archive/html/qemu-devel/2016-09/msg04687.html
Right, and unfortunately these are still good points.
Especially the part where you allowed to give the overlay filename really needs to work the way it does now with the 'image' option. We might not need to be that strict with temporary overlays, restricting to qcow2 with default options could be acceptable there - but whatever I think of to support both cases results in something that isn't really easier than the manual way that we figured out above.
Kevin
Re: [Qemu-devel] [PATCH v5 7/9] block: don't make snapshots for filters
Quoted 54 lines
From: Kevin Wolf [mailto:[email protected]]
Am 05.12.2016 um 12:49 hat Pavel Dovgalyuk geschrieben:Quoted 15 lines
Quoted 2 lines
From: Kevin Wolf [mailto:[email protected]]
Am 05.12.2016 um 08:43 hat Pavel Dovgalyuk geschrieben:Record/replay without this option uses '-snapshot' to preserve the state of the disk images.
Quoted 9 lines
Anyway, it seems that doing things manually is the safe way as long as we don't know the final solution, so I think I agree.
For a slightly more convenient way, one of the problems to solve seems to be that snapshot=on always affects the top level node and you can't create a temporary snapshot in the middle of the chain. Perhaps we should introduce a 'temporary-overlay' driver or something like that, so that you could specify things like this:
Quoted 5 lines
Quoted 3 lines
-drive if=none,driver=file,filename=test.img,id=orig -drive if=none,driver=temporary-overlay,file=orig,id=snap -drive if=none,driver=blkreplay,image=snap
This seems reasonable for manual way.
Maybe another, easier to implement option could be something like this:
-drive if=none,driver=file,filename=test.img,snapshot=on,overlay.node-name=snap -drive if=none,driver=blkreplay,image=snap
It would require that we implement support for overlay.* options like we already support backing.* options. Allowing to specify options for the overlay node is probably nice to have anyway.
However, there could be a few tricky parts there. For example, what happens if someone uses overlay.backing=something-else? Perhaps completely disallowing backing and backing.* for overlays would already solve this.
Quoted 10 lines
Quoted 2 lines
Which makes me wonder... Is blkreplay usable without the temporary snapshot or is this pretty much a requirement?
It's not a requirement. But to make replay deterministic we have to start with the same image every time. As I know, this may be achieved by:
1. Restoring original disk image manually
2. Using vm snapshot to start execution from
3. Using -snapshot option
4. Not using disks at allQuoted 6 lines
Quoted 3 lines
Because if it has to be
there, the next step could be that blkreplay creates temporary-overlay internally in its .bdrv_open().Here is your answer about such an approach :)
https://lists.gnu.org/archive/html/qemu-devel/2016-09/msg04687.html
Quoted 8 lines
Right, and unfortunately these are still good points.
Especially the part where you allowed to give the overlay filename really needs to work the way it does now with the 'image' option. We might not need to be that strict with temporary overlays, restricting to qcow2 with default options could be acceptable there - but whatever I think of to support both cases results in something that isn't really easier than the manual way that we figured out above.
Can we stop on the following?
1. Don't create any overlays automatically when user wants to save/restore VM state
2. In the opposite case create snapshots, but do not use -snapshot option. Snapshots will be created by the blkreplay as in the link specified.
Pavel Dovgalyuk
Re: [Qemu-devel] [PATCH v5 7/9] block: don't make snapshots for filters
In reply to Kevin WolfKevin,
Quoted 18 lines
From: Kevin Wolf [mailto:[email protected]]
Am 05.12.2016 um 12:49 hat Pavel Dovgalyuk geschrieben:Quoted 9 lines
Quoted 1 line
From: Kevin Wolf [mailto:[email protected]]
It's not a requirement. But to make replay deterministic we have to start with the same image every time. As I know, this may be achieved by:
1. Restoring original disk image manually
2. Using vm snapshot to start execution from
3. Using -snapshot option
4. Not using disks at allQuoted 6 lines
Quoted 3 lines
Because if it has to be
there, the next step could be that blkreplay creates temporary-overlay internally in its .bdrv_open().Here is your answer about such an approach :)
https://lists.gnu.org/archive/html/qemu-devel/2016-09/msg04687.html
Quoted 8 lines
Right, and unfortunately these are still good points.
Especially the part where you allowed to give the overlay filename really needs to work the way it does now with the 'image' option. We might not need to be that strict with temporary overlays, restricting to qcow2 with default options could be acceptable there - but whatever I think of to support both cases results in something that isn't really easier than the manual way that we figured out above.
What about the new version?
Pavel Dovgalyuk
PATCH v5 8/9 block: implement bdrv_recurse_is_first_non_filter for blkreplay
In reply to Pavel DovgalyukThis patch adds bdrv_recurse_is_first_non_filter implementation for blkreplay driver. It allows creating snapshots when blkreplay is enabled.
--- block/blkreplay.c | 9 +++++++++ 1 file changed, 9 insertions(+)
block/blkreplay.c +9 -0
@@ -130,6 +130,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" ,
@@ -145,6 +151,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 )
PATCH v5 9/9 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 22 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 rrsnapshot option for icount. rrshapshot option creates start snapshot at record and loads it at replay. It allows preserving the state of disk images used by virtual machine. This vm state can also use used to roll back the execution while replaying.
This set of patches includes fixes and additions for icount and record/replay implementation:
- VM start/stop in replay mode
- Network interaction record/replay
- overlay option for blkreplay filter
- rrsnapshot option for record/replay
- vmstate fix for integratorcp ARM platform
Quoted 3 lines
v5 changes:
- Recording is stopped when initial snapshot cannot be created
- Minor changes
Queued patches 1-3, thanks.
Paolo