[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH for-4.1 08/24] migration: introduce icount field for
From: |
Pavel Dovgalyuk |
Subject: |
[Qemu-devel] [PATCH for-4.1 08/24] migration: introduce icount field for snapshots |
Date: |
Fri, 21 Jun 2019 11:21:23 +0300 |
User-agent: |
StGit/0.17.1-dirty |
From: Pavel Dovgalyuk <address@hidden>
Saving icount as a parameters of the snapshot allows navigation between
them in the execution replay scenario.
This information can be used for finding a specific snapshot for proceeding
the recorded execution to the specific moment of the time.
E.g., 'reverse step' action (introduced in one of the following patches)
needs to load the nearest snapshot which is prior to the current moment
of time .
Signed-off-by: Pavel Dovgalyuk <address@hidden>
Acked-by: Markus Armbruster <address@hidden>
--
v2:
- made icount in SnapshotInfo optional (suggested by Eric Blake)
v7:
- added more comments for icount member (suggested by Markus Armbruster)
v9:
- updated icount comment
v10:
- updated icount comment again
---
block/qapi.c | 18 ++++++++++++++----
block/qcow2-snapshot.c | 2 ++
blockdev.c | 10 ++++++++++
include/block/snapshot.h | 1 +
migration/savevm.c | 5 +++++
qapi/block-core.json | 7 ++++++-
qapi/block.json | 3 ++-
7 files changed, 40 insertions(+), 6 deletions(-)
diff --git a/block/qapi.c b/block/qapi.c
index 917435f022..60295abf09 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -214,6 +214,8 @@ int bdrv_query_snapshot_info_list(BlockDriverState *bs,
info->date_nsec = sn_tab[i].date_nsec;
info->vm_clock_sec = sn_tab[i].vm_clock_nsec / 1000000000;
info->vm_clock_nsec = sn_tab[i].vm_clock_nsec % 1000000000;
+ info->icount = sn_tab[i].icount;
+ info->has_icount = sn_tab[i].icount != -1ULL;
info_list = g_new0(SnapshotInfoList, 1);
info_list->value = info;
@@ -635,14 +637,15 @@ BlockStatsList *qmp_query_blockstats(bool has_query_nodes,
void bdrv_snapshot_dump(QEMUSnapshotInfo *sn)
{
char date_buf[128], clock_buf[128];
+ char icount_buf[128] = {0};
struct tm tm;
time_t ti;
int64_t secs;
char *sizing = NULL;
if (!sn) {
- qemu_printf("%-10s%-20s%7s%20s%15s",
- "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK");
+ qemu_printf("%-10s%-18s%7s%20s%13s%11s",
+ "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK", "ICOUNT");
} else {
ti = sn->date_sec;
localtime_r(&ti, &tm);
@@ -656,11 +659,16 @@ void bdrv_snapshot_dump(QEMUSnapshotInfo *sn)
(int)(secs % 60),
(int)((sn->vm_clock_nsec / 1000000) % 1000));
sizing = size_to_str(sn->vm_state_size);
- qemu_printf("%-10s%-20s%7s%20s%15s",
+ if (sn->icount != -1ULL) {
+ snprintf(icount_buf, sizeof(icount_buf),
+ "%"PRId64, sn->icount);
+ }
+ qemu_printf("%-10s%-18s%7s%20s%13s%11s",
sn->id_str, sn->name,
sizing,
date_buf,
- clock_buf);
+ clock_buf,
+ icount_buf);
}
g_free(sizing);
}
@@ -822,6 +830,8 @@ void bdrv_image_info_dump(ImageInfo *info)
.date_nsec = elem->value->date_nsec,
.vm_clock_nsec = elem->value->vm_clock_sec * 1000000000ULL +
elem->value->vm_clock_nsec,
+ .icount = elem->value->has_icount ?
+ elem->value->icount : -1ULL,
};
pstrcpy(sn.id_str, sizeof(sn.id_str), elem->value->id);
diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c
index 2c2e9bd8da..7a3f4fc4f7 100644
--- a/block/qcow2-snapshot.c
+++ b/block/qcow2-snapshot.c
@@ -377,6 +377,7 @@ int qcow2_snapshot_create(BlockDriverState *bs,
QEMUSnapshotInfo *sn_info)
sn->date_sec = sn_info->date_sec;
sn->date_nsec = sn_info->date_nsec;
sn->vm_clock_nsec = sn_info->vm_clock_nsec;
+ sn->icount = sn_info->icount;
/* Allocate the L1 table of the snapshot and copy the current one there. */
l1_table_offset = qcow2_alloc_clusters(bs, s->l1_size * sizeof(uint64_t));
@@ -708,6 +709,7 @@ int qcow2_snapshot_list(BlockDriverState *bs,
QEMUSnapshotInfo **psn_tab)
sn_info->date_sec = sn->date_sec;
sn_info->date_nsec = sn->date_nsec;
sn_info->vm_clock_nsec = sn->vm_clock_nsec;
+ sn_info->icount = sn->icount;
}
*psn_tab = sn_tab;
return s->nb_snapshots;
diff --git a/blockdev.c b/blockdev.c
index 5d6a13dea9..7bd6930eed 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -58,6 +58,7 @@
#include "block/trace.h"
#include "sysemu/arch_init.h"
#include "sysemu/qtest.h"
+#include "sysemu/replay.h"
#include "qemu/cutils.h"
#include "qemu/help_option.h"
#include "qemu/throttle-options.h"
@@ -1241,6 +1242,10 @@ SnapshotInfo
*qmp_blockdev_snapshot_delete_internal_sync(const char *device,
info->vm_state_size = sn.vm_state_size;
info->vm_clock_nsec = sn.vm_clock_nsec % 1000000000;
info->vm_clock_sec = sn.vm_clock_nsec / 1000000000;
+ if (sn.icount != -1ULL) {
+ info->icount = sn.icount;
+ info->has_icount = true;
+ }
return info;
@@ -1448,6 +1453,11 @@ static void internal_snapshot_prepare(BlkActionState
*common,
sn->date_sec = tv.tv_sec;
sn->date_nsec = tv.tv_usec * 1000;
sn->vm_clock_nsec = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+ if (replay_mode != REPLAY_MODE_NONE) {
+ sn->icount = replay_get_current_step();
+ } else {
+ sn->icount = -1ULL;
+ }
ret1 = bdrv_snapshot_create(bs, sn);
if (ret1 < 0) {
diff --git a/include/block/snapshot.h b/include/block/snapshot.h
index b5d5084a12..deeb24c22c 100644
--- a/include/block/snapshot.h
+++ b/include/block/snapshot.h
@@ -42,6 +42,7 @@ typedef struct QEMUSnapshotInfo {
uint32_t date_sec; /* UTC date of the snapshot */
uint32_t date_nsec;
uint64_t vm_clock_nsec; /* VM clock relative to boot */
+ uint64_t icount; /* record/replay step */
} QEMUSnapshotInfo;
int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info,
diff --git a/migration/savevm.c b/migration/savevm.c
index c0e557b4c2..a113cc187d 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -2601,6 +2601,11 @@ int save_snapshot(const char *name, Error **errp)
sn->date_sec = tv.tv_sec;
sn->date_nsec = tv.tv_usec * 1000;
sn->vm_clock_nsec = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+ if (replay_mode != REPLAY_MODE_NONE) {
+ sn->icount = replay_get_current_step();
+ } else {
+ sn->icount = -1ULL;
+ }
if (name) {
ret = bdrv_snapshot_find(bs, old_sn, name);
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 0d43d4f37c..2c23214505 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -26,13 +26,18 @@
#
# @vm-clock-nsec: fractional part in nano seconds to be used with vm-clock-sec
#
+# @icount: Current instruction count. Appears when execution record/replay
+# is enabled. Used for "time-traveling" to match the moment
+# in the recorded execution with the snapshots. (since 4.1)
+#
# Since: 1.3
#
##
{ 'struct': 'SnapshotInfo',
'data': { 'id': 'str', 'name': 'str', 'vm-state-size': 'int',
'date-sec': 'int', 'date-nsec': 'int',
- 'vm-clock-sec': 'int', 'vm-clock-nsec': 'int' } }
+ 'vm-clock-sec': 'int', 'vm-clock-nsec': 'int',
+ '*icount': 'int' } }
##
# @ImageInfoSpecificQCow2EncryptionBase:
diff --git a/qapi/block.json b/qapi/block.json
index 145c268bb6..f389bb6f1a 100644
--- a/qapi/block.json
+++ b/qapi/block.json
@@ -176,7 +176,8 @@
# "date-sec": 1000012,
# "date-nsec": 10,
# "vm-clock-sec": 100,
-# "vm-clock-nsec": 20
+# "vm-clock-nsec": 20,
+# "icount": 220414
# }
# }
#
- [Qemu-devel] [PATCH for-4.1 15/24] replay: flush rr queue before loading the vmstate, (continued)
- [Qemu-devel] [PATCH for-4.1 15/24] replay: flush rr queue before loading the vmstate, Pavel Dovgalyuk, 2019/06/21
- [Qemu-devel] [PATCH for-4.1 19/24] replay: add BH oneshot event for block layer, Pavel Dovgalyuk, 2019/06/21
- [Qemu-devel] [PATCH for-4.1 13/24] replay: implement replay-seek command, Pavel Dovgalyuk, 2019/06/21
- [Qemu-devel] [PATCH for-4.1 11/24] replay: introduce info hmp/qmp command, Pavel Dovgalyuk, 2019/06/21
- [Qemu-devel] [PATCH for-4.1 21/24] util/qemu-timer: refactor deadline calculation for external timers, Pavel Dovgalyuk, 2019/06/21
- [Qemu-devel] [PATCH for-4.1 18/24] replay: describe reverse debugging in docs/replay.txt, Pavel Dovgalyuk, 2019/06/21
- [Qemu-devel] [PATCH for-4.1 17/24] gdbstub: add reverse continue support in replay mode, Pavel Dovgalyuk, 2019/06/21
- [Qemu-devel] [PATCH for-4.1 20/24] replay: document development rules, Pavel Dovgalyuk, 2019/06/21
- [Qemu-devel] [PATCH for-4.1 14/24] replay: refine replay-time module, Pavel Dovgalyuk, 2019/06/21
- [Qemu-devel] [PATCH for-4.1 09/24] replay: provide an accessor for rr filename, Pavel Dovgalyuk, 2019/06/21
- [Qemu-devel] [PATCH for-4.1 08/24] migration: introduce icount field for snapshots,
Pavel Dovgalyuk <=
- [Qemu-devel] [PATCH for-4.1 16/24] gdbstub: add reverse step support in replay mode, Pavel Dovgalyuk, 2019/06/21
- [Qemu-devel] [PATCH for-4.1 10/24] qapi: introduce replay.json for record/replay-related stuff, Pavel Dovgalyuk, 2019/06/21
- [Qemu-devel] [PATCH for-4.1 06/24] replay: finish record/replay before closing the disks, Pavel Dovgalyuk, 2019/06/21
- [Qemu-devel] [PATCH for-4.1 03/24] replay: disable default snapshot for record/replay, Pavel Dovgalyuk, 2019/06/21
- [Qemu-devel] [PATCH for-4.1 24/24] icount: clean up cpu_can_io before jumping to the next block, Pavel Dovgalyuk, 2019/06/21
- [Qemu-devel] [PATCH for-4.1 12/24] replay: introduce breakpoint at the specified step, Pavel Dovgalyuk, 2019/06/21
- [Qemu-devel] [PATCH for-4.1 07/24] qcow2: introduce icount field for snapshots, Pavel Dovgalyuk, 2019/06/21
- [Qemu-devel] [PATCH for-4.1 05/24] replay: don't drain/flush bdrv queue while RR is working, Pavel Dovgalyuk, 2019/06/21
- [Qemu-devel] [PATCH for-4.1 02/24] block: implement bdrv_snapshot_goto for blkreplay, Pavel Dovgalyuk, 2019/06/21
- [Qemu-devel] [PATCH for-4.1 04/24] replay: update docs for record/replay with block devices, Pavel Dovgalyuk, 2019/06/21