From patchwork Wed Sep 12 08:18:28 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 10597047 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4574514DB for ; Wed, 12 Sep 2018 08:28:26 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 31771293D2 for ; Wed, 12 Sep 2018 08:28:26 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 24A8B29444; Wed, 12 Sep 2018 08:28:26 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 7F616293D2 for ; Wed, 12 Sep 2018 08:28:25 +0000 (UTC) Received: from localhost ([::1]:35085 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g00Vc-0000CU-PB for patchwork-qemu-devel@patchwork.kernel.org; Wed, 12 Sep 2018 04:28:24 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47200) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g00M5-0000Zf-Q8 for qemu-devel@nongnu.org; Wed, 12 Sep 2018 04:18:34 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1g00M4-0008Ep-QJ for qemu-devel@nongnu.org; Wed, 12 Sep 2018 04:18:33 -0400 Received: from mail.ispras.ru ([83.149.199.45]:55772) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g00M4-0008Ek-DM for qemu-devel@nongnu.org; Wed, 12 Sep 2018 04:18:32 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 852C454008B; Wed, 12 Sep 2018 11:18:29 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Wed, 12 Sep 2018 11:18:28 +0300 Message-ID: <20180912081828.3228.17908.stgit@pasha-VirtualBox> In-Reply-To: <20180912081747.3228.21861.stgit@pasha-VirtualBox> References: <20180912081747.3228.21861.stgit@pasha-VirtualBox> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 83.149.199.45 Subject: [Qemu-devel] [PATCH v6 07/25] migration: introduce icount field for snapshots X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, war2jordan@live.com, pavel.dovgaluk@ispras.ru, pbonzini@redhat.com, quintela@redhat.com, ciro.santilli@gmail.com, jasowang@redhat.com, crosthwaite.peter@gmail.com, zuban32s@gmail.com, armbru@redhat.com, maria.klimushenkova@ispras.ru, mst@redhat.com, kraxel@redhat.com, boost.lists@gmail.com, thomas.dullien@googlemail.com, dovgaluk@ispras.ru, mreitz@redhat.com, alex.bennee@linaro.org, dgilbert@redhat.com, rth@twiddle.net Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP 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 --- 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 c66f949..9f2ccfa 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; @@ -663,14 +664,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); @@ -683,13 +685,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); } } @@ -857,6 +864,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 d682946..96b57f4 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 72f5347..54b4b9d 100644 --- a/blockdev.c +++ b/blockdev.c @@ -57,6 +57,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" @@ -1239,6 +1240,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; @@ -1447,6 +1452,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 13e51f0..0c21d67 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 4c7a37a..456af87 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -26,13 +26,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 3.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 11f01f2..a6396a9 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 # } # } #