|  | .. _replay: | 
|  |  | 
|  | .. | 
|  | Copyright (c) 2010-2022 Institute for System Programming | 
|  | of the Russian Academy of Sciences. | 
|  |  | 
|  | This work is licensed under the terms of the GNU GPL, version 2 or later. | 
|  | See the COPYING file in the top-level directory. | 
|  |  | 
|  | Record/replay | 
|  | ============= | 
|  |  | 
|  | Record/replay functions are used for the deterministic replay of qemu execution. | 
|  | Execution recording writes a non-deterministic events log, which can be later | 
|  | used for replaying the execution anywhere and for unlimited number of times. | 
|  | It also supports checkpointing for faster rewind to the specific replay moment. | 
|  | Execution replaying reads the log and replays all non-deterministic events | 
|  | including external input, hardware clocks, and interrupts. | 
|  |  | 
|  | Deterministic replay has the following features: | 
|  |  | 
|  | * Deterministically replays whole system execution and all contents of | 
|  | the memory, state of the hardware devices, clocks, and screen of the VM. | 
|  | * Writes execution log into the file for later replaying for multiple times | 
|  | on different machines. | 
|  | * Supports i386, x86_64, ARM, AArch64, Risc-V, MIPS, MIPS64, S390X, Alpha, | 
|  | PowerPC, PowerPC64, M68000, Microblaze, OpenRISC, Nios II, SPARC, | 
|  | and Xtensa hardware platforms. | 
|  | * Performs deterministic replay of all operations with keyboard and mouse | 
|  | input devices, serial ports, and network. | 
|  |  | 
|  | Usage of the record/replay: | 
|  |  | 
|  | * First, record the execution with the following command line: | 
|  |  | 
|  | .. parsed-literal:: | 
|  | |qemu_system| \\ | 
|  | -icount shift=auto,rr=record,rrfile=replay.bin \\ | 
|  | -drive file=disk.qcow2,if=none,snapshot,id=img-direct \\ | 
|  | -drive driver=blkreplay,if=none,image=img-direct,id=img-blkreplay \\ | 
|  | -device ide-hd,drive=img-blkreplay \\ | 
|  | -netdev user,id=net1 -device rtl8139,netdev=net1 \\ | 
|  | -object filter-replay,id=replay,netdev=net1 | 
|  |  | 
|  | * After recording, you can replay it by using another command line: | 
|  |  | 
|  | .. parsed-literal:: | 
|  | |qemu_system| \\ | 
|  | -icount shift=auto,rr=replay,rrfile=replay.bin \\ | 
|  | -drive file=disk.qcow2,if=none,snapshot,id=img-direct \\ | 
|  | -drive driver=blkreplay,if=none,image=img-direct,id=img-blkreplay \\ | 
|  | -device ide-hd,drive=img-blkreplay \\ | 
|  | -netdev user,id=net1 -device rtl8139,netdev=net1 \\ | 
|  | -object filter-replay,id=replay,netdev=net1 | 
|  |  | 
|  | The only difference with recording is changing the rr option | 
|  | from record to replay. | 
|  | * Block device images are not actually changed in the recording mode, | 
|  | because all of the changes are written to the temporary overlay file. | 
|  | This behavior is enabled by using blkreplay driver. It should be used | 
|  | for every enabled block device, as described in :ref:`block-label` section. | 
|  | * ``-net none`` option should be specified when network is not used, | 
|  | because QEMU adds network card by default. When network is needed, | 
|  | it should be configured explicitly with replay filter, as described | 
|  | in :ref:`network-label` section. | 
|  | * Interaction with audio devices and serial ports are recorded and replayed | 
|  | automatically when such devices are enabled. | 
|  |  | 
|  | Core idea | 
|  | --------- | 
|  |  | 
|  | Record/replay system is based on saving and replaying non-deterministic | 
|  | events (e.g. keyboard input) and simulating deterministic ones (e.g. reading | 
|  | from HDD or memory of the VM). Saving only non-deterministic events makes | 
|  | log file smaller and simulation faster. | 
|  |  | 
|  | The following non-deterministic data from peripheral devices is saved into | 
|  | the log: mouse and keyboard input, network packets, audio controller input, | 
|  | serial port input, and hardware clocks (they are non-deterministic | 
|  | too, because their values are taken from the host machine). Inputs from | 
|  | simulated hardware, memory of VM, software interrupts, and execution of | 
|  | instructions are not saved into the log, because they are deterministic and | 
|  | can be replayed by simulating the behavior of virtual machine starting from | 
|  | initial state. | 
|  |  | 
|  | Instruction counting | 
|  | -------------------- | 
|  |  | 
|  | QEMU should work in icount mode to use record/replay feature. icount was | 
|  | designed to allow deterministic execution in absence of external inputs | 
|  | of the virtual machine. Record/replay feature is enabled through ``-icount`` | 
|  | command-line option, making possible deterministic execution of the machine, | 
|  | interacting with user or network. | 
|  |  | 
|  | .. _block-label: | 
|  |  | 
|  | Block devices | 
|  | ------------- | 
|  |  | 
|  | Block devices record/replay module intercepts calls of | 
|  | bdrv coroutine functions at the top of block drivers stack. | 
|  | To record and replay block operations the drive must be configured | 
|  | as following: | 
|  |  | 
|  | .. parsed-literal:: | 
|  | -drive file=disk.qcow2,if=none,snapshot,id=img-direct | 
|  | -drive driver=blkreplay,if=none,image=img-direct,id=img-blkreplay | 
|  | -device ide-hd,drive=img-blkreplay | 
|  |  | 
|  | blkreplay driver should be inserted between disk image and virtual driver | 
|  | controller. Therefore all disk requests may be recorded and replayed. | 
|  |  | 
|  | .. _snapshotting-label: | 
|  |  | 
|  | Snapshotting | 
|  | ------------ | 
|  |  | 
|  | New VM snapshots may be created in replay mode. They can be used later | 
|  | to recover the desired VM state. All VM states created in replay mode | 
|  | are associated with the moment of time in the replay scenario. | 
|  | After recovering the VM state replay will start from that position. | 
|  |  | 
|  | Default starting snapshot name may be specified with icount field | 
|  | rrsnapshot as follows: | 
|  |  | 
|  | .. parsed-literal:: | 
|  | -icount shift=auto,rr=record,rrfile=replay.bin,rrsnapshot=snapshot_name | 
|  |  | 
|  | This snapshot is created at start of recording and restored at start | 
|  | of replaying. It also can be loaded while replaying to roll back | 
|  | the execution. | 
|  |  | 
|  | ``snapshot`` flag of the disk image must be removed to save the snapshots | 
|  | in the overlay (or original image) instead of using the temporary overlay. | 
|  |  | 
|  | .. parsed-literal:: | 
|  | -drive file=disk.ovl,if=none,id=img-direct | 
|  | -drive driver=blkreplay,if=none,image=img-direct,id=img-blkreplay | 
|  | -device ide-hd,drive=img-blkreplay | 
|  |  | 
|  | Use QEMU monitor to create additional snapshots. ``savevm <name>`` command | 
|  | created the snapshot and ``loadvm <name>`` restores it. To prevent corruption | 
|  | of the original disk image, use overlay files linked to the original images. | 
|  | Therefore all new snapshots (including the starting one) will be saved in | 
|  | overlays and the original image remains unchanged. | 
|  |  | 
|  | When you need to use snapshots with diskless virtual machine, | 
|  | it must be started with "orphan" qcow2 image. This image will be used | 
|  | for storing VM snapshots. Here is the example of the command line for this: | 
|  |  | 
|  | .. parsed-literal:: | 
|  | |qemu_system| \\ | 
|  | -icount shift=auto,rr=replay,rrfile=record.bin,rrsnapshot=init \\ | 
|  | -net none -drive file=empty.qcow2,if=none,id=rr | 
|  |  | 
|  | ``empty.qcow2`` drive does not connected to any virtual block device and used | 
|  | for VM snapshots only. | 
|  |  | 
|  | .. _network-label: | 
|  |  | 
|  | Network devices | 
|  | --------------- | 
|  |  | 
|  | Record and replay for network interactions is performed with the network filter. | 
|  | Each backend must have its own instance of the replay filter as follows: | 
|  |  | 
|  | .. parsed-literal:: | 
|  | -netdev user,id=net1 -device rtl8139,netdev=net1 | 
|  | -object filter-replay,id=replay,netdev=net1 | 
|  |  | 
|  | Replay network filter is used to record and replay network packets. While | 
|  | recording the virtual machine this filter puts all packets coming from | 
|  | the outer world into the log. In replay mode packets from the log are | 
|  | injected into the network device. All interactions with network backend | 
|  | in replay mode are disabled. | 
|  |  | 
|  | Audio devices | 
|  | ------------- | 
|  |  | 
|  | Audio data is recorded and replay automatically. The command line for recording | 
|  | and replaying must contain identical specifications of audio hardware, e.g.: | 
|  |  | 
|  | .. parsed-literal:: | 
|  | -soundhw ac97 | 
|  |  | 
|  | Serial ports | 
|  | ------------ | 
|  |  | 
|  | Serial ports input is recorded and replay automatically. The command lines | 
|  | for recording and replaying must contain identical number of ports in record | 
|  | and replay modes, but their backends may differ. | 
|  | E.g., ``-serial stdio`` in record mode, and ``-serial null`` in replay mode. | 
|  |  | 
|  | Reverse debugging | 
|  | ----------------- | 
|  |  | 
|  | Reverse debugging allows "executing" the program in reverse direction. | 
|  | GDB remote protocol supports "reverse step" and "reverse continue" | 
|  | commands. The first one steps single instruction backwards in time, | 
|  | and the second one finds the last breakpoint in the past. | 
|  |  | 
|  | Recorded executions may be used to enable reverse debugging. QEMU can't | 
|  | execute the code in backwards direction, but can load a snapshot and | 
|  | replay forward to find the desired position or breakpoint. | 
|  |  | 
|  | The following GDB commands are supported: | 
|  |  | 
|  | - ``reverse-stepi`` (or ``rsi``) - step one instruction backwards | 
|  | - ``reverse-continue`` (or ``rc``) - find last breakpoint in the past | 
|  |  | 
|  | Reverse step loads the nearest snapshot and replays the execution until | 
|  | the required instruction is met. | 
|  |  | 
|  | Reverse continue may include several passes of examining the execution | 
|  | between the snapshots. Each of the passes include the following steps: | 
|  |  | 
|  | #. loading the snapshot | 
|  | #. replaying to examine the breakpoints | 
|  | #. if breakpoint or watchpoint was met | 
|  |  | 
|  | * loading the snapshot again | 
|  | * replaying to the required breakpoint | 
|  |  | 
|  | #. else | 
|  |  | 
|  | * proceeding to the p.1 with the earlier snapshot | 
|  |  | 
|  | Therefore usage of the reverse debugging requires at least one snapshot | 
|  | created. This can be done by omitting ``snapshot`` option | 
|  | for the block drives and adding ``rrsnapshot`` for both record and replay | 
|  | command lines. | 
|  | See the :ref:`snapshotting-label` section to learn more about running record/replay | 
|  | and creating the snapshot in these modes. | 
|  |  | 
|  | When ``rrsnapshot`` is not used, then snapshot named ``start_debugging`` | 
|  | created in temporary overlay. This allows using reverse debugging, but with | 
|  | temporary snapshots (existing within the session). |