Skip to contentSkip to conversation

replay additions

PATCH Applied Pavel Dovgalyuk 5 participants 36 messages Sep 26, 2016 – Dec 22, 2016

Subsystems (2)

v5 of 9 Applied Latest is v9 →

lore
Share & tools
lore
#0 lore raw

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
#1 lore raw

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
index 3807245..4eb2ea3 100644
@@ -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
index 5835e8d..bea7b4a 100644
@@ -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
index efbf14c..9b02d7d 100644
@@ -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
index fffe072..f70382a 100644
@@ -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
index 167fd29..cc2238d 100644
@@ -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) {
#2 lore raw

PATCH v5 2/9 replay: vmstate for replay module

In reply to Pavel Dovgalyuk

This 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
index fcb3f74..c8ad3eb 100644
@@ -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
index 9b02d7d..e07eb7d 100644
@@ -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
index cc2238d..c797aea 100644
@@ -292,6 +292,7 @@ void replay_configure(QemuOpts *opts)
         exit(1);
     }
 
+    replay_vmstate_register();
     replay_enable(fname, mode);
 
 out:
#3 lore raw

PATCH v5 3/9 replay: allow replay stopping and restarting

In reply to Pavel Dovgalyuk

This 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
index 30f9d5f..a741654 100644
@@ -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
index e39ccb7..2f5684f 100644
@@ -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
index 0a88393..f80d6d2 100644
@@ -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
index 4eb2ea3..c513913 100644
@@ -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
index e07eb7d..9117e44 100644
@@ -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
index 220248f..5609ea0 100644
@@ -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
index de9fa1e..d9a6da9 100644
@@ -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
index fca0487..c92e319 100644
@@ -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);
#4 lore raw

PATCH v5 4/9 record/replay: add network support

In reply to 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=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
index 779c6c0..347b2ff 100644
@@ -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
index f80d6d2..abb35ca 100644
@@ -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
index b7c22fd..f787ba4 100644
@@ -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
index c8ad3eb..b2afd40 100644
@@ -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
index c513913..94a6dcc 100644
@@ -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
index 9117e44..c26d079 100644
@@ -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
index c797aea..7f27cf1 100644
@@ -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
index c92e319..1298be1 100644
@@ -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;
     }
 
Reviewed-by on v5 4/9
#5 lore raw

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=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.

Quoted 5 lines

v5 changes:
- using iov_to_buf function instead of loop

---

#6 lore raw

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=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.

Quoted 7 lines
Quoted 5 lines

v5 changes:
- using iov_to_buf function instead of loop

---

Jason,

please merge this yourself through the net tree.

Thanks,

Paolo

#7 lore raw

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=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

---

Quoted 9 lines
Quoted 1 line

Jason,

please merge this yourself through the net tree.

Thanks,

Paolo

Picked in net.

Thanks

#8 lore raw

PATCH v5 5/9 savevm: add public save_vmstate function

In reply to Pavel Dovgalyuk

This 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
index ee7c760..b471b1e 100644
@@ -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
index 33a2911..f571da6 100644
@@ -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)
#9 lore raw

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;
     }
#10 lore raw

PATCH v5 6/9 replay: save/load initial state

In reply to Pavel Dovgalyuk

This patch implements initial vmstate creation or loading at the start of record/replay. It is needed for rewinding the execution in the replay mode.

v4 changes:
- snapshots are not created by default anymore

v3 changes:
- added rrsnapshot option

---
 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
index 347b2ff..03e1931 100644
@@ -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
index abb35ca..740b425 100644
@@ -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
index 0b621bb..1aa046e 100644
@@ -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
index 5609ea0..9a57026 100644
@@ -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
index 7f27cf1..1835b99 100644
@@ -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
index 1298be1..e1c90ef 100644
@@ -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;
         }
#11 lore raw

PATCH v5 7/9 block: don't make snapshots for filters

In reply to Pavel Dovgalyuk

This 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
index bf5c2ca..8998b8b 100644
@@ -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);
     }
#12 lore raw

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.

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
index bf5c2ca..8998b8b 100644

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 -0
     if (drv->bdrv_snapshot_goto) {
         return drv->bdrv_snapshot_goto(bs, snapshot_id);
     }

Kevin

#13 lore raw

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.

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
index bf5c2ca..8998b8b 100644
@@ -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 -0
     if (drv->bdrv_snapshot_goto) {
         return drv->bdrv_snapshot_goto(bs, snapshot_id);
     }

Pavel Dovgalyuk

#14 lore raw

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.

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
index bf5c2ca..8998b8b 100644
@@ -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_snapshot iterates 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

#15 lore raw

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.

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
index bf5c2ca..8998b8b 100644
@@ -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_snapshot iterates 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.

Quoted 8 lines

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.

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

#16 lore raw

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.

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
index bf5c2ca..8998b8b 100644
@@ -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_snapshot iterates 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.

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_snapshot request 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

#17 lore raw

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 _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.

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_snapshot request 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

#18 lore raw

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 _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.

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_snapshot request 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

#19 lore raw

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 _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.

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_snapshot request 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

#20 lore raw

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 _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.

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_snapshot request 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-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?

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

#21 lore raw

Re: [Qemu-devel] [PATCH v5 7/9] block: don't make snapshots for filters

In reply to Pavel Dovgalyuk

Kevin,

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 _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.

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_snapshot request 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-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?

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

#22 lore raw

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-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

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

#23 lore raw

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-blkreplay

And this does not:
-drive

driver=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-blkreplay

QEMU 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->root should 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

#24 lore raw

Re: [Qemu-devel] [PATCH v5 7/9] block: don't make snapshots for filters

In reply to Pavel Dovgalyuk

Am 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-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?

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

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

#25 lore raw

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:
-drive

driver=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-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);
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->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.

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

#26 lore raw

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:
-drive

driver=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-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);
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->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.

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

Quoted 6 lines

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?

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

#27 lore raw

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:
-drive

driver=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-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);
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->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.

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

Quoted 6 lines

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?

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?

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

#28 lore raw

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:
-drive

driver=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-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);
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->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.

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

Quoted 6 lines

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?

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?

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

#29 lore raw

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->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.

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

Quoted 6 lines

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?

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?

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

#30 lore raw

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->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.

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

Quoted 6 lines

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?

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?

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

#31 lore raw

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 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

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

#32 lore raw

Re: [Qemu-devel] [PATCH v5 7/9] block: don't make snapshots for filters

In reply to Kevin Wolf

Kevin,

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 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

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

#33 lore raw

PATCH v5 8/9 block: implement bdrv_recurse_is_first_non_filter for blkreplay

In reply to Pavel Dovgalyuk

This 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
index a741654..5a13fb3 100644
@@ -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)
#34 lore raw

PATCH v5 9/9 integratorcp: adding vmstate for save/restore

In reply to Pavel Dovgalyuk

From: 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
index 96dc150..3653df2 100644
@@ -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)
#35 lore raw
In reply to Pavel Dovgalyuk
Quoted 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=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

Quoted 3 lines

v5 changes:
- Recording is stopped when initial snapshot cannot be created
- Minor changes

Queued patches 1-3, thanks.

Paolo