diff options
author | Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru> | 2016-09-26 11:08:16 +0300 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2016-09-27 11:57:30 +0200 |
commit | 6d0ceb80ffe18ad4b28aab7356f440636c0be7be (patch) | |
tree | 09d48a930e9a16114774f418c0888bf2809a1867 | |
parent | 306e196fa24c46d384577fb9c16e7cdb80f26d17 (diff) | |
download | qemu-6d0ceb80ffe18ad4b28aab7356f440636c0be7be.zip qemu-6d0ceb80ffe18ad4b28aab7356f440636c0be7be.tar.gz qemu-6d0ceb80ffe18ad4b28aab7356f440636c0be7be.tar.bz2 |
replay: allow replay stopping and restarting
This patch fixes bug with stopping and restarting replay
through monitor.
Signed-off-by: Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru>
Message-Id: <20160926080815.6992.71818.stgit@PASHA-ISP>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rwxr-xr-x | block/blkreplay.c | 15 | ||||
-rw-r--r-- | cpus.c | 1 | ||||
-rw-r--r-- | include/sysemu/replay.h | 4 | ||||
-rw-r--r-- | replay/replay-events.c | 8 | ||||
-rw-r--r-- | replay/replay-internal.h | 6 | ||||
-rw-r--r-- | replay/replay-snapshot.c | 1 | ||||
-rw-r--r-- | stubs/replay.c | 5 | ||||
-rw-r--r-- | vl.c | 1 |
8 files changed, 29 insertions, 12 deletions
diff --git a/block/blkreplay.c b/block/blkreplay.c index 30f9d5f..a741654 100755 --- a/block/blkreplay.c +++ b/block/blkreplay.c @@ -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(); @@ -750,6 +750,7 @@ static int do_vm_stop(RunState state) } bdrv_drain_all(); + replay_disable_events(); ret = blk_flush_all(); return ret; diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h index 0a88393..f80d6d2 100644 --- a/include/sysemu/replay.h +++ b/include/sysemu/replay.h @@ -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 */ diff --git a/replay/replay-events.c b/replay/replay-events.c index 4eb2ea3..c513913 100644 --- a/replay/replay-events.c +++ b/replay/replay-events.c @@ -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; +} diff --git a/replay/replay-internal.h b/replay/replay-internal.h index e07eb7d..9117e44 100644 --- a/replay/replay-internal.h +++ b/replay/replay-internal.h @@ -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 */ diff --git a/replay/replay-snapshot.c b/replay/replay-snapshot.c index a17e80e..4980597 100644 --- a/replay/replay-snapshot.c +++ b/replay/replay-snapshot.c @@ -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() }, }; diff --git a/stubs/replay.c b/stubs/replay.c index de9fa1e..d9a6da9 100644 --- a/stubs/replay.c +++ b/stubs/replay.c @@ -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; +} @@ -784,6 +784,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); |