From patchwork Mon Aug 14 16:31:32 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 1821060 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20221208 header.b=Yza0XjjW; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4RPg1h0th1z1yf2 for ; Tue, 15 Aug 2023 02:33:12 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qVaTz-0000Uh-5T; Mon, 14 Aug 2023 12:31:55 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qVaTx-0000UV-Hj for qemu-devel@nongnu.org; Mon, 14 Aug 2023 12:31:53 -0400 Received: from mail-pl1-x632.google.com ([2607:f8b0:4864:20::632]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qVaTv-0004qI-I8 for qemu-devel@nongnu.org; Mon, 14 Aug 2023 12:31:53 -0400 Received: by mail-pl1-x632.google.com with SMTP id d9443c01a7336-1bdc19b782aso17134025ad.0 for ; Mon, 14 Aug 2023 09:31:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1692030710; x=1692635510; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=vp6gU892XZK0ouQnofmt9i+CmckUy2isN46xGuzvKXk=; b=Yza0XjjWsH2MApMdyOANoSYFkvvqMpglfGIkb9+WXmxiBENfvuDA4O5gwR9oOMxrlD QVQLzPJaR2glOvsrfg2iqUijNIALlRump58wh3BO68fL4V0B36XtWW2KNjHhWlcMnKZ9 4AA5GF8tN82t5oOjq7CFm4XMqlN7zaSaAC/wS8j0xS/Ceo/C7cOnhSrmOUF9XF1ogNnZ vsdO1o+13MchT77NCgjhQTUEoOJYmGlIUc5WWop3cgIhvJgHQYNAEQWRSNj7zoIjOx7+ ATxCM12Pg8Gl87zcCsw0/tfAK7B5wrNQWYEq3c4q6vh0QGN4+sZ44FOnGA6xf6t2lPvo LdPw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692030710; x=1692635510; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=vp6gU892XZK0ouQnofmt9i+CmckUy2isN46xGuzvKXk=; b=kky5P9miP1AGJX0T7l0KRnVPegnafD9BSjN912S/p6iY4k56VX7G3N3j5kgzKzV6yg dQFWni6kjidSSU3bnweseSU5Ps7Q0X2TPW1lg7j1rTAaFBCMj0gB5ncT+V5uMm1CVU0X Fx+PnjQbNd7wm/VOOdrAu6dpezqvWXWxAY/Tmj3Bl9exnt6J5X8qAuEqFLXh42uofalw eFU31/eHNn9NUNJwKCNVusZ8Jt7N0lS/8qAV9XmwoKv+LXMHtGS7Eu/QfQ5k+a0fsDjy GwIBw6cGpalyVmzgjJtZnuN/QbYJwftlRdqNhdyF282Q73KBFEwqN7h1FPVLRHoRNgbQ baUQ== X-Gm-Message-State: AOJu0Yz25UpKocjw8Vi5CL7qKKNUr9KQ6GMccXxRqVr+FF0dQ65zZVkV ZfqRIrqPn07oOn+krqaiaPc= X-Google-Smtp-Source: AGHT+IE51zvn7/jg4pjLaGi99ZaebyzC1eH4zizPHfi3ncdvv16NRSsshbf5Dwxco/4/Tdg//Wpg5A== X-Received: by 2002:a17:902:e742:b0:1bc:7312:78db with SMTP id p2-20020a170902e74200b001bc731278dbmr10717324plf.57.1692030710148; Mon, 14 Aug 2023 09:31:50 -0700 (PDT) Received: from wheely.local0.net ([61.68.161.249]) by smtp.gmail.com with ESMTPSA id c6-20020a170902c1c600b001b8a3a0c928sm9613263plc.181.2023.08.14.09.31.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Aug 2023 09:31:49 -0700 (PDT) From: Nicholas Piggin To: Pavel Dovgalyuk Cc: Nicholas Piggin , Paolo Bonzini , John Snow , Cleber Rosa , =?utf-8?q?Phi?= =?utf-8?q?lippe_Mathieu-Daud=C3=A9?= , Wainer dos Santos Moschetta , Beraldo Leal , qemu-devel@nongnu.org Subject: [PATCH 1/4] scripts/replay_dump.sh: Update to current rr record format Date: Tue, 15 Aug 2023 02:31:32 +1000 Message-Id: <20230814163135.187882-2-npiggin@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230814163135.187882-1-npiggin@gmail.com> References: <20230814163135.187882-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::632; envelope-from=npiggin@gmail.com; helo=mail-pl1-x632.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org This thing seems to have fallen by the wayside. This gets it working with the current format, although does not quite implement all events. Signed-off-by: Nicholas Piggin --- My python skills are not good. Any help on this or patch 2 is appreciated. Thanks, Nick scripts/replay-dump.py | 107 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 101 insertions(+), 6 deletions(-) diff --git a/scripts/replay-dump.py b/scripts/replay-dump.py index 3ba97a6d30..937ae19ff1 100755 --- a/scripts/replay-dump.py +++ b/scripts/replay-dump.py @@ -20,6 +20,7 @@ import argparse import struct +import os from collections import namedtuple # This mirrors some of the global replay state which some of the @@ -62,6 +63,10 @@ def read_byte(fin): "Read a single byte" return struct.unpack('>B', fin.read(1))[0] +def read_bytes(fin, nr): + "Read a nr bytes" + return fin.read(nr) + def read_event(fin): "Read a single byte event, but save some state" if replay_state.already_read: @@ -122,12 +127,18 @@ def swallow_async_qword(eid, name, dumpfile): print(" %s(%d) @ %d" % (name, eid, step_id)) return True +def swallow_bytes(eid, name, dumpfile, nr): + "Swallow nr bytes of data without looking at it" + dumpfile.seek(nr, os.SEEK_CUR) + return True + async_decode_table = [ Decoder(0, "REPLAY_ASYNC_EVENT_BH", swallow_async_qword), - Decoder(1, "REPLAY_ASYNC_INPUT", decode_unimp), - Decoder(2, "REPLAY_ASYNC_INPUT_SYNC", decode_unimp), - Decoder(3, "REPLAY_ASYNC_CHAR_READ", decode_unimp), - Decoder(4, "REPLAY_ASYNC_EVENT_BLOCK", decode_unimp), - Decoder(5, "REPLAY_ASYNC_EVENT_NET", decode_unimp), + Decoder(1, "REPLAY_ASYNC_BH_ONESHOT", decode_unimp), + Decoder(2, "REPLAY_ASYNC_INPUT", decode_unimp), + Decoder(3, "REPLAY_ASYNC_INPUT_SYNC", decode_unimp), + Decoder(4, "REPLAY_ASYNC_CHAR_READ", decode_unimp), + Decoder(5, "REPLAY_ASYNC_EVENT_BLOCK", decode_unimp), + Decoder(6, "REPLAY_ASYNC_EVENT_NET", decode_unimp), ] # See replay_read_events/replay_read_event def decode_async(eid, name, dumpfile): @@ -156,6 +167,13 @@ def decode_audio_out(eid, name, dumpfile): print_event(eid, name, "%d" % (audio_data)) return True +def decode_random(eid, name, dumpfile): + ret = read_dword(dumpfile) + size = read_dword(dumpfile) + swallow_bytes(eid, name, dumpfile, size) + print_event(eid, name, "%d %d" % (ret, size)) + return True + def decode_checkpoint(eid, name, dumpfile): """Decode a checkpoint. @@ -184,6 +202,38 @@ def decode_interrupt(eid, name, dumpfile): print_event(eid, name) return True +def decode_exception(eid, name, dumpfile): + print_event(eid, name) + return True + +def decode_shutdown(eid, name, dumpfile): + print_event(eid, name) + return True + +def decode_end(eid, name, dumpfile): + print_event(eid, name) + return False + +def decode_char_write(eid, name, dumpfile): + res = read_dword(dumpfile) + offset = read_dword(dumpfile) + print_event(eid, name) + return True + +def decode_async_char_read(eid, name, dumpfile): + char_id = read_byte(dumpfile) + size = read_dword(dumpfile) + print_event(eid, name, "device:%x chars:%s" % (char_id, read_bytes(dumpfile, size))) + return True + +def decode_async_net(eid, name, dumpfile): + net_id = read_byte(dumpfile) + flags = read_dword(dumpfile) + size = read_dword(dumpfile) + swallow_bytes(eid, name, dumpfile, size) + print_event(eid, name, "net:%x flags:%x bytes:%d" % (net_id, flags, size)) + return True + def decode_clock(eid, name, dumpfile): clock_data = read_qword(dumpfile) print_event(eid, name, "0x%x" % (clock_data)) @@ -268,6 +318,48 @@ def decode_clock(eid, name, dumpfile): Decoder(28, "EVENT_CP_RESET", decode_checkpoint), ] +v12_event_table = [Decoder(0, "EVENT_INSTRUCTION", decode_instruction), + Decoder(1, "EVENT_INTERRUPT", decode_interrupt), + Decoder(2, "EVENT_EXCEPTION", decode_exception), + Decoder(3, "EVENT_ASYNC_BH", swallow_async_qword), + Decoder(4, "EVENT_ASYNC_BH_ONESHOT", swallow_async_qword), + Decoder(5, "EVENT_ASYNC_INPUT", decode_unimp), + Decoder(6, "EVENT_ASYNC_INPUT_SYNC", decode_unimp), + Decoder(7, "EVENT_ASYNC_CHAR_READ", decode_async_char_read), + Decoder(8, "EVENT_ASYNC_BLOCK", swallow_async_qword), + Decoder(9, "EVENT_ASYNC_NET", decode_async_net), + Decoder(10, "EVENT_SHUTDOWN", decode_unimp), + Decoder(11, "EVENT_SHUTDOWN_HOST_ERR", decode_shutdown), + Decoder(12, "EVENT_SHUTDOWN_HOST_QMP_QUIT", decode_shutdown), + Decoder(13, "EVENT_SHUTDOWN_HOST_QMP_RESET", decode_shutdown), + Decoder(14, "EVENT_SHUTDOWN_HOST_SIGNAL", decode_shutdown), + Decoder(15, "EVENT_SHUTDOWN_HOST_UI", decode_shutdown), + Decoder(16, "EVENT_SHUTDOWN_GUEST_SHUTDOWN", decode_shutdown), + Decoder(17, "EVENT_SHUTDOWN_GUEST_RESET", decode_shutdown), + Decoder(18, "EVENT_SHUTDOWN_GUEST_PANIC", decode_shutdown), + Decoder(19, "EVENT_SHUTDOWN_SUBSYS_RESET", decode_shutdown), + Decoder(20, "EVENT_SHUTDOWN_SNAPSHOT_LOAD", decode_shutdown), + Decoder(21, "EVENT_SHUTDOWN___MAX", decode_shutdown), + Decoder(22, "EVENT_CHAR_WRITE", decode_char_write), + Decoder(23, "EVENT_CHAR_READ_ALL", decode_unimp), + Decoder(24, "EVENT_CHAR_READ_ALL_ERROR", decode_unimp), + Decoder(25, "EVENT_AUDIO_OUT", decode_audio_out), + Decoder(26, "EVENT_AUDIO_IN", decode_unimp), + Decoder(27, "EVENT_RANDOM", decode_random), + Decoder(28, "EVENT_CLOCK_HOST", decode_clock), + Decoder(29, "EVENT_CLOCK_VIRTUAL_RT", decode_clock), + Decoder(30, "EVENT_CP_CLOCK_WARP_START", decode_checkpoint), + Decoder(31, "EVENT_CP_CLOCK_WARP_ACCOUNT", decode_checkpoint), + Decoder(32, "EVENT_CP_RESET_REQUESTED", decode_checkpoint), + Decoder(33, "EVENT_CP_SUSPEND_REQUESTED", decode_checkpoint), + Decoder(34, "EVENT_CP_CLOCK_VIRTUAL", decode_checkpoint), + Decoder(35, "EVENT_CP_CLOCK_HOST", decode_checkpoint), + Decoder(36, "EVENT_CP_CLOCK_VIRTUAL_RT", decode_checkpoint), + Decoder(37, "EVENT_CP_INIT", decode_checkpoint_init), + Decoder(38, "EVENT_CP_RESET", decode_checkpoint), + Decoder(39, "EVENT_END", decode_end), +] + def parse_arguments(): "Grab arguments for script" parser = argparse.ArgumentParser() @@ -285,7 +377,10 @@ def decode_file(filename): print("HEADER: version 0x%x" % (version)) - if version == 0xe02007: + if version == 0xe0200c: + event_decode_table = v12_event_table + replay_state.checkpoint_start = 12 + elif version == 0xe02007: event_decode_table = v7_event_table replay_state.checkpoint_start = 12 elif version == 0xe02006: From patchwork Mon Aug 14 16:31:33 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 1821058 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20221208 header.b=B83SmmWd; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4RPg123ppGz1yfZ for ; Tue, 15 Aug 2023 02:32:37 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qVaU4-0000VZ-AH; Mon, 14 Aug 2023 12:32:00 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qVaU1-0000VA-P2 for qemu-devel@nongnu.org; Mon, 14 Aug 2023 12:31:57 -0400 Received: from mail-pl1-x629.google.com ([2607:f8b0:4864:20::629]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qVaU0-0004uq-44 for qemu-devel@nongnu.org; Mon, 14 Aug 2023 12:31:57 -0400 Received: by mail-pl1-x629.google.com with SMTP id d9443c01a7336-1bbc87ded50so27115505ad.1 for ; Mon, 14 Aug 2023 09:31:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1692030714; x=1692635514; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=RNd0WOPv39XbbgsewCHXLS8Ws+tfcBl+X9eCoHKVg1Q=; b=B83SmmWdUxcsZGNBCYBW6sWXpALGsTSf4A+/3k7w9U5sr2WWJ+0NUPRACL5XryU/K6 qvqDBQ/vgp1tmgC/AQ8NIAANBrsMgqpKrfCx+lzyu5OE9jEyIlwy/MR53KXdr4DGwhJa kFddAdsuoRTzfrSikt0DaT8+KZC2RY6+Y0Z4V7rOWoQbO39ORXQa+lqj9iPr5fnAjPex FTTs9SI2V78PiUn/duR8zuYCd78DkMArh6yAFbgFrQlxZMJbwxDJJ60zNRrwub2j3Q2a DNDkDnFXEd+cn82NbKpqW5lvtMI2xNBY8uC+ZQP4ZrEHgwTcAFRytAHt35b/nY9wuItT s/wA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692030714; x=1692635514; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=RNd0WOPv39XbbgsewCHXLS8Ws+tfcBl+X9eCoHKVg1Q=; b=MCyuo6LduxCUNjtMN43pm246WfVgq649wHkg2V50O1GkP5ZTTEWizShMqJyIETb9Wv +sYIYFqTYZDbcSyK65T8k9w0xmIA/AkN6rd4oiWDCqwG5h/rNECpvC11+uHl3XjHwegy 7BxurHwyETcaVdC7id9we8c+wwT89dobStcq3yvPANBgxxGKfgQr8N+4VJG5H/FPQrPQ yEW/AMG0xR348Sft2NsNlokToeowtquFC9+NAEzpd15W1mJ8wqT/RzxRtbSC0pxMAoWR LT6mDeMA157uzQ6EQ7kIJEDG1+K+zX8jjkLvJI/CaZAf2qoLEH3f7Nfu7KvEzKIpRRIq DfVg== X-Gm-Message-State: AOJu0YxA6n+jeGIFWubzGl4Ce6Pf9MfFlOIB5DrbCeJEGPUWaHbyGnPm wfwRHLX7F6a6HjGS6VIxAFI= X-Google-Smtp-Source: AGHT+IF5zFeIeJKwuhDy5IClUo+QpkU89YpXbtFIBDeLmLZB4ErVSjjXw5YyCCN8+LLPtcMMUpUwuQ== X-Received: by 2002:a17:903:1ce:b0:1bc:382b:6897 with SMTP id e14-20020a17090301ce00b001bc382b6897mr10553450plh.13.1692030714296; Mon, 14 Aug 2023 09:31:54 -0700 (PDT) Received: from wheely.local0.net ([61.68.161.249]) by smtp.gmail.com with ESMTPSA id c6-20020a170902c1c600b001b8a3a0c928sm9613263plc.181.2023.08.14.09.31.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Aug 2023 09:31:54 -0700 (PDT) From: Nicholas Piggin To: Pavel Dovgalyuk Cc: Nicholas Piggin , Paolo Bonzini , John Snow , Cleber Rosa , =?utf-8?q?Phi?= =?utf-8?q?lippe_Mathieu-Daud=C3=A9?= , Wainer dos Santos Moschetta , Beraldo Leal , qemu-devel@nongnu.org Subject: [PATCH 2/4] tests/avocado: replay_linux.py add replay-dump.py test Date: Tue, 15 Aug 2023 02:31:33 +1000 Message-Id: <20230814163135.187882-3-npiggin@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230814163135.187882-1-npiggin@gmail.com> References: <20230814163135.187882-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::629; envelope-from=npiggin@gmail.com; helo=mail-pl1-x629.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org This runs replay-dump.py after recording a trace, and fails the test if the script fails. replay-dump.py is modified to exit with non-zero if an error is encountered while parsing. Signed-off-by: Nicholas Piggin --- It's possible this could introduce failures to existing test if an unimplemented event gets recorded. I would make a new test for this but it takes quite a while to record such a long trace that includes some block and net events to excercise the script. Thanks, Nick scripts/replay-dump.py | 6 ++++-- tests/avocado/replay_linux.py | 16 +++++++++++++++- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/scripts/replay-dump.py b/scripts/replay-dump.py index 937ae19ff1..8f4715632a 100755 --- a/scripts/replay-dump.py +++ b/scripts/replay-dump.py @@ -21,6 +21,7 @@ import argparse import struct import os +import sys from collections import namedtuple # This mirrors some of the global replay state which some of the @@ -97,7 +98,7 @@ def call_decode(table, index, dumpfile): print("Could not decode index: %d" % (index)) print("Entry is: %s" % (decoder)) print("Decode Table is:\n%s" % (table)) - return False + sys.exit(1) else: return decoder.fn(decoder.eid, decoder.name, dumpfile) @@ -118,7 +119,7 @@ def print_event(eid, name, string=None, event_count=None): def decode_unimp(eid, name, _unused_dumpfile): "Unimplimented decoder, will trigger exit" print("%s not handled - will now stop" % (name)) - return False + sys.exit(1) # Checkpoint decoder def swallow_async_qword(eid, name, dumpfile): @@ -401,3 +402,4 @@ def decode_file(filename): if __name__ == "__main__": args = parse_arguments() decode_file(args.file) + sys.exit(0) diff --git a/tests/avocado/replay_linux.py b/tests/avocado/replay_linux.py index a76dd507fc..12937ce0ec 100644 --- a/tests/avocado/replay_linux.py +++ b/tests/avocado/replay_linux.py @@ -11,6 +11,7 @@ import os import logging import time +import subprocess from avocado import skipUnless from avocado_qemu import BUILD_DIR @@ -21,6 +22,11 @@ from avocado.utils.path import find_command from avocado_qemu import LinuxTest +from pathlib import Path + +self_dir = Path(__file__).parent +src_dir = self_dir.parent.parent + class ReplayLinux(LinuxTest): """ Boots a Linux system, checking for a successful initialization @@ -94,7 +100,7 @@ def launch_and_wait(self, record, args, shift): else: vm.event_wait('SHUTDOWN', self.timeout) vm.shutdown(True) - logger.info('successfully fihished the replay') + logger.info('successfully finished the replay') elapsed = time.time() - start_time logger.info('elapsed time %.2f sec' % elapsed) return elapsed @@ -105,6 +111,14 @@ def run_rr(self, args=None, shift=7): logger = logging.getLogger('replay') logger.info('replay overhead {:.2%}'.format(t2 / t1 - 1)) + try: + replay_path = os.path.join(self.workdir, 'replay.bin') + subprocess.check_call(["./scripts/replay-dump.py", + "-f", replay_path], + cwd=src_dir, stdout=subprocess.DEVNULL) + except subprocess.CalledProcessError: + self.fail('replay-dump.py failed') + @skipUnless(os.getenv('AVOCADO_TIMEOUT_EXPECTED'), 'Test might timeout') class ReplayLinuxX8664(ReplayLinux): """ From patchwork Mon Aug 14 16:31:34 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 1821057 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20221208 header.b=PawWzh8/; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4RPg114ZFlz1yf2 for ; Tue, 15 Aug 2023 02:32:37 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qVaU7-0000WR-Lz; Mon, 14 Aug 2023 12:32:03 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qVaU6-0000WC-1I for qemu-devel@nongnu.org; Mon, 14 Aug 2023 12:32:02 -0400 Received: from mail-pl1-x62a.google.com ([2607:f8b0:4864:20::62a]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qVaU4-0004xq-Gx for qemu-devel@nongnu.org; Mon, 14 Aug 2023 12:32:01 -0400 Received: by mail-pl1-x62a.google.com with SMTP id d9443c01a7336-1bbf8cb61aeso28355855ad.2 for ; Mon, 14 Aug 2023 09:31:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1692030718; x=1692635518; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=sgieqkv4AvDj0uYBJOPb/yUDnPBp/9usJYWOJeI9mbM=; b=PawWzh8/T9vP1mnpqVJT2WsoxYQJMFzb8ha+8iOoRawr8k4lUELJMx6Gt0G84OhzrG z38yHY+hmlNLpjSYFfQWpjvC/ftY9hyz3VwE+1Yf9U5RizARgKpbUKcaUjzJxxPgsQZ6 gFbRzUXf/j9E5WMJW2PIIzvrLRynT9VAZxynQd7W3pMVEbmniPyA5J40n6hjnna0S193 z859ZEQVHW35glipuCBowzVlOn0o9S7kjUzrz8Hj3aEfQ0sD/OuveuS7p/l/lWl37RIW NHSVz9wQWItfJIjHQKPI2nJ3lydy+Rray+aF9Ne3FtSHBfYXkz+VRSf4BI3dslZHriCT HV2g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692030718; x=1692635518; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=sgieqkv4AvDj0uYBJOPb/yUDnPBp/9usJYWOJeI9mbM=; b=ZNoIo7KCA+xmrlXBtaGkulZ4Wz67KqxWTtwpW7J28wF4IZVy2UJJwViZE8XXociiiy sjfZct9ar7njm+iokbXTHf6Y12QHIEONlofkgVWboEKHFKYTIYYjofoPaC1KX0VJ7tLp XVeCFNySfC9bk85MrSTCD5FXZIOZyyiwPkBn4LwmBkj42b7uStNNYk8dJar0lMncvLR5 cutoBLauODX5VdP68ClPRoAU4MOGID0usf0mH5KbtXnNvSgFvb2MHBlCu37TgOKTl8xB KHIeotrRetsfkcZTQ87QMsbqVHVEIR1WlwVFLfQO/sQke5XO5K6/tZ7vIsRBiBUcRguY kuGA== X-Gm-Message-State: AOJu0YyhMFVhvf/1CpvrfrYh0C8RHxRzpbXCXaeibc9SFVW1bSuBCElB SFAL0KxcNARhA+RxxaI1pFU= X-Google-Smtp-Source: AGHT+IFKuI2AK6nDDzdfu+hhIYmneMnCeXgmNoV3QtX3Zx517pcoCqGtvImwRlsk0KFkUJVzfLAMDw== X-Received: by 2002:a17:903:1cc:b0:1b8:a2af:fe23 with SMTP id e12-20020a17090301cc00b001b8a2affe23mr6873016plh.2.1692030718438; Mon, 14 Aug 2023 09:31:58 -0700 (PDT) Received: from wheely.local0.net ([61.68.161.249]) by smtp.gmail.com with ESMTPSA id c6-20020a170902c1c600b001b8a3a0c928sm9613263plc.181.2023.08.14.09.31.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Aug 2023 09:31:58 -0700 (PDT) From: Nicholas Piggin To: Pavel Dovgalyuk Cc: Nicholas Piggin , Paolo Bonzini , John Snow , Cleber Rosa , =?utf-8?q?Phi?= =?utf-8?q?lippe_Mathieu-Daud=C3=A9?= , Wainer dos Santos Moschetta , Beraldo Leal , qemu-devel@nongnu.org Subject: [PATCH 3/4] replay: allow runstate shutdown->running when replaying trace Date: Tue, 15 Aug 2023 02:31:34 +1000 Message-Id: <20230814163135.187882-4-npiggin@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230814163135.187882-1-npiggin@gmail.com> References: <20230814163135.187882-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::62a; envelope-from=npiggin@gmail.com; helo=mail-pl1-x62a.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org When replaying a trace, it is possible to go from shutdown to running with a reverse-debugging step. This can be useful if the problem being debugged triggers a reset or shutdown. Signed-off-by: Nicholas Piggin Acked-by: Pavel Dovgalyuk --- include/sysemu/runstate.h | 1 + replay/replay.c | 2 ++ softmmu/runstate.c | 19 +++++++++++++++++++ 3 files changed, 22 insertions(+) diff --git a/include/sysemu/runstate.h b/include/sysemu/runstate.h index 7beb29c2e2..85a1167ccb 100644 --- a/include/sysemu/runstate.h +++ b/include/sysemu/runstate.h @@ -9,6 +9,7 @@ void runstate_set(RunState new_state); RunState runstate_get(void); bool runstate_is_running(void); bool runstate_needs_reset(void); +void runstate_replay_enable(void); typedef void VMChangeStateHandler(void *opaque, bool running, RunState state); diff --git a/replay/replay.c b/replay/replay.c index 0f7d766efe..e64f71209a 100644 --- a/replay/replay.c +++ b/replay/replay.c @@ -272,6 +272,8 @@ static void replay_enable(const char *fname, int mode) /* go to the beginning */ fseek(replay_file, HEADER_SIZE, SEEK_SET); replay_fetch_data_kind(); + + runstate_replay_enable(); } replay_init_events(); diff --git a/softmmu/runstate.c b/softmmu/runstate.c index f3bd862818..9fd3e57485 100644 --- a/softmmu/runstate.c +++ b/softmmu/runstate.c @@ -174,6 +174,12 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE__MAX, RUN_STATE__MAX }, }; +static const RunStateTransition replay_runstate_transitions_def[] = { + { RUN_STATE_SHUTDOWN, RUN_STATE_RUNNING}, + + { RUN_STATE__MAX, RUN_STATE__MAX }, +}; + static bool runstate_valid_transitions[RUN_STATE__MAX][RUN_STATE__MAX]; bool runstate_check(RunState state) @@ -181,6 +187,19 @@ bool runstate_check(RunState state) return current_run_state == state; } +void runstate_replay_enable(void) +{ + const RunStateTransition *p; + + assert(replay_mode == REPLAY_MODE_PLAY); + + for (p = &replay_runstate_transitions_def[0]; p->from != RUN_STATE__MAX; + p++) { + runstate_valid_transitions[p->from][p->to] = true; + } + +} + static void runstate_init(void) { const RunStateTransition *p; From patchwork Mon Aug 14 16:31:35 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 1821059 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20221208 header.b=Wy0bLsAe; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4RPg1S6G2sz1yf2 for ; Tue, 15 Aug 2023 02:33:00 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qVaUE-0000X3-J3; Mon, 14 Aug 2023 12:32:11 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qVaUA-0000Wo-Mh for qemu-devel@nongnu.org; Mon, 14 Aug 2023 12:32:06 -0400 Received: from mail-pl1-x62c.google.com ([2607:f8b0:4864:20::62c]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qVaU8-00051J-LY for qemu-devel@nongnu.org; Mon, 14 Aug 2023 12:32:06 -0400 Received: by mail-pl1-x62c.google.com with SMTP id d9443c01a7336-1bc7e65ea44so30439135ad.1 for ; Mon, 14 Aug 2023 09:32:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1692030723; x=1692635523; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=3cfGugDGU5ubW9njTN7eY8oAlg1UghZNc5pQEAohzDA=; b=Wy0bLsAeR7eYKALpOtaVoF1q9QcrGnjTEcXg85QQt+BSEXqcRs5m9b4NakzVS/oZXL jz1+9Wd7QVm00WMpZL6uzsD39EwFes+JFLlf3yaQD1DHZuCc0YAJVK7aGCA2vwvABNWt XWhYCN9bORtcA5fmWf38wb6W3ROgEUSPTYOrjb+gGd8yIlp6N2Ou9GLHepQ3AUiyQrjN GPW9h1I2Lg/6GsMZnm9g0MHezeOZgVTGfQx2DiRCKADKZbo87tQCmlIiDvK9Y96PzVRe C3j8PDLnkgMnC0S6/9qEoTWsq+ncr5mwHaw+I59WCBzYpN3bvlMDmIo84YSyaADJIWXf UEpA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692030723; x=1692635523; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=3cfGugDGU5ubW9njTN7eY8oAlg1UghZNc5pQEAohzDA=; b=ZdGPdueSaWh4EmMxEk3Guyjl/Pq/yUexP2JLSr2mzdpvfMbPCPNzZUUeyv+UOlccdH IgJ1jQJ8RLjFzXeo1wYrw5pqHYTbnhMKieCfUshHC6q7hppcpQupCZfRkc9nQFf0vQdx BvlSnkmhnEwNg0HO7MD+Kqc8yuFOeCkvmDjnnczwMIs/t12G1JcZ3ROiOLAx08ZzUz64 7yfd9TCfRfGrUWGfeae6EATQXrNLMh2urxcS/WYko33Q17KfEWRK/RR56PKU1vOSTber DyEiYfztyGTzOEezrpS1+g+KNdg+z0T7JrlE1fu4tUDyBnQahOYbLol6bE82NJC4MAAk SjBg== X-Gm-Message-State: AOJu0YwTJUTfpLxjn/ZExUVJKtT71a7z4z2aQpyjr/A+FGRizUZUlh0k pN3ucza8vRuoetTVjlHt7aWQ67O9NOA= X-Google-Smtp-Source: AGHT+IF2zrjeTAtRN2V1i1rCdYAsGwFiDNoimSas7qPMIg9PClxgue6WJljUGcI4/DoYJYN2G1b9OQ== X-Received: by 2002:a17:902:c409:b0:1ae:6947:e63b with SMTP id k9-20020a170902c40900b001ae6947e63bmr16574012plk.16.1692030722880; Mon, 14 Aug 2023 09:32:02 -0700 (PDT) Received: from wheely.local0.net ([61.68.161.249]) by smtp.gmail.com with ESMTPSA id c6-20020a170902c1c600b001b8a3a0c928sm9613263plc.181.2023.08.14.09.31.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Aug 2023 09:32:02 -0700 (PDT) From: Nicholas Piggin To: Pavel Dovgalyuk Cc: Nicholas Piggin , Paolo Bonzini , John Snow , Cleber Rosa , =?utf-8?q?Phi?= =?utf-8?q?lippe_Mathieu-Daud=C3=A9?= , Wainer dos Santos Moschetta , Beraldo Leal , qemu-devel@nongnu.org Subject: [PATCH 4/4] replay: simple auto-snapshot mode for record Date: Tue, 15 Aug 2023 02:31:35 +1000 Message-Id: <20230814163135.187882-5-npiggin@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230814163135.187882-1-npiggin@gmail.com> References: <20230814163135.187882-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::62c; envelope-from=npiggin@gmail.com; helo=mail-pl1-x62c.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org record makes an initial snapshot when the machine is created, to enable reverse-debugging. Often the issue being debugged appears near the end of the trace, so it is important for performance to keep snapshots close to the end. This implements a periodic snapshot mode that keeps a rolling set of recent snapshots. Arguably this should be done by the debugger or a program that talks to QMP, but for setting up simple scenarios and tests, it is convenient to have this feature. Signed-off-by: Nicholas Piggin --- docs/system/replay.rst | 5 ++++ include/sysemu/replay.h | 11 ++++++++ qemu-options.hx | 9 +++++-- replay/replay-snapshot.c | 57 ++++++++++++++++++++++++++++++++++++++++ replay/replay.c | 25 ++++++++++++++++++ softmmu/vl.c | 9 +++++++ 6 files changed, 114 insertions(+), 2 deletions(-) diff --git a/docs/system/replay.rst b/docs/system/replay.rst index 3105327423..bef9ea4171 100644 --- a/docs/system/replay.rst +++ b/docs/system/replay.rst @@ -156,6 +156,11 @@ for storing VM snapshots. Here is the example of the command line for this: ``empty.qcow2`` drive does not connected to any virtual block device and used for VM snapshots only. +``rrsnapmode`` can be used to select just an initial snapshot or periodic +snapshots, with ``rrsnapcount`` specifying the number of periodic snapshots +to maintain, and ``rrsnaptime`` the amount of run time in seconds between +periodic snapshots. + .. _network-label: Network devices diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h index 08aae5869f..a83e54afc6 100644 --- a/include/sysemu/replay.h +++ b/include/sysemu/replay.h @@ -45,6 +45,17 @@ typedef enum ReplayCheckpoint ReplayCheckpoint; typedef struct ReplayNetState ReplayNetState; +enum ReplaySnapshotMode { + REPLAY_SNAPSHOT_MODE_INITIAL, + REPLAY_SNAPSHOT_MODE_PERIODIC, +}; +typedef enum ReplaySnapshotMode ReplaySnapshotMode; + +extern ReplaySnapshotMode replay_snapshot_mode; + +extern uint64_t replay_snapshot_periodic_delay; +extern int replay_snapshot_periodic_nr_keep; + /* Name of the initial VM snapshot */ extern char *replay_snapshot; diff --git a/qemu-options.hx b/qemu-options.hx index 29b98c3d4c..0dce93eeab 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -4530,13 +4530,13 @@ SRST ERST DEF("icount", HAS_ARG, QEMU_OPTION_icount, \ - "-icount [shift=N|auto][,align=on|off][,sleep=on|off][,rr=record|replay,rrfile=[,rrsnapshot=]]\n" \ + "-icount [shift=N|auto][,align=on|off][,sleep=on|off][,rr=record|replay,rrfile=[,rrsnapshot=][,rrsnapmode=initial|periodic][,rrsnaptime=secs][,rrsnapcount=N]\n" \ " enable virtual instruction counter with 2^N clock ticks per\n" \ " instruction, enable aligning the host and virtual clocks\n" \ " or disable real time cpu sleeping, and optionally enable\n" \ " record-and-replay mode\n", QEMU_ARCH_ALL) SRST -``-icount [shift=N|auto][,align=on|off][,sleep=on|off][,rr=record|replay,rrfile=filename[,rrsnapshot=snapshot]]`` +``-icount [shift=N|auto][,align=on|off][,sleep=on|off][,rr=record|replay,rrfile=filename[,rrsnapshot=snapshot][,rrsnapmode=initial|periodic][,rrsnaptime=secs][,rrsnapcount=N]]`` Enable virtual instruction counter. The virtual cpu will execute one instruction every 2^N ns of virtual time. If ``auto`` is specified then the virtual cpu speed will be automatically adjusted to keep @@ -4578,6 +4578,11 @@ SRST name. In record mode, a new VM snapshot with the given name is created at the start of execution recording. In replay mode this option specifies the snapshot name used to load the initial VM state. + ``rrsnapmode=periodic`` will additionally cause a periodic snapshot to + be created after ``rrsnaptime=secs`` seconds of real runtime. The last + ``rrsnapcount=N`` periodic snapshots (not including the initial) will + be kept (0 for infinite). Periodic snapshots are useful to speed + reverse debugging operations near the end of the recorded trace. ERST DEF("watchdog-action", HAS_ARG, QEMU_OPTION_watchdog_action, \ diff --git a/replay/replay-snapshot.c b/replay/replay-snapshot.c index 10a7cf7992..38eac61c43 100644 --- a/replay/replay-snapshot.c +++ b/replay/replay-snapshot.c @@ -69,6 +69,53 @@ void replay_vmstate_register(void) vmstate_register(NULL, 0, &vmstate_replay, &replay_state); } +static QEMUTimer *replay_snapshot_timer; +static int replay_snapshot_count; + +static void replay_snapshot_timer_cb(void *opaque) +{ + Error *err = NULL; + char *name; + + if (!replay_can_snapshot()) { + /* Try again soon */ + timer_mod(replay_snapshot_timer, + qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + + replay_snapshot_periodic_delay / 10); + return; + } + + name = g_strdup_printf("%s-%d", replay_snapshot, replay_snapshot_count); + if (!save_snapshot(name, + true, NULL, false, NULL, &err)) { + error_report_err(err); + error_report("Could not create periodic snapshot " + "for icount record, disabling"); + g_free(name); + return; + } + g_free(name); + replay_snapshot_count++; + + if (replay_snapshot_periodic_nr_keep >= 1 && + replay_snapshot_count > replay_snapshot_periodic_nr_keep) { + int del_nr; + + del_nr = replay_snapshot_count - replay_snapshot_periodic_nr_keep - 1; + name = g_strdup_printf("%s-%d", replay_snapshot, del_nr); + if (!delete_snapshot(name, false, NULL, &err)) { + error_report_err(err); + error_report("Could not delete periodic snapshot " + "for icount record"); + } + g_free(name); + } + + timer_mod(replay_snapshot_timer, + qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + + replay_snapshot_periodic_delay); +} + void replay_vmstate_init(void) { Error *err = NULL; @@ -81,6 +128,16 @@ void replay_vmstate_init(void) error_report("Could not create snapshot for icount record"); exit(1); } + + if (replay_snapshot_mode == REPLAY_SNAPSHOT_MODE_PERIODIC) { + replay_snapshot_timer = timer_new_ms(QEMU_CLOCK_REALTIME, + replay_snapshot_timer_cb, + NULL); + timer_mod(replay_snapshot_timer, + qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + + replay_snapshot_periodic_delay); + } + } else if (replay_mode == REPLAY_MODE_PLAY) { if (!load_snapshot(replay_snapshot, NULL, false, NULL, &err)) { error_report_err(err); diff --git a/replay/replay.c b/replay/replay.c index e64f71209a..fa5930700d 100644 --- a/replay/replay.c +++ b/replay/replay.c @@ -29,6 +29,10 @@ ReplayMode replay_mode = REPLAY_MODE_NONE; char *replay_snapshot; +ReplaySnapshotMode replay_snapshot_mode; +uint64_t replay_snapshot_periodic_delay; +int replay_snapshot_periodic_nr_keep; + /* Name of replay file */ static char *replay_filename; ReplayState replay_state; @@ -313,6 +317,27 @@ void replay_configure(QemuOpts *opts) } replay_snapshot = g_strdup(qemu_opt_get(opts, "rrsnapshot")); + if (replay_snapshot && mode == REPLAY_MODE_RECORD) { + const char *snapmode; + + snapmode = qemu_opt_get(opts, "rrsnapmode"); + if (!snapmode || !strcmp(snapmode, "initial")) { + replay_snapshot_mode = REPLAY_SNAPSHOT_MODE_INITIAL; + } else if (!strcmp(snapmode, "periodic")) { + replay_snapshot_mode = REPLAY_SNAPSHOT_MODE_PERIODIC; + } else { + error_report("Invalid rrsnapmode option: %s", snapmode); + exit(1); + } + + /* Default 10 host seconds of machine runtime per snapshot. */ + replay_snapshot_periodic_delay = + qemu_opt_get_number(opts, "rrsnaptime", 10) * 1000; + + /* Default 2, to cover at least the last 10 host seconds of runtime. */ + replay_snapshot_periodic_nr_keep = + qemu_opt_get_number(opts, "rrsnapcount", 2); + } replay_vmstate_register(); replay_enable(fname, mode); diff --git a/softmmu/vl.c b/softmmu/vl.c index b0b96f67fa..e032eb45e8 100644 --- a/softmmu/vl.c +++ b/softmmu/vl.c @@ -446,6 +446,15 @@ static QemuOptsList qemu_icount_opts = { }, { .name = "rrsnapshot", .type = QEMU_OPT_STRING, + }, { + .name = "rrsnapmode", + .type = QEMU_OPT_STRING, + }, { + .name = "rrsnaptime", + .type = QEMU_OPT_NUMBER, + }, { + .name = "rrsnapcount", + .type = QEMU_OPT_NUMBER, }, { /* end of list */ } },