qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>
To: qemu-devel@nongnu.org
Cc: peter.maydell@linaro.org, peter.crosthwaite@xilinx.com,
	alex.bennee@linaro.org, mark.burton@greensocs.com,
	real@ispras.ru, batuzovk@ispras.ru,
	maria.klimushenkova@ispras.ru, pavel.dovgaluk@ispras.ru,
	pbonzini@redhat.com, afaerber@suse.de, fred.konrad@greensocs.com
Subject: [Qemu-devel] [RFC PATCH v5 30/31] replay: command line options
Date: Wed, 26 Nov 2014 13:41:35 +0300	[thread overview]
Message-ID: <20141126104135.7772.82944.stgit@PASHA-ISP> (raw)
In-Reply-To: <20141126103841.7772.11864.stgit@PASHA-ISP>

This patch introduces command line options for enabling recording or replaying
virtual machine behavior. "-record" option starts recording of the execution
and saves it into the log, specified with "fname" parameter. "-replay" option
is intended for replaying previously saved log.

Signed-off-by: Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru>
---
 cpus.c          |    3 +-
 qemu-options.hx |   27 +++++++++++++++++++
 vl.c            |   79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 106 insertions(+), 3 deletions(-)

diff --git a/cpus.c b/cpus.c
index 8780eee..c8fca6c 100644
--- a/cpus.c
+++ b/cpus.c
@@ -929,9 +929,10 @@ static void qemu_wait_io_event_common(CPUState *cpu)
 static void qemu_tcg_wait_io_event(void)
 {
     CPUState *cpu;
+    GMainContext *context = g_main_context_default();
 
     while (all_cpu_threads_idle()) {
-       /* Start accounting real time to the virtual clock if the CPUs
+        /* Start accounting real time to the virtual clock if the CPUs
           are idle.  */
         qemu_clock_warp(QEMU_CLOCK_VIRTUAL);
         qemu_cond_wait(tcg_halt_cond, &qemu_global_mutex);
diff --git a/qemu-options.hx b/qemu-options.hx
index 22cf3b9..44ad8fc 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -3380,6 +3380,33 @@ Dump json-encoded vmstate information for current machine type to file
 in @var{file}
 ETEXI
 
+DEF("record", HAS_ARG, QEMU_OPTION_record,
+    "-record fname=<filename>[,suffix=<suffix>,snapshot=<on/off>]\n"
+    "                writes replay file for latter replaying\n",
+    QEMU_ARCH_ALL)
+STEXI
+@item -record fname=@var{file}[,suffix=@var{suffix},snapshot=@var{snapshot}]
+Writes compact execution trace into @var{file}.
+Changes for disk images are written
+into separate files with @var{suffix} added. If no @var{suffix} is
+specified, "replay_qcow" is used as suffix.
+If @var{snapshot} parameter is set as off, then original disk image will be
+modified. Default value is on.
+ETEXI
+
+DEF("replay", HAS_ARG, QEMU_OPTION_replay,
+    "-replay fname=<filename>[,suffix=<suffix>,snapshot=<on/off>]\n"
+    "                plays saved replay file\n", QEMU_ARCH_ALL)
+STEXI
+@item -replay fname=@var{filename}[,suffix=@var{suffix},snapshot=@var{snapshot}]
+Plays compact execution trace from @var{filename}.
+Changes for disk images and VM states are read
+from separate files with @var{suffix} added. If no @var{suffix} is
+specified, "replay_qcow" is used as suffix.
+If @var{snapshot} parameter is set as off, then original disk image will be
+modified. Default value is on.
+ETEXI
+
 HXCOMM This is the last statement. Insert new options before this line!
 STEXI
 @end table
diff --git a/vl.c b/vl.c
index 877a77c..fb5003e 100644
--- a/vl.c
+++ b/vl.c
@@ -548,6 +548,42 @@ static QemuOptsList qemu_icount_opts = {
     },
 };
 
+static QemuOptsList qemu_record_opts = {
+    .name = "record",
+    .head = QTAILQ_HEAD_INITIALIZER(qemu_record_opts.head),
+    .desc = {
+        {
+            .name = "fname",
+            .type = QEMU_OPT_STRING,
+        },{
+            .name = "suffix",
+            .type = QEMU_OPT_STRING,
+        },{
+            .name = "snapshot",
+            .type = QEMU_OPT_BOOL,
+        },
+        { /* end of list */ }
+    },
+};
+
+static QemuOptsList qemu_replay_opts = {
+    .name = "replay",
+    .head = QTAILQ_HEAD_INITIALIZER(qemu_replay_opts.head),
+    .desc = {
+        {
+            .name = "fname",
+            .type = QEMU_OPT_STRING,
+        },{
+            .name = "suffix",
+            .type = QEMU_OPT_STRING,
+        },{
+            .name = "snapshot",
+            .type = QEMU_OPT_BOOL,
+        },
+        { /* end of list */ }
+    },
+};
+
 /**
  * Get machine options
  *
@@ -2711,7 +2747,9 @@ out:
 int main(int argc, char **argv, char **envp)
 {
     int i;
-    int snapshot, linux_boot;
+    int snapshot, linux_boot, replay_snapshot;
+    int not_compatible_replay_param = 0;
+    const char *icount_option = NULL;
     const char *initrd_filename;
     const char *kernel_filename, *kernel_cmdline;
     const char *boot_order;
@@ -2784,6 +2822,8 @@ int main(int argc, char **argv, char **envp)
     qemu_add_opts(&qemu_name_opts);
     qemu_add_opts(&qemu_numa_opts);
     qemu_add_opts(&qemu_icount_opts);
+    qemu_add_opts(&qemu_replay_opts);
+    qemu_add_opts(&qemu_record_opts);
 
     runstate_init();
 
@@ -2797,6 +2837,7 @@ int main(int argc, char **argv, char **envp)
     cpu_model = NULL;
     ram_size = default_ram_size;
     snapshot = 0;
+    replay_snapshot = 1;
     cyls = heads = secs = 0;
     translation = BIOS_ATA_TRANSLATION_AUTO;
 
@@ -2914,6 +2955,7 @@ int main(int argc, char **argv, char **envp)
                 break;
             case QEMU_OPTION_pflash:
                 drive_add(IF_PFLASH, -1, optarg, PFLASH_OPTS);
+                not_compatible_replay_param++;
                 break;
             case QEMU_OPTION_snapshot:
                 snapshot = 1;
@@ -3070,6 +3112,7 @@ int main(int argc, char **argv, char **envp)
 #endif
             case QEMU_OPTION_bt:
                 add_device_config(DEV_BT, optarg);
+                not_compatible_replay_param++;
                 break;
             case QEMU_OPTION_audio_help:
                 AUD_help ();
@@ -3284,6 +3327,7 @@ int main(int argc, char **argv, char **envp)
                 if (!opts) {
                     exit(1);
                 }
+                not_compatible_replay_param++;
                 break;
             case QEMU_OPTION_fsdev:
                 olist = qemu_find_opts("fsdev");
@@ -3412,6 +3456,7 @@ int main(int argc, char **argv, char **envp)
                 if (strncmp(optarg, "mon:", 4) == 0) {
                     default_monitor = 0;
                 }
+                not_compatible_replay_param++;
                 break;
             case QEMU_OPTION_debugcon:
                 add_device_config(DEV_DEBUGCON, optarg);
@@ -3532,6 +3577,7 @@ int main(int argc, char **argv, char **envp)
                 if (!qemu_opts_parse(qemu_find_opts("smp-opts"), optarg, 1)) {
                     exit(1);
                 }
+                not_compatible_replay_param++;
                 break;
 	    case QEMU_OPTION_vnc:
 #ifdef CONFIG_VNC
@@ -3770,6 +3816,24 @@ int main(int argc, char **argv, char **envp)
                     exit(1);
                 }
                 break;
+            case QEMU_OPTION_record:
+                opts = qemu_opts_parse(qemu_find_opts("record"), optarg, 0);
+                if (!opts) {
+                    fprintf(stderr, "Invalid record options: %s\n", optarg);
+                    exit(1);
+                }
+                replay_configure(opts, REPLAY_MODE_RECORD);
+                replay_snapshot = qemu_opt_get_bool(opts, "snapshot", 1);
+                break;
+            case QEMU_OPTION_replay:
+                opts = qemu_opts_parse(qemu_find_opts("replay"), optarg, 0);
+                if (!opts) {
+                    fprintf(stderr, "Invalid replay options: %s\n", optarg);
+                    exit(1);
+                }
+                replay_configure(opts, REPLAY_MODE_PLAY);
+                replay_snapshot = qemu_opt_get_bool(opts, "snapshot", 1);
+                break;
             default:
                 os_parse_cmd_args(popt->index, optarg);
             }
@@ -3784,6 +3848,12 @@ int main(int argc, char **argv, char **envp)
         exit(1);
     }
 
+    if (not_compatible_replay_param && (replay_mode != REPLAY_MODE_NONE)) {
+        fprintf(stderr, "options -smp, -pflash, -chardev, -bt, -parallel "
+                        "are not compatible with record/replay\n");
+        exit(1);
+    }
+
     if (qemu_opts_foreach(qemu_find_opts("sandbox"), parse_sandbox, NULL, 0)) {
         exit(1);
     }
@@ -4125,6 +4195,11 @@ int main(int argc, char **argv, char **envp)
         qemu_opts_del(icount_opts);
     }
 
+    if (replay_mode != REPLAY_MODE_NONE && !use_icount) {
+        fprintf(stderr, "Please enable icount to use record/replay\n");
+        exit(1);
+    }
+
     /* clean up network at qemu process termination */
     atexit(&net_cleanup);
 
@@ -4161,7 +4236,7 @@ int main(int argc, char **argv, char **envp)
     }
 
     /* open the virtual block devices */
