[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v3 07/19] migration: introduce icount field for snap
From: |
Pavel Dovgalyuk |
Subject: |
[Qemu-devel] [PATCH v3 07/19] migration: introduce icount field for snapshots |
Date: |
Wed, 23 May 2018 09:50:22 +0300 |
User-agent: |
StGit/0.17.1-dirty |
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 rewinding
the recorded execution to the specific moment of the time.
E.g., 'reverse step' action needs to load the nearest snapshot which is
prior to the current moment of time .
Signed-off-by: Pavel Dovgalyuk <address@hidden>
--
v2:
- made icount in SnapshotInfo optional (suggested by Eric Blake)
---
block/qapi.c | 17 +++++++++++++----
block/qcow2-snapshot.c | 2 ++
blockdev.c | 10 ++++++++++
include/block/snapshot.h | 1 +
migration/savevm.c | 5 +++++
qapi/block-core.json | 5 ++++-
qapi/block.json | 3 ++-
7 files changed, 37 insertions(+), 6 deletions(-)
diff --git a/block/qapi.c b/block/qapi.c
index e12968f..a89e180 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -210,6 +210,7 @@ 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_list = g_new0(SnapshotInfoList, 1);
info_list->value = info;
@@ -648,14 +649,15 @@ void bdrv_snapshot_dump(fprintf_function func_fprintf,
void *f,
QEMUSnapshotInfo *sn)
{
char buf1[128], date_buf[128], clock_buf[128];
+ char icount_buf[128] = {0};
struct tm tm;
time_t ti;
int64_t secs;
if (!sn) {
func_fprintf(f,
- "%-10s%-20s%7s%20s%15s",
- "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK");
+ "%-10s%-18s%7s%20s%13s%11s",
+ "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK", "ICOUNT");
} else {
ti = sn->date_sec;
localtime_r(&ti, &tm);
@@ -668,13 +670,18 @@ void bdrv_snapshot_dump(fprintf_function func_fprintf,
void *f,
(int)((secs / 60) % 60),
(int)(secs % 60),
(int)((sn->vm_clock_nsec / 1000000) % 1000));
+ if (sn->icount != -1ULL) {
+ snprintf(icount_buf, sizeof(icount_buf),
+ "%"PRId64, sn->icount);
+ }
func_fprintf(f,
- "%-10s%-20s%7s%20s%15s",
+ "%-10s%-18s%7s%20s%13s%11s",
sn->id_str, sn->name,
get_human_readable_size(buf1, sizeof(buf1),
sn->vm_state_size),
date_buf,
- clock_buf);
+ clock_buf,
+ icount_buf);
}
}
@@ -842,6 +849,8 @@ void bdrv_image_info_dump(fprintf_function func_fprintf,
void *f,
.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 d04553e..0af32c3 100644
--- a/block/qcow2-snapshot.c
+++ b/block/qcow2-snapshot.c
@@ -379,6 +379,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));
@@ -698,6 +699,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 3808b1f..b965da6 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -56,6 +56,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"
@@ -1348,6 +1349,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;
@@ -1556,6 +1561,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 f73d109..c9c8975 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 4251125..5c4747d 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -2457,6 +2457,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 55728cb..23b3ba6 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -25,13 +25,16 @@
#
# @vm-clock-nsec: fractional part in nano seconds to be used with vm-clock-sec
#
+# @icount: current instruction count for execution record/replay (since 2.13)
+#
# 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 c694524..2f364f7 100644
--- a/qapi/block.json
+++ b/qapi/block.json
@@ -148,7 +148,8 @@
# "date-sec": 1000012,
# "date-nsec": 10,
# "vm-clock-sec": 100,
-# "vm-clock-nsec": 20
+# "vm-clock-nsec": 20,
+# "icount": 220414
# }
# }
#
- [Qemu-devel] [PATCH v3 00/19] reverse debugging, Pavel Dovgalyuk, 2018/05/23
- [Qemu-devel] [PATCH v3 01/19] block: implement bdrv_snapshot_goto for blkreplay, Pavel Dovgalyuk, 2018/05/23
- [Qemu-devel] [PATCH v3 02/19] replay: disable default snapshot for record/replay, Pavel Dovgalyuk, 2018/05/23
- [Qemu-devel] [PATCH v3 03/19] replay: update docs for record/replay with block devices, Pavel Dovgalyuk, 2018/05/23
- [Qemu-devel] [PATCH v3 04/19] replay: don't drain/flush bdrv queue while RR is working, Pavel Dovgalyuk, 2018/05/23
- [Qemu-devel] [PATCH v3 05/19] replay: finish record/replay before closing the disks, Pavel Dovgalyuk, 2018/05/23
- [Qemu-devel] [PATCH v3 06/19] qcow2: introduce icount field for snapshots, Pavel Dovgalyuk, 2018/05/23
- [Qemu-devel] [PATCH v3 07/19] migration: introduce icount field for snapshots,
Pavel Dovgalyuk <=
- [Qemu-devel] [PATCH v3 08/19] replay: introduce info hmp/qmp command, Pavel Dovgalyuk, 2018/05/23
- [Qemu-devel] [PATCH v3 09/19] replay: introduce breakpoint at the specified step, Pavel Dovgalyuk, 2018/05/23
- [Qemu-devel] [PATCH v3 10/19] replay: implement replay-seek command to proceed to the desired step, Pavel Dovgalyuk, 2018/05/23
- [Qemu-devel] [PATCH v3 11/19] replay: flush events when exiting, Pavel Dovgalyuk, 2018/05/23
- [Qemu-devel] [PATCH v3 13/19] replay: refine replay-time module, Pavel Dovgalyuk, 2018/05/23
- [Qemu-devel] [PATCH v3 12/19] timer: remove replay clock probe in deadline calculation, Pavel Dovgalyuk, 2018/05/23
- [Qemu-devel] [PATCH v3 14/19] translator: fix breakpoint processing, Pavel Dovgalyuk, 2018/05/23
- [Qemu-devel] [PATCH v3 15/19] replay: flush rr queue before loading the vmstate, Pavel Dovgalyuk, 2018/05/23
- [Qemu-devel] [PATCH v3 16/19] gdbstub: add reverse step support in replay mode, Pavel Dovgalyuk, 2018/05/23