[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v7 04/14] migration: introduce icount field for snapshots
From: |
Pavel Dovgalyuk |
Subject: |
[PATCH v7 04/14] migration: introduce icount field for snapshots |
Date: |
Sat, 03 Oct 2020 20:13:08 +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 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.
This patch also updates snapshot test which verifies qemu monitor output.
Signed-off-by: Pavel Dovgalyuk <Pavel.Dovgalyuk@ispras.ru>
Acked-by: Markus Armbruster <armbru@redhat.com>
Acked-by: Kevin Wolf <kwolf@redhat.com>
--
v4 changes:
- squashed format update with test output update
v7 changes:
- introduced the spaces between the fields in snapshot info output
- updated the test to match new field widths
---
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 | 10 +++++++--
stubs/replay.c | 5 +++++
tests/qemu-iotests/261 | 4 ++--
tests/qemu-iotests/267.out | 48 ++++++++++++++++++++++----------------------
9 files changed, 71 insertions(+), 32 deletions(-)
diff --git a/block/qapi.c b/block/qapi.c
index f423ece98c..036da085ee 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -230,6 +230,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;
@@ -694,14 +696,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%11s%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);
@@ -715,11 +718,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%11s%20s%15s",
+ if (sn->icount != -1ULL) {
+ snprintf(icount_buf, sizeof(icount_buf),
+ "%"PRId64, sn->icount);
+ }
+ qemu_printf("%-9s %-17s %7s%20s%13s%11s",
sn->id_str, sn->name,
sizing,
date_buf,
- clock_buf);
+ clock_buf,
+ icount_buf);
}
g_free(sizing);
}
@@ -881,6 +889,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 d68b25e0c5..2e98c7f4b6 100644
--- a/block/qcow2-snapshot.c
+++ b/block/qcow2-snapshot.c
@@ -663,6 +663,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;
sn->extra_data_size = sizeof(QCowSnapshotExtraData);
/* Allocate the L1 table of the snapshot and copy the current one there. */
@@ -1007,6 +1008,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 bebd3ba1c3..a6ae475dac 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -59,6 +59,7 @@
#include "sysemu/arch_init.h"
#include "sysemu/qtest.h"
#include "sysemu/runstate.h"
+#include "sysemu/replay.h"
#include "qemu/cutils.h"
#include "qemu/help_option.h"
#include "qemu/main-loop.h"
@@ -1190,6 +1191,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;
@@ -1350,6 +1355,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_icount();
+ } 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 2bfcd57578..b0fe42993d 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 34e4b71052..0e8dc78684 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -2723,6 +2723,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_icount();
+ } 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 86ed72ef9f..015cc0afa4 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -27,13 +27,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 5.2)
+#
# 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:
@@ -5529,7 +5534,8 @@
# "date-sec": 1000012,
# "date-nsec": 10,
# "vm-clock-sec": 100,
-# "vm-clock-nsec": 20
+# "vm-clock-nsec": 20,
+# "icount": 220414
# }
# }
#
diff --git a/stubs/replay.c b/stubs/replay.c
index 5974ec1f50..eacb366aa8 100644
--- a/stubs/replay.c
+++ b/stubs/replay.c
@@ -88,3 +88,8 @@ int replay_read_random(void *buf, size_t len)
{
return 0;
}
+
+uint64_t replay_get_current_icount(void)
+{
+ return 0;
+}
diff --git a/tests/qemu-iotests/261 b/tests/qemu-iotests/261
index 848ffa760d..847b4c6a37 100755
--- a/tests/qemu-iotests/261
+++ b/tests/qemu-iotests/261
@@ -392,7 +392,7 @@ _check_test_img -r all
echo
echo "$((sn_count - 1)) snapshots should remain:"
-echo " qemu-img info reports $(_img_info | grep -c '^ \{34\}') snapshots"
+echo " qemu-img info reports $(_img_info | grep -c '^ \{32\}') snapshots"
echo " Image header reports $(peek_file_be "$TEST_IMG" 60 4) snapshots"
echo
@@ -519,7 +519,7 @@ _check_test_img -r all
echo
echo '65536 snapshots should remain:'
-echo " qemu-img info reports $(_img_info | grep -c '^ \{34\}') snapshots"
+echo " qemu-img info reports $(_img_info | grep -c '^ \{32\}') snapshots"
echo " Image header reports $(peek_file_be "$TEST_IMG" 60 4) snapshots"
# success, all done
diff --git a/tests/qemu-iotests/267.out b/tests/qemu-iotests/267.out
index 215902b3ad..27471ffae8 100644
--- a/tests/qemu-iotests/267.out
+++ b/tests/qemu-iotests/267.out
@@ -33,8 +33,8 @@ QEMU X.Y.Z monitor - type 'help' for more information
(qemu) savevm snap0
(qemu) info snapshots
List of snapshots present on all disks:
-ID TAG VM SIZE DATE VM CLOCK
--- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000
+ID TAG VM SIZE DATE VM CLOCK ICOUNT
+-- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000
(qemu) loadvm snap0
(qemu) quit
@@ -44,8 +44,8 @@ QEMU X.Y.Z monitor - type 'help' for more information
(qemu) savevm snap0
(qemu) info snapshots
List of snapshots present on all disks:
-ID TAG VM SIZE DATE VM CLOCK
--- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000
+ID TAG VM SIZE DATE VM CLOCK ICOUNT
+-- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000
(qemu) loadvm snap0
(qemu) quit
@@ -69,8 +69,8 @@ QEMU X.Y.Z monitor - type 'help' for more information
(qemu) savevm snap0
(qemu) info snapshots
List of snapshots present on all disks:
-ID TAG VM SIZE DATE VM CLOCK
--- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000
+ID TAG VM SIZE DATE VM CLOCK ICOUNT
+-- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000
(qemu) loadvm snap0
(qemu) quit
@@ -94,8 +94,8 @@ QEMU X.Y.Z monitor - type 'help' for more information
(qemu) savevm snap0
(qemu) info snapshots
List of snapshots present on all disks:
-ID TAG VM SIZE DATE VM CLOCK
--- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000
+ID TAG VM SIZE DATE VM CLOCK ICOUNT
+-- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000
(qemu) loadvm snap0
(qemu) quit
@@ -105,8 +105,8 @@ QEMU X.Y.Z monitor - type 'help' for more information
(qemu) savevm snap0
(qemu) info snapshots
List of snapshots present on all disks:
-ID TAG VM SIZE DATE VM CLOCK
--- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000
+ID TAG VM SIZE DATE VM CLOCK ICOUNT
+-- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000
(qemu) loadvm snap0
(qemu) quit
@@ -119,8 +119,8 @@ QEMU X.Y.Z monitor - type 'help' for more information
(qemu) savevm snap0
(qemu) info snapshots
List of snapshots present on all disks:
-ID TAG VM SIZE DATE VM CLOCK
--- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000
+ID TAG VM SIZE DATE VM CLOCK ICOUNT
+-- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000
(qemu) loadvm snap0
(qemu) quit
@@ -134,8 +134,8 @@ QEMU X.Y.Z monitor - type 'help' for more information
(qemu) savevm snap0
(qemu) info snapshots
List of snapshots present on all disks:
-ID TAG VM SIZE DATE VM CLOCK
--- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000
+ID TAG VM SIZE DATE VM CLOCK ICOUNT
+-- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000
(qemu) loadvm snap0
(qemu) quit
@@ -145,15 +145,15 @@ QEMU X.Y.Z monitor - type 'help' for more information
(qemu) savevm snap0
(qemu) info snapshots
List of snapshots present on all disks:
-ID TAG VM SIZE DATE VM CLOCK
--- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000
+ID TAG VM SIZE DATE VM CLOCK ICOUNT
+-- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000
(qemu) loadvm snap0
(qemu) quit
Internal snapshots on overlay:
Snapshot list:
-ID TAG VM SIZE DATE VM CLOCK
-1 snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000
+ID TAG VM SIZE DATE VM CLOCK ICOUNT
+1 snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000
Internal snapshots on backing file:
=== -blockdev with NBD server on the backing file ===
@@ -166,17 +166,17 @@ QEMU X.Y.Z monitor - type 'help' for more information
(qemu) savevm snap0
(qemu) info snapshots
List of snapshots present on all disks:
-ID TAG VM SIZE DATE VM CLOCK
--- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000
+ID TAG VM SIZE DATE VM CLOCK ICOUNT
+-- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000
(qemu) loadvm snap0
(qemu) quit
Internal snapshots on overlay:
Snapshot list:
-ID TAG VM SIZE DATE VM CLOCK
-1 snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000
+ID TAG VM SIZE DATE VM CLOCK ICOUNT
+1 snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000
Internal snapshots on backing file:
Snapshot list:
-ID TAG VM SIZE DATE VM CLOCK
-1 snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000
+ID TAG VM SIZE DATE VM CLOCK ICOUNT
+1 snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000
*** done
- [PATCH v7 00/14] Reverse debugging, Pavel Dovgalyuk, 2020/10/03
- [PATCH v7 01/14] replay: don't record interrupt poll, Pavel Dovgalyuk, 2020/10/03
- [PATCH v7 02/14] replay: provide an accessor for rr filename, Pavel Dovgalyuk, 2020/10/03
- [PATCH v7 03/14] qcow2: introduce icount field for snapshots, Pavel Dovgalyuk, 2020/10/03
- [PATCH v7 04/14] migration: introduce icount field for snapshots,
Pavel Dovgalyuk <=
- [PATCH v7 05/14] qapi: introduce replay.json for record/replay-related stuff, Pavel Dovgalyuk, 2020/10/03
- [PATCH v7 06/14] replay: introduce info hmp/qmp command, Pavel Dovgalyuk, 2020/10/03
- [PATCH v7 07/14] replay: introduce breakpoint at the specified step, Pavel Dovgalyuk, 2020/10/03
- [PATCH v7 08/14] replay: implement replay-seek command, Pavel Dovgalyuk, 2020/10/03
- [PATCH v7 09/14] replay: flush rr queue before loading the vmstate, Pavel Dovgalyuk, 2020/10/03
- [PATCH v7 10/14] gdbstub: add reverse step support in replay mode, Pavel Dovgalyuk, 2020/10/03
- [PATCH v7 11/14] gdbstub: add reverse continue support in replay mode, Pavel Dovgalyuk, 2020/10/03
- [PATCH v7 12/14] replay: describe reverse debugging in docs/replay.txt, Pavel Dovgalyuk, 2020/10/03
- [PATCH v7 13/14] replay: create temporary snapshot at debugger connection, Pavel Dovgalyuk, 2020/10/03
- [PATCH v7 14/14] tests/acceptance: add reverse debugging test, Pavel Dovgalyuk, 2020/10/03