-    if (snapshot)
+    if (snapshot || (replay_mode != REPLAY_MODE_NONE && replay_snapshot))
         qemu_opts_foreach(qemu_find_opts("drive"), drive_enable_snapshot, NULL, 0);
     if (qemu_opts_foreach(qemu_find_opts("drive"), drive_init_func,
                           &machine_class->block_default_type, 1) != 0) {

  parent reply	other threads:[~2014-11-26 10:41 UTC|newest]

Thread overview: 60+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-11-26 10:38 [Qemu-devel] [RFC PATCH v5 00/31] Deterministic replay and reverse execution Pavel Dovgalyuk
2014-11-26 10:38 ` [Qemu-devel] [RFC PATCH v5 01/31] cpu-exec: fix cpu_exec_nocache Pavel Dovgalyuk
2014-11-26 10:38 ` [Qemu-devel] [RFC PATCH v5 02/31] acpi: accurate overflow check Pavel Dovgalyuk
2014-11-26 13:15   ` Paolo Bonzini
2014-11-26 10:39 ` [Qemu-devel] [RFC PATCH v5 03/31] replay: global variables and function stubs Pavel Dovgalyuk
2014-11-26 15:32   ` Eric Blake
2014-11-26 10:39 ` [Qemu-devel] [RFC PATCH v5 04/31] sysemu: system functions for replay Pavel Dovgalyuk
2014-11-26 10:39 ` [Qemu-devel] [RFC PATCH v5 05/31] replay: internal functions for replay log Pavel Dovgalyuk
2014-11-26 10:39 ` [Qemu-devel] [RFC PATCH v5 06/31] cpu-exec: reset exception_index correctly Pavel Dovgalyuk
2014-11-26 10:39 ` [Qemu-devel] [RFC PATCH v5 07/31] icount: implement icount requesting Pavel Dovgalyuk
2014-12-03 10:17   ` Paolo Bonzini
2014-12-04 11:02     ` Pavel Dovgaluk
2014-12-04 15:50       ` Paolo Bonzini
2014-12-05  5:34         ` Pavel Dovgaluk
2014-12-05 10:36           ` Paolo Bonzini
2014-12-05 10:55             ` Pavel Dovgaluk
2014-12-05 11:43               ` Paolo Bonzini
2014-12-05 12:59                 ` Pavel Dovgaluk
     [not found]                 ` <12880.8243353435$1417784373@news.gmane.org>
2014-12-05 15:13                   ` Paolo Bonzini
2014-11-26 10:39 ` [Qemu-devel] [RFC PATCH v5 08/31] icount: improve enable/disable ticks Pavel Dovgalyuk
2014-11-26 10:39 ` [Qemu-devel] [RFC PATCH v5 09/31] replay: introduce icount event Pavel Dovgalyuk
2014-11-26 10:39 ` [Qemu-devel] [RFC PATCH v5 10/31] i386: do not cross the pages boundaries in replay mode Pavel Dovgalyuk
2014-11-26 10:39 ` [Qemu-devel] [RFC PATCH v5 11/31] From 7abf2f72777958d395cfd01d97fe707cc06152b5 Mon Sep 17 00:00:00 2001 Pavel Dovgalyuk
2014-11-26 10:39 ` [Qemu-devel] [RFC PATCH v5 12/31] From 185a3a47d08857a66332ae862b372a153ce92bb9 " Pavel Dovgalyuk
2014-11-26 10:39 ` [Qemu-devel] [RFC PATCH v5 13/31] From a0cb9e80ba0de409b5ad556109a1c71ce4d8ce19 " Pavel Dovgalyuk
2014-11-26 10:40 ` [Qemu-devel] [RFC PATCH v5 14/31] From 04bbd21134dd2c6b7309a7f5f2b780aae2757003 " Pavel Dovgalyuk
2014-11-26 10:40 ` [Qemu-devel] [RFC PATCH v5 15/31] cpu-exec: allow temporary disabling icount Pavel Dovgalyuk
2014-11-26 10:40 ` [Qemu-devel] [RFC PATCH v5 16/31] cpu-exec: invalidate nocache translation if they are interrupted Pavel Dovgalyuk
2014-11-26 10:40 ` [Qemu-devel] [RFC PATCH v5 17/31] replay: interrupts and exceptions Pavel Dovgalyuk
2014-11-26 10:40 ` [Qemu-devel] [RFC PATCH v5 18/31] replay: asynchronous events infrastructure Pavel Dovgalyuk
2014-11-26 10:40 ` [Qemu-devel] [RFC PATCH v5 19/31] cpu: replay instructions sequence Pavel Dovgalyuk
2014-11-26 10:40 ` [Qemu-devel] [RFC PATCH v5 20/31] replay: recording and replaying clock ticks Pavel Dovgalyuk
2014-11-26 10:52   ` Paolo Bonzini
2014-11-26 12:22     ` Pavel Dovgaluk
2014-11-26 12:51       ` Paolo Bonzini
2014-11-26 10:40 ` [Qemu-devel] [RFC PATCH v5 21/31] replay: recording and replaying different timers Pavel Dovgalyuk
2014-11-26 10:40 ` [Qemu-devel] [RFC PATCH v5 22/31] timer: introduce new QEMU_CLOCK_VIRTUAL_RT clock Pavel Dovgalyuk
2014-11-26 11:04   ` Paolo Bonzini
2014-11-26 12:27     ` Pavel Dovgaluk
2014-11-27  9:11     ` Pavel Dovgaluk
2014-11-27 16:53       ` Paolo Bonzini
2014-11-28  7:52         ` Pavel Dovgaluk
2014-11-28 11:28     ` Pavel Dovgaluk
2014-11-28 12:40       ` Paolo Bonzini
2014-11-26 10:40 ` [Qemu-devel] [RFC PATCH v5 23/31] cpus: make icount warp deterministic in replay mode Pavel Dovgalyuk
2014-11-26 11:26   ` Paolo Bonzini
2014-11-26 10:41 ` [Qemu-devel] [RFC PATCH v5 24/31] replay: shutdown event Pavel Dovgalyuk
2014-11-26 10:41 ` [Qemu-devel] [RFC PATCH v5 25/31] replay: checkpoints Pavel Dovgalyuk
2014-11-26 10:41 ` [Qemu-devel] [RFC PATCH v5 26/31] replay: bottom halves Pavel Dovgalyuk
2014-11-26 10:41 ` [Qemu-devel] [RFC PATCH v5 27/31] replay: replay aio requests Pavel Dovgalyuk
2014-11-26 10:41 ` [Qemu-devel] [RFC PATCH v5 28/31] replay: thread pool Pavel Dovgalyuk
2014-11-26 10:41 ` [Qemu-devel] [RFC PATCH v5 29/31] replay: initialization and deinitialization Pavel Dovgalyuk
2014-11-26 10:41 ` Pavel Dovgalyuk [this message]
2014-11-26 10:41 ` [Qemu-devel] [RFC PATCH v5 31/31] replay: recording of the user input Pavel Dovgalyuk
2014-11-26 10:47 ` [Qemu-devel] [RFC PATCH v5 00/31] Deterministic replay and reverse execution Pavel Dovgaluk
2014-11-26 13:26 ` Paolo Bonzini
     [not found] ` <5475b20f.841f8c0a.8e72.ffffa4f6SMTPIN_ADDED_BROKEN@mx.google.com>
2014-11-27  9:53   ` Artyom Tarasenko
2014-11-27 17:45     ` Paolo Bonzini
2014-11-28  9:39       ` Artyom Tarasenko
2014-11-28  7:51     ` Pavel Dovgaluk

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20141126104135.7772.82944.stgit@PASHA-ISP \
    --to=pavel.dovgaluk@ispras.ru \
    --cc=afaerber@suse.de \
    --cc=alex.bennee@linaro.org \
    --cc=batuzovk@ispras.ru \
    --cc=fred.konrad@greensocs.com \
    --cc=maria.klimushenkova@ispras.ru \
    --cc=mark.burton@greensocs.com \
    --cc=pbonzini@redhat.com \
    --cc=peter.crosthwaite@xilinx.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=real@ispras.ru \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).