xref: /openbmc/qemu/docs/interop/bitmaps.rst (revision e029fe22caad9b75c7ab69bd4e84853c11fb71e0)
17746cf8aSKashyap Chamarthy..
290edef80SJohn Snow   Copyright 2019 John Snow <jsnow@redhat.com> and Red Hat, Inc.
37746cf8aSKashyap Chamarthy   All rights reserved.
47746cf8aSKashyap Chamarthy
57746cf8aSKashyap Chamarthy   This file is licensed via The FreeBSD Documentation License, the full
67746cf8aSKashyap Chamarthy   text of which is included at the end of this document.
77746cf8aSKashyap Chamarthy
87746cf8aSKashyap Chamarthy====================================
97746cf8aSKashyap ChamarthyDirty Bitmaps and Incremental Backup
107746cf8aSKashyap Chamarthy====================================
117746cf8aSKashyap Chamarthy
1290edef80SJohn SnowDirty Bitmaps are in-memory objects that track writes to block devices. They
1390edef80SJohn Snowcan be used in conjunction with various block job operations to perform
1490edef80SJohn Snowincremental or differential backup regimens.
157746cf8aSKashyap Chamarthy
1690edef80SJohn SnowThis document explains the conceptual mechanisms, as well as up-to-date,
1790edef80SJohn Snowcomplete and comprehensive documentation on the API to manipulate them.
1890edef80SJohn Snow(Hopefully, the "why", "what", and "how".)
1990edef80SJohn Snow
2090edef80SJohn SnowThe intended audience for this document is developers who are adding QEMU
2190edef80SJohn Snowbackup features to management applications, or power users who run and
2290edef80SJohn Snowadminister QEMU directly via QMP.
237746cf8aSKashyap Chamarthy
247746cf8aSKashyap Chamarthy.. contents::
257746cf8aSKashyap Chamarthy
2690edef80SJohn SnowOverview
2790edef80SJohn Snow--------
2890edef80SJohn Snow
2990edef80SJohn SnowBitmaps are bit vectors where each '1' bit in the vector indicates a modified
3090edef80SJohn Snow("dirty") segment of the corresponding block device. The size of the segment
3190edef80SJohn Snowthat is tracked is the granularity of the bitmap. If the granularity of a
3290edef80SJohn Snowbitmap is 64K, each '1' bit means that a 64K region as a whole may have
3390edef80SJohn Snowchanged in some way, possibly by as little as one byte.
3490edef80SJohn Snow
3590edef80SJohn SnowSmaller granularities mean more accurate tracking of modified disk data, but
3690edef80SJohn Snowrequires more computational overhead and larger bitmap sizes. Larger
3790edef80SJohn Snowgranularities mean smaller bitmap sizes, but less targeted backups.
3890edef80SJohn Snow
3990edef80SJohn SnowThe size of a bitmap (in bytes) can be computed as such:
4090edef80SJohn Snow    ``size`` = ceil(ceil(``image_size`` / ``granularity``) / 8)
4190edef80SJohn Snow
4290edef80SJohn Snowe.g. the size of a 64KiB granularity bitmap on a 2TiB image is:
4390edef80SJohn Snow    ``size`` = ((2147483648K / 64K) / 8)
4490edef80SJohn Snow         = 4194304B = 4MiB.
4590edef80SJohn Snow
4690edef80SJohn SnowQEMU uses these bitmaps when making incremental backups to know which sections
4790edef80SJohn Snowof the file to copy out. They are not enabled by default and must be
4890edef80SJohn Snowexplicitly added in order to begin tracking writes.
4990edef80SJohn Snow
5090edef80SJohn SnowBitmaps can be created at any time and can be attached to any arbitrary block
5190edef80SJohn Snownode in the storage graph, but are most useful conceptually when attached to
5290edef80SJohn Snowthe root node attached to the guest's storage device model.
5390edef80SJohn Snow
5490edef80SJohn SnowThat is to say: It's likely most useful to track the guest's writes to disk,
5590edef80SJohn Snowbut you could theoretically track things like qcow2 metadata changes by
5690edef80SJohn Snowattaching the bitmap elsewhere in the storage graph. This is beyond the scope
5790edef80SJohn Snowof this document.
5890edef80SJohn Snow
5990edef80SJohn SnowQEMU supports persisting these bitmaps to disk via the qcow2 image format.
6090edef80SJohn SnowBitmaps which are stored or loaded in this way are called "persistent",
6190edef80SJohn Snowwhereas bitmaps that are not are called "transient".
6290edef80SJohn Snow
6390edef80SJohn SnowQEMU also supports the migration of both transient bitmaps (tracking any
6490edef80SJohn Snowarbitrary image format) or persistent bitmaps (qcow2) via live migration.
6590edef80SJohn Snow
6690edef80SJohn SnowSupported Image Formats
6790edef80SJohn Snow-----------------------
6890edef80SJohn Snow
6990edef80SJohn SnowQEMU supports all documented features below on the qcow2 image format.
7090edef80SJohn Snow
7190edef80SJohn SnowHowever, qcow2 is only strictly necessary for the persistence feature, which
7290edef80SJohn Snowwrites bitmap data to disk upon close. If persistence is not required for a
7390edef80SJohn Snowspecific use case, all bitmap features excepting persistence are available for
7490edef80SJohn Snowany arbitrary image format.
7590edef80SJohn Snow
7690edef80SJohn SnowFor example, Dirty Bitmaps can be combined with the 'raw' image format, but
7790edef80SJohn Snowany changes to the bitmap will be discarded upon exit.
7890edef80SJohn Snow
7990edef80SJohn Snow.. warning:: Transient bitmaps will not be saved on QEMU exit! Persistent
8090edef80SJohn Snow             bitmaps are available only on qcow2 images.
8190edef80SJohn Snow
827746cf8aSKashyap ChamarthyDirty Bitmap Names
837746cf8aSKashyap Chamarthy------------------
847746cf8aSKashyap Chamarthy
8590edef80SJohn SnowBitmap objects need a method to reference them in the API. All API-created and
8690edef80SJohn Snowmanaged bitmaps have a human-readable name chosen by the user at creation
8790edef80SJohn Snowtime.
887746cf8aSKashyap Chamarthy
8990edef80SJohn Snow- A bitmap's name is unique to the node, but bitmaps attached to different
9090edef80SJohn Snow  nodes can share the same name. Therefore, all bitmaps are addressed via
9190edef80SJohn Snow  their (node, name) pair.
927746cf8aSKashyap Chamarthy
9390edef80SJohn Snow- The name of a user-created bitmap cannot be empty ("").
947746cf8aSKashyap Chamarthy
9590edef80SJohn Snow- Transient bitmaps can have JSON unicode names that are effectively not
9690edef80SJohn Snow  length limited. (QMP protocol may restrict messages to less than 64MiB.)
977746cf8aSKashyap Chamarthy
9890edef80SJohn Snow- Persistent storage formats may impose their own requirements on bitmap names
9990edef80SJohn Snow  and namespaces. Presently, only qcow2 supports persistent bitmaps. See
10090edef80SJohn Snow  docs/interop/qcow2.txt for more details on restrictions. Notably:
1017746cf8aSKashyap Chamarthy
10290edef80SJohn Snow   - qcow2 bitmap names are limited to between 1 and 1023 bytes long.
10390edef80SJohn Snow
10490edef80SJohn Snow   - No two bitmaps saved to the same qcow2 file may share the same name.
10590edef80SJohn Snow
10690edef80SJohn Snow- QEMU occasionally uses bitmaps for internal use which have no name. They are
10790edef80SJohn Snow  hidden from API query calls, cannot be manipulated by the external API, are
10890edef80SJohn Snow  never persistent, nor ever migrated.
10990edef80SJohn Snow
11090edef80SJohn SnowBitmap Status
11190edef80SJohn Snow-------------
11290edef80SJohn Snow
11390edef80SJohn SnowDirty Bitmap objects can be queried with the QMP command `query-block
11490edef80SJohn Snow<qemu-qmp-ref.html#index-query_002dblock>`_, and are visible via the
11590edef80SJohn Snow`BlockDirtyInfo <qemu-qmp-ref.html#index-BlockDirtyInfo>`_ QAPI structure.
11690edef80SJohn Snow
11790edef80SJohn SnowThis struct shows the name, granularity, and dirty byte count for each bitmap.
11890edef80SJohn SnowAdditionally, it shows several boolean status indicators:
11990edef80SJohn Snow
12090edef80SJohn Snow- ``recording``: This bitmap is recording writes.
12190edef80SJohn Snow- ``busy``: This bitmap is in-use by an operation.
12290edef80SJohn Snow- ``persistent``: This bitmap is a persistent type.
12390edef80SJohn Snow- ``inconsistent``: This bitmap is corrupted and cannot be used.
12490edef80SJohn Snow
12590edef80SJohn SnowThe ``+busy`` status prohibits you from deleting, clearing, or otherwise
12690edef80SJohn Snowmodifying a bitmap, and happens when the bitmap is being used for a backup
12790edef80SJohn Snowoperation or is in the process of being loaded from a migration. Many of the
12890edef80SJohn Snowcommands documented below will refuse to work on such bitmaps.
12990edef80SJohn Snow
13090edef80SJohn SnowThe ``+inconsistent`` status similarly prohibits almost all operations,
13190edef80SJohn Snownotably allowing only the ``block-dirty-bitmap-remove`` operation.
13290edef80SJohn Snow
13390edef80SJohn SnowThere is also a deprecated ``status`` field of type `DirtyBitmapStatus
13490edef80SJohn Snow<qemu-qmp-ref.html#index-DirtyBitmapStatus>`_. A bitmap historically had
13590edef80SJohn Snowfive visible states:
13690edef80SJohn Snow
13790edef80SJohn Snow   #. ``Frozen``: This bitmap is currently in-use by an operation and is
13890edef80SJohn Snow      immutable. It can't be deleted, renamed, reset, etc.
13990edef80SJohn Snow
14090edef80SJohn Snow      (This is now ``+busy``.)
14190edef80SJohn Snow
14290edef80SJohn Snow   #. ``Disabled``: This bitmap is not recording new writes.
14390edef80SJohn Snow
14490edef80SJohn Snow      (This is now ``-recording -busy``.)
14590edef80SJohn Snow
14690edef80SJohn Snow   #. ``Active``: This bitmap is recording new writes.
14790edef80SJohn Snow
14890edef80SJohn Snow      (This is now ``+recording -busy``.)
14990edef80SJohn Snow
15090edef80SJohn Snow   #. ``Locked``: This bitmap is in-use by an operation, and is immutable.
15190edef80SJohn Snow      The difference from "Frozen" was primarily implementation details.
15290edef80SJohn Snow
15390edef80SJohn Snow      (This is now ``+busy``.)
15490edef80SJohn Snow
15590edef80SJohn Snow   #. ``Inconsistent``: This persistent bitmap was not saved to disk
15690edef80SJohn Snow      correctly, and can no longer be used. It remains in memory to serve as
15790edef80SJohn Snow      an indicator of failure.
15890edef80SJohn Snow
15990edef80SJohn Snow      (This is now ``+inconsistent``.)
16090edef80SJohn Snow
16190edef80SJohn SnowThese states are directly replaced by the status indicators and should not be
16290edef80SJohn Snowused. The difference between ``Frozen`` and ``Locked`` is an implementation
16390edef80SJohn Snowdetail and should not be relevant to external users.
1647746cf8aSKashyap Chamarthy
1657746cf8aSKashyap ChamarthyBasic QMP Usage
1667746cf8aSKashyap Chamarthy---------------
1677746cf8aSKashyap Chamarthy
16890edef80SJohn SnowThe primary interface to manipulating bitmap objects is via the QMP
1693bc8dc8aSMarkus Armbrusterinterface. If you are not familiar, see the :doc:`qmp-spec` for the
170*7cbdabb5SMarkus Armbrusterprotocol, and :doc:`qemu-qmp-ref` for a full reference of all QMP
171*7cbdabb5SMarkus Armbrustercommands.
17290edef80SJohn Snow
1737746cf8aSKashyap ChamarthySupported Commands
1747746cf8aSKashyap Chamarthy~~~~~~~~~~~~~~~~~~
1757746cf8aSKashyap Chamarthy
17690edef80SJohn SnowThere are six primary bitmap-management API commands:
17790edef80SJohn Snow
1787746cf8aSKashyap Chamarthy- ``block-dirty-bitmap-add``
1797746cf8aSKashyap Chamarthy- ``block-dirty-bitmap-remove``
1807746cf8aSKashyap Chamarthy- ``block-dirty-bitmap-clear``
18190edef80SJohn Snow- ``block-dirty-bitmap-disable``
18290edef80SJohn Snow- ``block-dirty-bitmap-enable``
18390edef80SJohn Snow- ``block-dirty-bitmap-merge``
1847746cf8aSKashyap Chamarthy
18590edef80SJohn SnowAnd one related query command:
1867746cf8aSKashyap Chamarthy
18790edef80SJohn Snow- ``query-block``
18890edef80SJohn Snow
18990edef80SJohn SnowCreation: block-dirty-bitmap-add
19090edef80SJohn Snow~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
19190edef80SJohn Snow
19290edef80SJohn Snow`block-dirty-bitmap-add
19390edef80SJohn Snow<qemu-qmp-ref.html#index-block_002ddirty_002dbitmap_002dadd>`_:
19490edef80SJohn Snow
19590edef80SJohn SnowCreates a new bitmap that tracks writes to the specified node. granularity,
19690edef80SJohn Snowpersistence, and recording state can be adjusted at creation time.
19790edef80SJohn Snow
19890edef80SJohn Snow.. admonition:: Example
19990edef80SJohn Snow
20090edef80SJohn Snow to create a new, actively recording persistent bitmap:
2017746cf8aSKashyap Chamarthy
202a7786bfbSJohn Snow .. code-block:: QMP
2037746cf8aSKashyap Chamarthy
20490edef80SJohn Snow  -> { "execute": "block-dirty-bitmap-add",
2057746cf8aSKashyap Chamarthy       "arguments": {
2067746cf8aSKashyap Chamarthy         "node": "drive0",
2077746cf8aSKashyap Chamarthy         "name": "bitmap0",
20890edef80SJohn Snow         "persistent": true,
2097746cf8aSKashyap Chamarthy       }
2107746cf8aSKashyap Chamarthy     }
2117746cf8aSKashyap Chamarthy
21290edef80SJohn Snow  <- { "return": {} }
2137746cf8aSKashyap Chamarthy
21490edef80SJohn Snow- This bitmap will have a default granularity that matches the cluster size of
21590edef80SJohn Snow  its associated drive, if available, clamped to between [4KiB, 64KiB]. The
21690edef80SJohn Snow  current default for qcow2 is 64KiB.
2177746cf8aSKashyap Chamarthy
21890edef80SJohn Snow.. admonition:: Example
21990edef80SJohn Snow
22090edef80SJohn Snow To create a new, disabled (``-recording``), transient bitmap that tracks
22190edef80SJohn Snow changes in 32KiB segments:
22290edef80SJohn Snow
223a7786bfbSJohn Snow .. code-block:: QMP
22490edef80SJohn Snow
22590edef80SJohn Snow  -> { "execute": "block-dirty-bitmap-add",
22690edef80SJohn Snow       "arguments": {
22790edef80SJohn Snow         "node": "drive0",
22890edef80SJohn Snow         "name": "bitmap1",
22990edef80SJohn Snow         "granularity": 32768,
23090edef80SJohn Snow         "disabled": true
23190edef80SJohn Snow       }
23290edef80SJohn Snow     }
23390edef80SJohn Snow
23490edef80SJohn Snow  <- { "return": {} }
23590edef80SJohn Snow
23690edef80SJohn SnowDeletion: block-dirty-bitmap-remove
23790edef80SJohn Snow~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
23890edef80SJohn Snow
23990edef80SJohn Snow`block-dirty-bitmap-remove
24090edef80SJohn Snow<qemu-qmp-ref.html#index-block_002ddirty_002dbitmap_002dremove>`_:
24190edef80SJohn Snow
24290edef80SJohn SnowDeletes a bitmap. Bitmaps that are ``+busy`` cannot be removed.
24390edef80SJohn Snow
24490edef80SJohn Snow- Deleting a bitmap does not impact any other bitmaps attached to the same
24590edef80SJohn Snow  node, nor does it affect any backups already created from this bitmap or
2467746cf8aSKashyap Chamarthy  node.
2477746cf8aSKashyap Chamarthy
24890edef80SJohn Snow- Because bitmaps are only unique to the node to which they are attached, you
24990edef80SJohn Snow  must specify the node/drive name here, too.
25090edef80SJohn Snow
25190edef80SJohn Snow- Deleting a persistent bitmap will remove it from the qcow2 file.
25290edef80SJohn Snow
25390edef80SJohn Snow.. admonition:: Example
25490edef80SJohn Snow
25590edef80SJohn Snow Remove a bitmap named ``bitmap0`` from node ``drive0``:
2567746cf8aSKashyap Chamarthy
257a7786bfbSJohn Snow .. code-block:: QMP
2587746cf8aSKashyap Chamarthy
25990edef80SJohn Snow  -> { "execute": "block-dirty-bitmap-remove",
2607746cf8aSKashyap Chamarthy       "arguments": {
2617746cf8aSKashyap Chamarthy         "node": "drive0",
2627746cf8aSKashyap Chamarthy         "name": "bitmap0"
2637746cf8aSKashyap Chamarthy       }
2647746cf8aSKashyap Chamarthy     }
2657746cf8aSKashyap Chamarthy
26690edef80SJohn Snow  <- { "return": {} }
2677746cf8aSKashyap Chamarthy
26890edef80SJohn SnowResetting: block-dirty-bitmap-clear
26990edef80SJohn Snow~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2707746cf8aSKashyap Chamarthy
27190edef80SJohn Snow`block-dirty-bitmap-clear
27290edef80SJohn Snow<qemu-qmp-ref.html#index-block_002ddirty_002dbitmap_002dclear>`_:
27390edef80SJohn Snow
27490edef80SJohn SnowClears all dirty bits from a bitmap. ``+busy`` bitmaps cannot be cleared.
27590edef80SJohn Snow
27690edef80SJohn Snow- An incremental backup created from an empty bitmap will copy no data, as if
27790edef80SJohn Snow  nothing has changed.
27890edef80SJohn Snow
27990edef80SJohn Snow.. admonition:: Example
28090edef80SJohn Snow
28190edef80SJohn Snow Clear all dirty bits from bitmap ``bitmap0`` on node ``drive0``:
2827746cf8aSKashyap Chamarthy
283a7786bfbSJohn Snow .. code-block:: QMP
2847746cf8aSKashyap Chamarthy
28590edef80SJohn Snow  -> { "execute": "block-dirty-bitmap-clear",
2867746cf8aSKashyap Chamarthy       "arguments": {
2877746cf8aSKashyap Chamarthy         "node": "drive0",
2887746cf8aSKashyap Chamarthy         "name": "bitmap0"
2897746cf8aSKashyap Chamarthy       }
2907746cf8aSKashyap Chamarthy     }
2917746cf8aSKashyap Chamarthy
29290edef80SJohn Snow  <- { "return": {} }
29390edef80SJohn Snow
29490edef80SJohn SnowEnabling: block-dirty-bitmap-enable
29590edef80SJohn Snow~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
29690edef80SJohn Snow
29790edef80SJohn Snow`block-dirty-bitmap-enable
29890edef80SJohn Snow<qemu-qmp-ref.html#index-block_002ddirty_002dbitmap_002denable>`_:
29990edef80SJohn Snow
30090edef80SJohn Snow"Enables" a bitmap, setting the ``recording`` bit to true, causing writes to
30190edef80SJohn Snowbegin being recorded. ``+busy`` bitmaps cannot be enabled.
30290edef80SJohn Snow
30390edef80SJohn Snow- Bitmaps default to being enabled when created, unless configured otherwise.
30490edef80SJohn Snow
30590edef80SJohn Snow- Persistent enabled bitmaps will remember their ``+recording`` status on
30690edef80SJohn Snow  load.
30790edef80SJohn Snow
30890edef80SJohn Snow.. admonition:: Example
30990edef80SJohn Snow
31090edef80SJohn Snow To set ``+recording`` on bitmap ``bitmap0`` on node ``drive0``:
31190edef80SJohn Snow
312a7786bfbSJohn Snow .. code-block:: QMP
31390edef80SJohn Snow
31490edef80SJohn Snow  -> { "execute": "block-dirty-bitmap-enable",
31590edef80SJohn Snow       "arguments": {
31690edef80SJohn Snow         "node": "drive0",
31790edef80SJohn Snow         "name": "bitmap0"
31890edef80SJohn Snow       }
31990edef80SJohn Snow     }
32090edef80SJohn Snow
32190edef80SJohn Snow  <- { "return": {} }
32290edef80SJohn Snow
32390edef80SJohn SnowEnabling: block-dirty-bitmap-disable
32490edef80SJohn Snow~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
32590edef80SJohn Snow
32690edef80SJohn Snow`block-dirty-bitmap-disable
32790edef80SJohn Snow<qemu-qmp-ref.html#index-block_002ddirty_002dbitmap_002ddisable>`_:
32890edef80SJohn Snow
32990edef80SJohn Snow"Disables" a bitmap, setting the ``recording`` bit to false, causing further
33090edef80SJohn Snowwrites to begin being ignored. ``+busy`` bitmaps cannot be disabled.
33190edef80SJohn Snow
33290edef80SJohn Snow.. warning::
33390edef80SJohn Snow
33490edef80SJohn Snow  This is potentially dangerous: QEMU makes no effort to stop any writes if
33590edef80SJohn Snow  there are disabled bitmaps on a node, and will not mark any disabled bitmaps
33690edef80SJohn Snow  as ``+inconsistent`` if any such writes do happen. Backups made from such
33790edef80SJohn Snow  bitmaps will not be able to be used to reconstruct a coherent image.
33890edef80SJohn Snow
33990edef80SJohn Snow- Disabling a bitmap may be useful for examining which sectors of a disk
34090edef80SJohn Snow  changed during a specific time period, or for explicit management of
34190edef80SJohn Snow  differential backup windows.
34290edef80SJohn Snow
34390edef80SJohn Snow- Persistent disabled bitmaps will remember their ``-recording`` status on
34490edef80SJohn Snow  load.
34590edef80SJohn Snow
34690edef80SJohn Snow.. admonition:: Example
34790edef80SJohn Snow
34890edef80SJohn Snow To set ``-recording`` on bitmap ``bitmap0`` on node ``drive0``:
34990edef80SJohn Snow
350a7786bfbSJohn Snow .. code-block:: QMP
35190edef80SJohn Snow
35290edef80SJohn Snow  -> { "execute": "block-dirty-bitmap-disable",
35390edef80SJohn Snow       "arguments": {
35490edef80SJohn Snow         "node": "drive0",
35590edef80SJohn Snow         "name": "bitmap0"
35690edef80SJohn Snow       }
35790edef80SJohn Snow     }
35890edef80SJohn Snow
35990edef80SJohn Snow  <- { "return": {} }
36090edef80SJohn Snow
36190edef80SJohn SnowMerging, Copying: block-dirty-bitmap-merge
36290edef80SJohn Snow~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
36390edef80SJohn Snow
36490edef80SJohn Snow`block-dirty-bitmap-merge
36590edef80SJohn Snow<qemu-qmp-ref.html#index-block_002ddirty_002dbitmap_002dmerge>`_:
36690edef80SJohn Snow
36790edef80SJohn SnowMerges one or more bitmaps into a target bitmap. For any segment that is dirty
36890edef80SJohn Snowin any one source bitmap, the target bitmap will mark that segment dirty.
36990edef80SJohn Snow
37090edef80SJohn Snow- Merge takes one or more bitmaps as a source and merges them together into a
37190edef80SJohn Snow  single destination, such that any segment marked as dirty in any source
37290edef80SJohn Snow  bitmap(s) will be marked dirty in the destination bitmap.
37390edef80SJohn Snow
37490edef80SJohn Snow- Merge does not create the destination bitmap if it does not exist. A blank
37590edef80SJohn Snow  bitmap can be created beforehand to achieve the same effect.
37690edef80SJohn Snow
37790edef80SJohn Snow- The destination is not cleared prior to merge, so subsequent merge
37890edef80SJohn Snow  operations will continue to cumulatively mark more segments as dirty.
37990edef80SJohn Snow
38090edef80SJohn Snow- If the merge operation should fail, the destination bitmap is guaranteed to
38190edef80SJohn Snow  be unmodified. The operation may fail if the source or destination bitmaps
38290edef80SJohn Snow  are busy, or have different granularities.
38390edef80SJohn Snow
38490edef80SJohn Snow- Bitmaps can only be merged on the same node. There is only one "node"
38590edef80SJohn Snow  argument, so all bitmaps must be attached to that same node.
38690edef80SJohn Snow
38790edef80SJohn Snow- Copy can be achieved by merging from a single source to an empty
38890edef80SJohn Snow  destination.
38990edef80SJohn Snow
39090edef80SJohn Snow.. admonition:: Example
39190edef80SJohn Snow
39290edef80SJohn Snow Merge the data from ``bitmap0`` into the bitmap ``new_bitmap`` on node
39390edef80SJohn Snow ``drive0``. If ``new_bitmap`` was empty prior to this command, this achieves
39490edef80SJohn Snow a copy.
39590edef80SJohn Snow
396a7786bfbSJohn Snow .. code-block:: QMP
39790edef80SJohn Snow
39890edef80SJohn Snow  -> { "execute": "block-dirty-bitmap-merge",
39990edef80SJohn Snow       "arguments": {
40090edef80SJohn Snow         "node": "drive0",
40190edef80SJohn Snow         "target": "new_bitmap",
402575e6226SJohn Snow         "bitmaps": [ "bitmap0" ]
40390edef80SJohn Snow       }
40490edef80SJohn Snow     }
40590edef80SJohn Snow
40690edef80SJohn Snow  <- { "return": {} }
40790edef80SJohn Snow
40890edef80SJohn SnowQuerying: query-block
40990edef80SJohn Snow~~~~~~~~~~~~~~~~~~~~~
41090edef80SJohn Snow
41190edef80SJohn Snow`query-block
41290edef80SJohn Snow<qemu-qmp-ref.html#index-query_002dblock>`_:
41390edef80SJohn Snow
41490edef80SJohn SnowNot strictly a bitmaps command, but will return information about any bitmaps
41590edef80SJohn Snowattached to nodes serving as the root for guest devices.
41690edef80SJohn Snow
41790edef80SJohn Snow- The "inconsistent" bit will not appear when it is false, appearing only when
41890edef80SJohn Snow  the value is true to indicate there is a problem.
41990edef80SJohn Snow
42090edef80SJohn Snow.. admonition:: Example
42190edef80SJohn Snow
42290edef80SJohn Snow Query the block sub-system of QEMU. The following json has trimmed irrelevant
42390edef80SJohn Snow keys from the response to highlight only the bitmap-relevant portions of the
42490edef80SJohn Snow API. This result highlights a bitmap ``bitmap0`` attached to the root node of
42590edef80SJohn Snow device ``drive0``.
42690edef80SJohn Snow
427a7786bfbSJohn Snow .. code-block:: QMP
42890edef80SJohn Snow
42990edef80SJohn Snow  -> {
43090edef80SJohn Snow       "execute": "query-block",
43190edef80SJohn Snow       "arguments": {}
43290edef80SJohn Snow     }
43390edef80SJohn Snow
43490edef80SJohn Snow  <- {
43590edef80SJohn Snow       "return": [ {
43690edef80SJohn Snow         "dirty-bitmaps": [ {
43790edef80SJohn Snow           "status": "active",
43890edef80SJohn Snow           "count": 0,
43990edef80SJohn Snow           "busy": false,
44090edef80SJohn Snow           "name": "bitmap0",
44190edef80SJohn Snow           "persistent": false,
44290edef80SJohn Snow           "recording": true,
44390edef80SJohn Snow           "granularity": 65536
44490edef80SJohn Snow         } ],
44590edef80SJohn Snow         "device": "drive0",
44690edef80SJohn Snow       } ]
44790edef80SJohn Snow     }
44890edef80SJohn Snow
44990edef80SJohn SnowBitmap Persistence
45090edef80SJohn Snow------------------
45190edef80SJohn Snow
45290edef80SJohn SnowAs outlined in `Supported Image Formats`_, QEMU can persist bitmaps to qcow2
45390edef80SJohn Snowfiles. Demonstrated in `Creation: block-dirty-bitmap-add`_, passing
45490edef80SJohn Snow``persistent: true`` to ``block-dirty-bitmap-add`` will persist that bitmap to
45590edef80SJohn Snowdisk.
45690edef80SJohn Snow
45790edef80SJohn SnowPersistent bitmaps will be automatically loaded into memory upon load, and
45890edef80SJohn Snowwill be written back to disk upon close. Their usage should be mostly
45990edef80SJohn Snowtransparent.
46090edef80SJohn Snow
46190edef80SJohn SnowHowever, if QEMU does not get a chance to close the file cleanly, the bitmap
46290edef80SJohn Snowwill be marked as ``+inconsistent`` at next load and considered unsafe to use
46390edef80SJohn Snowfor any operation. At this point, the only valid operation on such bitmaps is
46490edef80SJohn Snow``block-dirty-bitmap-remove``.
46590edef80SJohn Snow
46690edef80SJohn SnowLosing a bitmap in this way does not invalidate any existing backups that have
46790edef80SJohn Snowbeen made from this bitmap, but no further backups will be able to be issued
46890edef80SJohn Snowfor this chain.
46990edef80SJohn Snow
4707746cf8aSKashyap ChamarthyTransactions
4717746cf8aSKashyap Chamarthy------------
4727746cf8aSKashyap Chamarthy
47390edef80SJohn SnowTransactions are a QMP feature that allows you to submit multiple QMP commands
47490edef80SJohn Snowat once, being guaranteed that they will all succeed or fail atomically,
47590edef80SJohn Snowtogether. The interaction of bitmaps and transactions are demonstrated below.
47690edef80SJohn Snow
47790edef80SJohn SnowSee `transaction <qemu-qmp.ref.html#index-transaction>`_ in the QMP reference
47890edef80SJohn Snowfor more details.
47990edef80SJohn Snow
4807746cf8aSKashyap ChamarthyJustification
4817746cf8aSKashyap Chamarthy~~~~~~~~~~~~~
4827746cf8aSKashyap Chamarthy
48390edef80SJohn SnowBitmaps can generally be modified at any time, but certain operations often
48490edef80SJohn Snowonly make sense when paired directly with other commands. When a VM is paused,
48590edef80SJohn Snowit's easy to ensure that no guest writes occur between individual QMP
48690edef80SJohn Snowcommands. When a VM is running, this is difficult to accomplish with
48776ca4b58Szhaolichangindividual QMP commands that may allow guest writes to occur between each
48890edef80SJohn Snowcommand.
4897746cf8aSKashyap Chamarthy
49090edef80SJohn SnowFor example, using only individual QMP commands, we could:
4917746cf8aSKashyap Chamarthy
49290edef80SJohn Snow#. Boot the VM in a paused state.
49390edef80SJohn Snow#. Create a full drive backup of drive0.
49490edef80SJohn Snow#. Create a new bitmap attached to drive0, confident that nothing has been
49590edef80SJohn Snow   written to drive0 in the meantime.
49690edef80SJohn Snow#. Resume execution of the VM.
49790edef80SJohn Snow#. At a later point, issue incremental backups from ``bitmap0``.
4987746cf8aSKashyap Chamarthy
49990edef80SJohn SnowAt this point, the bitmap and drive backup would be correctly in sync, and
50090edef80SJohn Snowincremental backups made from this point forward would be correctly aligned to
50190edef80SJohn Snowthe full drive backup.
5027746cf8aSKashyap Chamarthy
50390edef80SJohn SnowThis is not particularly useful if we decide we want to start incremental
50490edef80SJohn Snowbackups after the VM has been running for a while, for which we would want to
50590edef80SJohn Snowperform actions such as the following:
50690edef80SJohn Snow
50790edef80SJohn Snow#. Boot the VM and begin execution.
50890edef80SJohn Snow#. Using a single transaction, perform the following operations:
5097746cf8aSKashyap Chamarthy
5107746cf8aSKashyap Chamarthy   -  Create ``bitmap0``.
5117746cf8aSKashyap Chamarthy   -  Create a full drive backup of ``drive0``.
5127746cf8aSKashyap Chamarthy
51390edef80SJohn Snow#. At a later point, issue incremental backups from ``bitmap0``.
51490edef80SJohn Snow
51590edef80SJohn Snow.. note:: As a consideration, if ``bitmap0`` is created prior to the full
51690edef80SJohn Snow          drive backup, incremental backups can still be authored from this
51790edef80SJohn Snow          bitmap, but they will copy extra segments reflecting writes that
51890edef80SJohn Snow          occurred prior to the backup operation. Transactions allow us to
51990edef80SJohn Snow          narrow critical points in time to reduce waste, or, in the other
52090edef80SJohn Snow          direction, to ensure that no segments are omitted.
5217746cf8aSKashyap Chamarthy
5227746cf8aSKashyap ChamarthySupported Bitmap Transactions
5237746cf8aSKashyap Chamarthy~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5247746cf8aSKashyap Chamarthy
5257746cf8aSKashyap Chamarthy-  ``block-dirty-bitmap-add``
5267746cf8aSKashyap Chamarthy-  ``block-dirty-bitmap-clear``
52790edef80SJohn Snow-  ``block-dirty-bitmap-enable``
52890edef80SJohn Snow-  ``block-dirty-bitmap-disable``
52990edef80SJohn Snow-  ``block-dirty-bitmap-merge``
5307746cf8aSKashyap Chamarthy
53190edef80SJohn SnowThe usages for these commands are identical to their respective QMP commands,
53290edef80SJohn Snowbut see the sections below for concrete examples.
5337746cf8aSKashyap Chamarthy
53490edef80SJohn SnowIncremental Backups - Push Model
53590edef80SJohn Snow--------------------------------
5367746cf8aSKashyap Chamarthy
53790edef80SJohn SnowIncremental backups are simply partial disk images that can be combined with
53890edef80SJohn Snowother partial disk images on top of a base image to reconstruct a full backup
53990edef80SJohn Snowfrom the point in time at which the incremental backup was issued.
5407746cf8aSKashyap Chamarthy
54190edef80SJohn SnowThe "Push Model" here references the fact that QEMU is "pushing" the modified
54224d6cc1fSVladimir Sementsov-Ogievskiyblocks out to a destination. We will be using the  `blockdev-backup
54324d6cc1fSVladimir Sementsov-Ogievskiy<qemu-qmp-ref.html#index-blockdev_002dbackup>`_ QMP command to create both
54490edef80SJohn Snowfull and incremental backups.
5457746cf8aSKashyap Chamarthy
54624d6cc1fSVladimir Sementsov-OgievskiyThe command is a background job, which has its own QMP API for querying and
54790edef80SJohn Snowmanagement documented in `Background jobs
54890edef80SJohn Snow<qemu-qmp-ref.html#Background-jobs>`_.
5497746cf8aSKashyap Chamarthy
5507746cf8aSKashyap ChamarthyExample: New Incremental Backup Anchor Point
5517746cf8aSKashyap Chamarthy~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5527746cf8aSKashyap Chamarthy
55390edef80SJohn SnowAs outlined in the Transactions - `Justification`_ section, perhaps we want to
55490edef80SJohn Snowcreate a new incremental backup chain attached to a drive.
55590edef80SJohn Snow
55690edef80SJohn SnowThis example creates a new, full backup of "drive0" and accompanies it with a
55790edef80SJohn Snownew, empty bitmap that records writes from this point in time forward.
55890edef80SJohn Snow
55924d6cc1fSVladimir Sementsov-OgievskiyThe target can be created with the help of `blockdev-add
56024d6cc1fSVladimir Sementsov-Ogievskiy<qemu-qmp-ref.html#index-blockdev_002dadd>`_ or `blockdev-create
56124d6cc1fSVladimir Sementsov-Ogievskiy<qemu-qmp-ref.html#index-blockdev_002dcreate>`_ command.
56224d6cc1fSVladimir Sementsov-Ogievskiy
56390edef80SJohn Snow.. note:: Any new writes that happen after this command is issued, even while
56490edef80SJohn Snow          the backup job runs, will be written locally and not to the backup
56590edef80SJohn Snow          destination. These writes will be recorded in the bitmap
56690edef80SJohn Snow          accordingly.
5677746cf8aSKashyap Chamarthy
568a7786bfbSJohn Snow.. code-block:: QMP
5697746cf8aSKashyap Chamarthy
57090edef80SJohn Snow  -> {
57190edef80SJohn Snow       "execute": "transaction",
5727746cf8aSKashyap Chamarthy       "arguments": {
5737746cf8aSKashyap Chamarthy         "actions": [
57490edef80SJohn Snow           {
57590edef80SJohn Snow             "type": "block-dirty-bitmap-add",
57690edef80SJohn Snow             "data": {
57790edef80SJohn Snow               "node": "drive0",
57890edef80SJohn Snow               "name": "bitmap0"
57990edef80SJohn Snow             }
58090edef80SJohn Snow           },
58190edef80SJohn Snow           {
58224d6cc1fSVladimir Sementsov-Ogievskiy             "type": "blockdev-backup",
58390edef80SJohn Snow             "data": {
58490edef80SJohn Snow               "device": "drive0",
58524d6cc1fSVladimir Sementsov-Ogievskiy               "target": "target0",
58624d6cc1fSVladimir Sementsov-Ogievskiy               "sync": "full"
58790edef80SJohn Snow             }
58890edef80SJohn Snow           }
5897746cf8aSKashyap Chamarthy         ]
5907746cf8aSKashyap Chamarthy       }
5917746cf8aSKashyap Chamarthy     }
5927746cf8aSKashyap Chamarthy
59390edef80SJohn Snow  <- { "return": {} }
5947746cf8aSKashyap Chamarthy
59590edef80SJohn Snow  <- {
59690edef80SJohn Snow       "timestamp": {
59790edef80SJohn Snow         "seconds": 1555436945,
59890edef80SJohn Snow         "microseconds": 179620
59990edef80SJohn Snow       },
60090edef80SJohn Snow       "data": {
60190edef80SJohn Snow         "status": "created",
60290edef80SJohn Snow         "id": "drive0"
60390edef80SJohn Snow       },
60490edef80SJohn Snow       "event": "JOB_STATUS_CHANGE"
60590edef80SJohn Snow     }
6067746cf8aSKashyap Chamarthy
60790edef80SJohn Snow  ...
60890edef80SJohn Snow
60990edef80SJohn Snow  <- {
61090edef80SJohn Snow       "timestamp": {...},
61190edef80SJohn Snow       "data": {
61290edef80SJohn Snow         "device": "drive0",
61390edef80SJohn Snow         "type": "backup",
61490edef80SJohn Snow         "speed": 0,
61590edef80SJohn Snow         "len": 68719476736,
61690edef80SJohn Snow         "offset": 68719476736
61790edef80SJohn Snow       },
61890edef80SJohn Snow       "event": "BLOCK_JOB_COMPLETED"
61990edef80SJohn Snow     }
62090edef80SJohn Snow
62190edef80SJohn Snow  <- {
62290edef80SJohn Snow       "timestamp": {...},
62390edef80SJohn Snow       "data": {
62490edef80SJohn Snow         "status": "concluded",
62590edef80SJohn Snow         "id": "drive0"
62690edef80SJohn Snow       },
62790edef80SJohn Snow       "event": "JOB_STATUS_CHANGE"
62890edef80SJohn Snow     }
62990edef80SJohn Snow
63090edef80SJohn Snow  <- {
63190edef80SJohn Snow       "timestamp": {...},
63290edef80SJohn Snow       "data": {
63390edef80SJohn Snow         "status": "null",
63490edef80SJohn Snow         "id": "drive0"
63590edef80SJohn Snow       },
63690edef80SJohn Snow       "event": "JOB_STATUS_CHANGE"
63790edef80SJohn Snow     }
63890edef80SJohn Snow
63990edef80SJohn SnowA full explanation of the job transition semantics and the JOB_STATUS_CHANGE
64090edef80SJohn Snowevent are beyond the scope of this document and will be omitted in all
64190edef80SJohn Snowsubsequent examples; above, several more events have been omitted for brevity.
64290edef80SJohn Snow
64390edef80SJohn Snow.. note:: Subsequent examples will omit all events except BLOCK_JOB_COMPLETED
64490edef80SJohn Snow          except where necessary to illustrate workflow differences.
64590edef80SJohn Snow
64690edef80SJohn Snow          Omitted events and json objects will be represented by ellipses:
64790edef80SJohn Snow          ``...``
64890edef80SJohn Snow
64990edef80SJohn SnowExample: Resetting an Incremental Backup Anchor Point
65090edef80SJohn Snow~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
65190edef80SJohn Snow
65290edef80SJohn SnowIf we want to start a new backup chain with an existing bitmap, we can also
65390edef80SJohn Snowuse a transaction to reset the bitmap while making a new full backup:
65490edef80SJohn Snow
655a7786bfbSJohn Snow.. code-block:: QMP
65690edef80SJohn Snow
65790edef80SJohn Snow  -> {
65890edef80SJohn Snow       "execute": "transaction",
65990edef80SJohn Snow       "arguments": {
66090edef80SJohn Snow         "actions": [
66190edef80SJohn Snow         {
66290edef80SJohn Snow           "type": "block-dirty-bitmap-clear",
66390edef80SJohn Snow           "data": {
66490edef80SJohn Snow             "node": "drive0",
66590edef80SJohn Snow             "name": "bitmap0"
66690edef80SJohn Snow           }
66790edef80SJohn Snow         },
66890edef80SJohn Snow         {
66924d6cc1fSVladimir Sementsov-Ogievskiy           "type": "blockdev-backup",
67090edef80SJohn Snow           "data": {
67190edef80SJohn Snow             "device": "drive0",
67224d6cc1fSVladimir Sementsov-Ogievskiy             "target": "target0",
67324d6cc1fSVladimir Sementsov-Ogievskiy             "sync": "full"
67490edef80SJohn Snow           }
67590edef80SJohn Snow         }
67690edef80SJohn Snow       ]
67790edef80SJohn Snow     }
67890edef80SJohn Snow   }
67990edef80SJohn Snow
68090edef80SJohn Snow  <- { "return": {} }
68190edef80SJohn Snow
68290edef80SJohn Snow  ...
68390edef80SJohn Snow
68490edef80SJohn Snow  <- {
68590edef80SJohn Snow       "timestamp": {...},
68690edef80SJohn Snow       "data": {
68790edef80SJohn Snow         "device": "drive0",
68890edef80SJohn Snow         "type": "backup",
68990edef80SJohn Snow         "speed": 0,
69090edef80SJohn Snow         "len": 68719476736,
69190edef80SJohn Snow         "offset": 68719476736
69290edef80SJohn Snow       },
69390edef80SJohn Snow       "event": "BLOCK_JOB_COMPLETED"
69490edef80SJohn Snow     }
69590edef80SJohn Snow
69690edef80SJohn Snow  ...
69790edef80SJohn Snow
69890edef80SJohn SnowThe result of this example is identical to the first, but we clear an existing
69990edef80SJohn Snowbitmap instead of adding a new one.
70090edef80SJohn Snow
70190edef80SJohn Snow.. tip:: In both of these examples, "bitmap0" is tied conceptually to the
70290edef80SJohn Snow         creation of new, full backups. This relationship is not saved or
70390edef80SJohn Snow         remembered by QEMU; it is up to the operator or management layer to
70490edef80SJohn Snow         remember which bitmaps are associated with which backups.
7057746cf8aSKashyap Chamarthy
7067746cf8aSKashyap ChamarthyExample: First Incremental Backup
7077746cf8aSKashyap Chamarthy~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7087746cf8aSKashyap Chamarthy
70990edef80SJohn Snow#. Create a full backup and sync it to a dirty bitmap using any method:
7107746cf8aSKashyap Chamarthy
71190edef80SJohn Snow   - Either of the two live backup method demonstrated above,
71290edef80SJohn Snow   - Using QMP commands with the VM paused as in the `Justification`_ section,
71390edef80SJohn Snow     or
71490edef80SJohn Snow   - With the VM offline, manually copy the image and start the VM in a paused
71590edef80SJohn Snow     state, careful to add a new bitmap before the VM begins execution.
7167746cf8aSKashyap Chamarthy
71790edef80SJohn Snow   Whichever method is chosen, let's assume that at the end of this step:
7187746cf8aSKashyap Chamarthy
71990edef80SJohn Snow   - The full backup is named ``drive0.full.qcow2``.
72090edef80SJohn Snow   - The bitmap we created is named ``bitmap0``, attached to ``drive0``.
72190edef80SJohn Snow
72290edef80SJohn Snow#. Create a destination image for the incremental backup that utilizes the
72390edef80SJohn Snow   full backup as a backing image.
72490edef80SJohn Snow
72590edef80SJohn Snow   - Let's assume the new incremental image is named ``drive0.inc0.qcow2``:
7267746cf8aSKashyap Chamarthy
7277746cf8aSKashyap Chamarthy   .. code:: bash
7287746cf8aSKashyap Chamarthy
72990edef80SJohn Snow       $ qemu-img create -f qcow2 drive0.inc0.qcow2 \
73090edef80SJohn Snow         -b drive0.full.qcow2 -F qcow2
7317746cf8aSKashyap Chamarthy
73224d6cc1fSVladimir Sementsov-Ogievskiy#. Add target block node:
73324d6cc1fSVladimir Sementsov-Ogievskiy
73424d6cc1fSVladimir Sementsov-Ogievskiy   .. code-block:: QMP
73524d6cc1fSVladimir Sementsov-Ogievskiy
73624d6cc1fSVladimir Sementsov-Ogievskiy    -> {
73724d6cc1fSVladimir Sementsov-Ogievskiy         "execute": "blockdev-add",
73824d6cc1fSVladimir Sementsov-Ogievskiy         "arguments": {
73924d6cc1fSVladimir Sementsov-Ogievskiy           "node-name": "target0",
74024d6cc1fSVladimir Sementsov-Ogievskiy           "driver": "qcow2",
74124d6cc1fSVladimir Sementsov-Ogievskiy           "file": {
74224d6cc1fSVladimir Sementsov-Ogievskiy             "driver": "file",
74324d6cc1fSVladimir Sementsov-Ogievskiy             "filename": "drive0.inc0.qcow2"
74424d6cc1fSVladimir Sementsov-Ogievskiy           }
74524d6cc1fSVladimir Sementsov-Ogievskiy         }
74624d6cc1fSVladimir Sementsov-Ogievskiy       }
74724d6cc1fSVladimir Sementsov-Ogievskiy
74824d6cc1fSVladimir Sementsov-Ogievskiy    <- { "return": {} }
74924d6cc1fSVladimir Sementsov-Ogievskiy
75090edef80SJohn Snow#. Issue an incremental backup command:
7517746cf8aSKashyap Chamarthy
752a7786bfbSJohn Snow   .. code-block:: QMP
7537746cf8aSKashyap Chamarthy
75490edef80SJohn Snow    -> {
75524d6cc1fSVladimir Sementsov-Ogievskiy         "execute": "blockdev-backup",
7567746cf8aSKashyap Chamarthy         "arguments": {
7577746cf8aSKashyap Chamarthy           "device": "drive0",
7587746cf8aSKashyap Chamarthy           "bitmap": "bitmap0",
75924d6cc1fSVladimir Sementsov-Ogievskiy           "target": "target0",
76024d6cc1fSVladimir Sementsov-Ogievskiy           "sync": "incremental"
7617746cf8aSKashyap Chamarthy         }
7627746cf8aSKashyap Chamarthy       }
7637746cf8aSKashyap Chamarthy
76490edef80SJohn Snow    <- { "return": {} }
76590edef80SJohn Snow
76690edef80SJohn Snow    ...
76790edef80SJohn Snow
76890edef80SJohn Snow    <- {
76990edef80SJohn Snow         "timestamp": {...},
77090edef80SJohn Snow         "data": {
77190edef80SJohn Snow           "device": "drive0",
77290edef80SJohn Snow           "type": "backup",
77390edef80SJohn Snow           "speed": 0,
77490edef80SJohn Snow           "len": 68719476736,
77590edef80SJohn Snow           "offset": 68719476736
77690edef80SJohn Snow         },
77790edef80SJohn Snow         "event": "BLOCK_JOB_COMPLETED"
77890edef80SJohn Snow       }
77990edef80SJohn Snow
78090edef80SJohn Snow    ...
78190edef80SJohn Snow
78290edef80SJohn SnowThis copies any blocks modified since the full backup was created into the
78390edef80SJohn Snow``drive0.inc0.qcow2`` file. During the operation, ``bitmap0`` is marked
78490edef80SJohn Snow``+busy``. If the operation is successful, ``bitmap0`` will be cleared to
78590edef80SJohn Snowreflect the "incremental" backup regimen, which only copies out new changes
78690edef80SJohn Snowfrom each incremental backup.
78790edef80SJohn Snow
78890edef80SJohn Snow.. note:: Any new writes that occur after the backup operation starts do not
78990edef80SJohn Snow          get copied to the destination. The backup's "point in time" is when
79090edef80SJohn Snow          the backup starts, not when it ends. These writes are recorded in a
79190edef80SJohn Snow          special bitmap that gets re-added to bitmap0 when the backup ends so
79290edef80SJohn Snow          that the next incremental backup can copy them out.
79390edef80SJohn Snow
7947746cf8aSKashyap ChamarthyExample: Second Incremental Backup
7957746cf8aSKashyap Chamarthy~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7967746cf8aSKashyap Chamarthy
79790edef80SJohn Snow#. Create a new destination image for the incremental backup that points to
79890edef80SJohn Snow   the previous one, e.g.: ``drive0.inc1.qcow2``
7997746cf8aSKashyap Chamarthy
8007746cf8aSKashyap Chamarthy   .. code:: bash
8017746cf8aSKashyap Chamarthy
80290edef80SJohn Snow       $ qemu-img create -f qcow2 drive0.inc1.qcow2 \
80390edef80SJohn Snow         -b drive0.inc0.qcow2 -F qcow2
8047746cf8aSKashyap Chamarthy
80524d6cc1fSVladimir Sementsov-Ogievskiy#. Add target block node:
80624d6cc1fSVladimir Sementsov-Ogievskiy
80724d6cc1fSVladimir Sementsov-Ogievskiy   .. code-block:: QMP
80824d6cc1fSVladimir Sementsov-Ogievskiy
80924d6cc1fSVladimir Sementsov-Ogievskiy    -> {
81024d6cc1fSVladimir Sementsov-Ogievskiy         "execute": "blockdev-add",
81124d6cc1fSVladimir Sementsov-Ogievskiy         "arguments": {
81224d6cc1fSVladimir Sementsov-Ogievskiy           "node-name": "target0",
81324d6cc1fSVladimir Sementsov-Ogievskiy           "driver": "qcow2",
81424d6cc1fSVladimir Sementsov-Ogievskiy           "file": {
81524d6cc1fSVladimir Sementsov-Ogievskiy             "driver": "file",
81624d6cc1fSVladimir Sementsov-Ogievskiy             "filename": "drive0.inc1.qcow2"
81724d6cc1fSVladimir Sementsov-Ogievskiy           }
81824d6cc1fSVladimir Sementsov-Ogievskiy         }
81924d6cc1fSVladimir Sementsov-Ogievskiy       }
82024d6cc1fSVladimir Sementsov-Ogievskiy
82124d6cc1fSVladimir Sementsov-Ogievskiy    <- { "return": {} }
82224d6cc1fSVladimir Sementsov-Ogievskiy
82390edef80SJohn Snow#. Issue a new incremental backup command. The only difference here is that we
82490edef80SJohn Snow   have changed the target image below.
8257746cf8aSKashyap Chamarthy
826a7786bfbSJohn Snow   .. code-block:: QMP
8277746cf8aSKashyap Chamarthy
82890edef80SJohn Snow    -> {
82924d6cc1fSVladimir Sementsov-Ogievskiy         "execute": "blockdev-backup",
8307746cf8aSKashyap Chamarthy         "arguments": {
8317746cf8aSKashyap Chamarthy           "device": "drive0",
8327746cf8aSKashyap Chamarthy           "bitmap": "bitmap0",
83324d6cc1fSVladimir Sementsov-Ogievskiy           "target": "target0",
83424d6cc1fSVladimir Sementsov-Ogievskiy           "sync": "incremental"
8357746cf8aSKashyap Chamarthy         }
8367746cf8aSKashyap Chamarthy       }
8377746cf8aSKashyap Chamarthy
83890edef80SJohn Snow    <- { "return": {} }
8397746cf8aSKashyap Chamarthy
84090edef80SJohn Snow    ...
8417746cf8aSKashyap Chamarthy
84290edef80SJohn Snow    <- {
84390edef80SJohn Snow         "timestamp": {...},
84490edef80SJohn Snow         "data": {
84590edef80SJohn Snow           "device": "drive0",
84690edef80SJohn Snow           "type": "backup",
84790edef80SJohn Snow           "speed": 0,
84890edef80SJohn Snow           "len": 68719476736,
84990edef80SJohn Snow           "offset": 68719476736
85090edef80SJohn Snow         },
85190edef80SJohn Snow         "event": "BLOCK_JOB_COMPLETED"
85290edef80SJohn Snow       }
8537746cf8aSKashyap Chamarthy
85490edef80SJohn Snow    ...
8557746cf8aSKashyap Chamarthy
85690edef80SJohn SnowBecause the first incremental backup from the previous example completed
85790edef80SJohn Snowsuccessfully, ``bitmap0`` was synchronized with ``drive0.inc0.qcow2``. Here,
85890edef80SJohn Snowwe use ``bitmap0`` again to create a new incremental backup that targets the
85990edef80SJohn Snowprevious one, creating a chain of three images:
8607746cf8aSKashyap Chamarthy
86190edef80SJohn Snow.. admonition:: Diagram
8627746cf8aSKashyap Chamarthy
86390edef80SJohn Snow .. code:: text
86490edef80SJohn Snow
86590edef80SJohn Snow   +-------------------+   +-------------------+   +-------------------+
86690edef80SJohn Snow   | drive0.full.qcow2 |<--| drive0.inc0.qcow2 |<--| drive0.inc1.qcow2 |
86790edef80SJohn Snow   +-------------------+   +-------------------+   +-------------------+
86890edef80SJohn Snow
86990edef80SJohn SnowEach new incremental backup re-synchronizes the bitmap to the latest backup
87090edef80SJohn Snowauthored, allowing a user to continue to "consume" it to create new backups on
87190edef80SJohn Snowtop of an existing chain.
87290edef80SJohn Snow
87390edef80SJohn SnowIn the above diagram, neither drive0.inc1.qcow2 nor drive0.inc0.qcow2 are
87490edef80SJohn Snowcomplete images by themselves, but rely on their backing chain to reconstruct
87590edef80SJohn Snowa full image. The dependency terminates with each full backup.
87690edef80SJohn Snow
87790edef80SJohn SnowEach backup in this chain remains independent, and is unchanged by new entries
87890edef80SJohn Snowmade later in the chain. For instance, drive0.inc0.qcow2 remains a perfectly
87990edef80SJohn Snowvalid backup of the disk as it was when that backup was issued.
88090edef80SJohn Snow
88190edef80SJohn SnowExample: Incremental Push Backups without Backing Files
88290edef80SJohn Snow~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
88390edef80SJohn Snow
88490edef80SJohn SnowBackup images are best kept off-site, so we often will not have the preceding
88590edef80SJohn Snowbackups in a chain available to link against. This is not a problem at backup
88690edef80SJohn Snowtime; we simply do not set the backing image when creating the destination
88790edef80SJohn Snowimage:
88890edef80SJohn Snow
88990edef80SJohn Snow#. Create a new destination image with no backing file set. We will need to
89090edef80SJohn Snow   specify the size of the base image, because the backing file isn't
89190edef80SJohn Snow   available for QEMU to use to determine it.
8927746cf8aSKashyap Chamarthy
8937746cf8aSKashyap Chamarthy   .. code:: bash
8947746cf8aSKashyap Chamarthy
89590edef80SJohn Snow       $ qemu-img create -f qcow2 drive0.inc2.qcow2 64G
8967746cf8aSKashyap Chamarthy
89790edef80SJohn Snow   .. note:: Alternatively, you can omit ``mode: "existing"`` from the push
89890edef80SJohn Snow             backup commands to have QEMU create an image without a backing
89990edef80SJohn Snow             file for you, but you lose control over format options like
90090edef80SJohn Snow             compatibility and preallocation presets.
90190edef80SJohn Snow
90224d6cc1fSVladimir Sementsov-Ogievskiy#. Add target block node:
90324d6cc1fSVladimir Sementsov-Ogievskiy
90424d6cc1fSVladimir Sementsov-Ogievskiy   .. code-block:: QMP
90524d6cc1fSVladimir Sementsov-Ogievskiy
90624d6cc1fSVladimir Sementsov-Ogievskiy    -> {
90724d6cc1fSVladimir Sementsov-Ogievskiy         "execute": "blockdev-add",
90824d6cc1fSVladimir Sementsov-Ogievskiy         "arguments": {
90924d6cc1fSVladimir Sementsov-Ogievskiy           "node-name": "target0",
91024d6cc1fSVladimir Sementsov-Ogievskiy           "driver": "qcow2",
91124d6cc1fSVladimir Sementsov-Ogievskiy           "file": {
91224d6cc1fSVladimir Sementsov-Ogievskiy             "driver": "file",
91324d6cc1fSVladimir Sementsov-Ogievskiy             "filename": "drive0.inc2.qcow2"
91424d6cc1fSVladimir Sementsov-Ogievskiy           }
91524d6cc1fSVladimir Sementsov-Ogievskiy         }
91624d6cc1fSVladimir Sementsov-Ogievskiy       }
91724d6cc1fSVladimir Sementsov-Ogievskiy
91824d6cc1fSVladimir Sementsov-Ogievskiy    <- { "return": {} }
91924d6cc1fSVladimir Sementsov-Ogievskiy
92090edef80SJohn Snow#. Issue a new incremental backup command. Apart from the new destination
92190edef80SJohn Snow   image, there is no difference from the last two examples.
9227746cf8aSKashyap Chamarthy
923a7786bfbSJohn Snow   .. code-block:: QMP
9247746cf8aSKashyap Chamarthy
92590edef80SJohn Snow    -> {
92624d6cc1fSVladimir Sementsov-Ogievskiy         "execute": "blockdev-backup",
9277746cf8aSKashyap Chamarthy         "arguments": {
9287746cf8aSKashyap Chamarthy           "device": "drive0",
9297746cf8aSKashyap Chamarthy           "bitmap": "bitmap0",
93024d6cc1fSVladimir Sementsov-Ogievskiy           "target": "target0",
93124d6cc1fSVladimir Sementsov-Ogievskiy           "sync": "incremental"
9327746cf8aSKashyap Chamarthy         }
9337746cf8aSKashyap Chamarthy       }
9347746cf8aSKashyap Chamarthy
93590edef80SJohn Snow    <- { "return": {} }
9367746cf8aSKashyap Chamarthy
93790edef80SJohn Snow    ...
9387746cf8aSKashyap Chamarthy
93990edef80SJohn Snow    <- {
94090edef80SJohn Snow         "timestamp": {...},
94190edef80SJohn Snow         "data": {
94290edef80SJohn Snow           "device": "drive0",
94390edef80SJohn Snow           "type": "backup",
94490edef80SJohn Snow           "speed": 0,
94590edef80SJohn Snow           "len": 68719476736,
94690edef80SJohn Snow           "offset": 68719476736
94790edef80SJohn Snow         },
94890edef80SJohn Snow         "event": "BLOCK_JOB_COMPLETED"
94990edef80SJohn Snow       }
9507746cf8aSKashyap Chamarthy
95190edef80SJohn Snow    ...
95290edef80SJohn Snow
95390edef80SJohn SnowThe only difference from the perspective of the user is that you will need to
95490edef80SJohn Snowset the backing image when attempting to restore the backup:
9557746cf8aSKashyap Chamarthy
9567746cf8aSKashyap Chamarthy.. code:: bash
9577746cf8aSKashyap Chamarthy
95890edef80SJohn Snow    $ qemu-img rebase drive0.inc2.qcow2 \
95990edef80SJohn Snow      -u -b drive0.inc1.qcow2
9607746cf8aSKashyap Chamarthy
96190edef80SJohn SnowThis uses the "unsafe" rebase mode to simply set the backing file to a file
96290edef80SJohn Snowthat isn't present.
96390edef80SJohn Snow
96490edef80SJohn SnowIt is also possible to use ``--image-opts`` to specify the entire backing
96590edef80SJohn Snowchain by hand as an ephemeral property at runtime, but that is beyond the
96690edef80SJohn Snowscope of this document.
96790edef80SJohn Snow
96890edef80SJohn SnowExample: Multi-drive Incremental Backup
96990edef80SJohn Snow~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
97090edef80SJohn Snow
97190edef80SJohn SnowAssume we have a VM with two drives, "drive0" and "drive1" and we wish to back
97290edef80SJohn Snowboth of them up such that the two backups represent the same crash-consistent
97390edef80SJohn Snowpoint in time.
97490edef80SJohn Snow
97590edef80SJohn Snow#. For each drive, create an empty image:
97690edef80SJohn Snow
97790edef80SJohn Snow   .. code:: bash
97890edef80SJohn Snow
97990edef80SJohn Snow    $ qemu-img create -f qcow2 drive0.full.qcow2 64G
98090edef80SJohn Snow    $ qemu-img create -f qcow2 drive1.full.qcow2 64G
98190edef80SJohn Snow
98224d6cc1fSVladimir Sementsov-Ogievskiy#. Add target block nodes:
98324d6cc1fSVladimir Sementsov-Ogievskiy
98424d6cc1fSVladimir Sementsov-Ogievskiy   .. code-block:: QMP
98524d6cc1fSVladimir Sementsov-Ogievskiy
98624d6cc1fSVladimir Sementsov-Ogievskiy    -> {
98724d6cc1fSVladimir Sementsov-Ogievskiy         "execute": "blockdev-add",
98824d6cc1fSVladimir Sementsov-Ogievskiy         "arguments": {
98924d6cc1fSVladimir Sementsov-Ogievskiy           "node-name": "target0",
99024d6cc1fSVladimir Sementsov-Ogievskiy           "driver": "qcow2",
99124d6cc1fSVladimir Sementsov-Ogievskiy           "file": {
99224d6cc1fSVladimir Sementsov-Ogievskiy             "driver": "file",
99324d6cc1fSVladimir Sementsov-Ogievskiy             "filename": "drive0.full.qcow2"
99424d6cc1fSVladimir Sementsov-Ogievskiy           }
99524d6cc1fSVladimir Sementsov-Ogievskiy         }
99624d6cc1fSVladimir Sementsov-Ogievskiy       }
99724d6cc1fSVladimir Sementsov-Ogievskiy
99824d6cc1fSVladimir Sementsov-Ogievskiy    <- { "return": {} }
99924d6cc1fSVladimir Sementsov-Ogievskiy
100024d6cc1fSVladimir Sementsov-Ogievskiy    -> {
100124d6cc1fSVladimir Sementsov-Ogievskiy         "execute": "blockdev-add",
100224d6cc1fSVladimir Sementsov-Ogievskiy         "arguments": {
100324d6cc1fSVladimir Sementsov-Ogievskiy           "node-name": "target1",
100424d6cc1fSVladimir Sementsov-Ogievskiy           "driver": "qcow2",
100524d6cc1fSVladimir Sementsov-Ogievskiy           "file": {
100624d6cc1fSVladimir Sementsov-Ogievskiy             "driver": "file",
100724d6cc1fSVladimir Sementsov-Ogievskiy             "filename": "drive1.full.qcow2"
100824d6cc1fSVladimir Sementsov-Ogievskiy           }
100924d6cc1fSVladimir Sementsov-Ogievskiy         }
101024d6cc1fSVladimir Sementsov-Ogievskiy       }
101124d6cc1fSVladimir Sementsov-Ogievskiy
101224d6cc1fSVladimir Sementsov-Ogievskiy    <- { "return": {} }
101324d6cc1fSVladimir Sementsov-Ogievskiy
101490edef80SJohn Snow#. Create a full (anchor) backup for each drive, with accompanying bitmaps:
10157746cf8aSKashyap Chamarthy
1016a7786bfbSJohn Snow   .. code-block:: QMP
10177746cf8aSKashyap Chamarthy
101890edef80SJohn Snow    -> {
101990edef80SJohn Snow         "execute": "transaction",
10207746cf8aSKashyap Chamarthy         "arguments": {
10217746cf8aSKashyap Chamarthy           "actions": [
102290edef80SJohn Snow             {
102390edef80SJohn Snow               "type": "block-dirty-bitmap-add",
102490edef80SJohn Snow               "data": {
102590edef80SJohn Snow                 "node": "drive0",
102690edef80SJohn Snow                 "name": "bitmap0"
102790edef80SJohn Snow               }
102890edef80SJohn Snow             },
102990edef80SJohn Snow             {
103090edef80SJohn Snow               "type": "block-dirty-bitmap-add",
103190edef80SJohn Snow               "data": {
103290edef80SJohn Snow                 "node": "drive1",
103390edef80SJohn Snow                 "name": "bitmap0"
103490edef80SJohn Snow               }
103590edef80SJohn Snow             },
103690edef80SJohn Snow             {
103724d6cc1fSVladimir Sementsov-Ogievskiy               "type": "blockdev-backup",
103890edef80SJohn Snow               "data": {
103990edef80SJohn Snow                 "device": "drive0",
104024d6cc1fSVladimir Sementsov-Ogievskiy                 "target": "target0",
104124d6cc1fSVladimir Sementsov-Ogievskiy                 "sync": "full"
104290edef80SJohn Snow               }
104390edef80SJohn Snow             },
104490edef80SJohn Snow             {
104524d6cc1fSVladimir Sementsov-Ogievskiy               "type": "blockdev-backup",
104690edef80SJohn Snow               "data": {
104790edef80SJohn Snow                 "device": "drive1",
104824d6cc1fSVladimir Sementsov-Ogievskiy                 "target": "target1",
104924d6cc1fSVladimir Sementsov-Ogievskiy                 "sync": "full"
105090edef80SJohn Snow               }
105190edef80SJohn Snow             }
10527746cf8aSKashyap Chamarthy           ]
10537746cf8aSKashyap Chamarthy         }
10547746cf8aSKashyap Chamarthy       }
10557746cf8aSKashyap Chamarthy
105690edef80SJohn Snow    <- { "return": {} }
10577746cf8aSKashyap Chamarthy
105890edef80SJohn Snow    ...
10597746cf8aSKashyap Chamarthy
106090edef80SJohn Snow    <- {
106190edef80SJohn Snow         "timestamp": {...},
106290edef80SJohn Snow         "data": {
106390edef80SJohn Snow           "device": "drive0",
106490edef80SJohn Snow           "type": "backup",
106590edef80SJohn Snow           "speed": 0,
106690edef80SJohn Snow           "len": 68719476736,
106790edef80SJohn Snow           "offset": 68719476736
106890edef80SJohn Snow         },
10697746cf8aSKashyap Chamarthy         "event": "BLOCK_JOB_COMPLETED"
10707746cf8aSKashyap Chamarthy       }
10717746cf8aSKashyap Chamarthy
107290edef80SJohn Snow    ...
107390edef80SJohn Snow
107490edef80SJohn Snow    <- {
107590edef80SJohn Snow         "timestamp": {...},
107690edef80SJohn Snow         "data": {
107790edef80SJohn Snow           "device": "drive1",
107890edef80SJohn Snow           "type": "backup",
107990edef80SJohn Snow           "speed": 0,
108090edef80SJohn Snow           "len": 68719476736,
108190edef80SJohn Snow           "offset": 68719476736
108290edef80SJohn Snow         },
108390edef80SJohn Snow         "event": "BLOCK_JOB_COMPLETED"
108490edef80SJohn Snow       }
108590edef80SJohn Snow
108690edef80SJohn Snow    ...
108790edef80SJohn Snow
108890edef80SJohn Snow#. Later, create new destination images for each of the incremental backups
108990edef80SJohn Snow   that point to their respective full backups:
109090edef80SJohn Snow
109190edef80SJohn Snow   .. code:: bash
109290edef80SJohn Snow
109390edef80SJohn Snow     $ qemu-img create -f qcow2 drive0.inc0.qcow2 \
109490edef80SJohn Snow       -b drive0.full.qcow2 -F qcow2
109590edef80SJohn Snow     $ qemu-img create -f qcow2 drive1.inc0.qcow2 \
109690edef80SJohn Snow       -b drive1.full.qcow2 -F qcow2
109790edef80SJohn Snow
109824d6cc1fSVladimir Sementsov-Ogievskiy#. Add target block nodes:
109924d6cc1fSVladimir Sementsov-Ogievskiy
110024d6cc1fSVladimir Sementsov-Ogievskiy   .. code-block:: QMP
110124d6cc1fSVladimir Sementsov-Ogievskiy
110224d6cc1fSVladimir Sementsov-Ogievskiy    -> {
110324d6cc1fSVladimir Sementsov-Ogievskiy         "execute": "blockdev-add",
110424d6cc1fSVladimir Sementsov-Ogievskiy         "arguments": {
110524d6cc1fSVladimir Sementsov-Ogievskiy           "node-name": "target0",
110624d6cc1fSVladimir Sementsov-Ogievskiy           "driver": "qcow2",
110724d6cc1fSVladimir Sementsov-Ogievskiy           "file": {
110824d6cc1fSVladimir Sementsov-Ogievskiy             "driver": "file",
110924d6cc1fSVladimir Sementsov-Ogievskiy             "filename": "drive0.inc0.qcow2"
111024d6cc1fSVladimir Sementsov-Ogievskiy           }
111124d6cc1fSVladimir Sementsov-Ogievskiy         }
111224d6cc1fSVladimir Sementsov-Ogievskiy       }
111324d6cc1fSVladimir Sementsov-Ogievskiy
111424d6cc1fSVladimir Sementsov-Ogievskiy    <- { "return": {} }
111524d6cc1fSVladimir Sementsov-Ogievskiy
111624d6cc1fSVladimir Sementsov-Ogievskiy    -> {
111724d6cc1fSVladimir Sementsov-Ogievskiy         "execute": "blockdev-add",
111824d6cc1fSVladimir Sementsov-Ogievskiy         "arguments": {
111924d6cc1fSVladimir Sementsov-Ogievskiy           "node-name": "target1",
112024d6cc1fSVladimir Sementsov-Ogievskiy           "driver": "qcow2",
112124d6cc1fSVladimir Sementsov-Ogievskiy           "file": {
112224d6cc1fSVladimir Sementsov-Ogievskiy             "driver": "file",
112324d6cc1fSVladimir Sementsov-Ogievskiy             "filename": "drive1.inc0.qcow2"
112424d6cc1fSVladimir Sementsov-Ogievskiy           }
112524d6cc1fSVladimir Sementsov-Ogievskiy         }
112624d6cc1fSVladimir Sementsov-Ogievskiy       }
112724d6cc1fSVladimir Sementsov-Ogievskiy
112824d6cc1fSVladimir Sementsov-Ogievskiy    <- { "return": {} }
112924d6cc1fSVladimir Sementsov-Ogievskiy
113090edef80SJohn Snow#. Issue a multi-drive incremental push backup transaction:
11317746cf8aSKashyap Chamarthy
1132a7786bfbSJohn Snow   .. code-block:: QMP
11337746cf8aSKashyap Chamarthy
113490edef80SJohn Snow    -> {
113590edef80SJohn Snow         "execute": "transaction",
11367746cf8aSKashyap Chamarthy         "arguments": {
11377746cf8aSKashyap Chamarthy           "actions": [
113890edef80SJohn Snow             {
113924d6cc1fSVladimir Sementsov-Ogievskiy               "type": "blockev-backup",
114090edef80SJohn Snow               "data": {
114190edef80SJohn Snow                 "device": "drive0",
114290edef80SJohn Snow                 "bitmap": "bitmap0",
114390edef80SJohn Snow                 "sync": "incremental",
114424d6cc1fSVladimir Sementsov-Ogievskiy                 "target": "target0"
11457746cf8aSKashyap Chamarthy               }
114690edef80SJohn Snow             },
114790edef80SJohn Snow             {
114824d6cc1fSVladimir Sementsov-Ogievskiy               "type": "blockdev-backup",
114990edef80SJohn Snow               "data": {
115090edef80SJohn Snow                 "device": "drive1",
115190edef80SJohn Snow                 "bitmap": "bitmap0",
115290edef80SJohn Snow                 "sync": "incremental",
115324d6cc1fSVladimir Sementsov-Ogievskiy                 "target": "target1"
115490edef80SJohn Snow               }
115590edef80SJohn Snow             },
115690edef80SJohn Snow           ]
11577746cf8aSKashyap Chamarthy         }
11587746cf8aSKashyap Chamarthy       }
11597746cf8aSKashyap Chamarthy
116090edef80SJohn Snow    <- { "return": {} }
11617746cf8aSKashyap Chamarthy
116290edef80SJohn Snow    ...
116390edef80SJohn Snow
116490edef80SJohn Snow    <- {
116590edef80SJohn Snow         "timestamp": {...},
116690edef80SJohn Snow         "data": {
116790edef80SJohn Snow           "device": "drive0",
116890edef80SJohn Snow           "type": "backup",
116990edef80SJohn Snow           "speed": 0,
117090edef80SJohn Snow           "len": 68719476736,
117190edef80SJohn Snow           "offset": 68719476736
117290edef80SJohn Snow         },
117390edef80SJohn Snow         "event": "BLOCK_JOB_COMPLETED"
117490edef80SJohn Snow       }
117590edef80SJohn Snow
117690edef80SJohn Snow    ...
117790edef80SJohn Snow
117890edef80SJohn Snow    <- {
117990edef80SJohn Snow         "timestamp": {...},
118090edef80SJohn Snow         "data": {
118190edef80SJohn Snow           "device": "drive1",
118290edef80SJohn Snow           "type": "backup",
118390edef80SJohn Snow           "speed": 0,
118490edef80SJohn Snow           "len": 68719476736,
118590edef80SJohn Snow           "offset": 68719476736
118690edef80SJohn Snow         },
118790edef80SJohn Snow         "event": "BLOCK_JOB_COMPLETED"
118890edef80SJohn Snow       }
118990edef80SJohn Snow
119090edef80SJohn Snow    ...
119190edef80SJohn Snow
119290edef80SJohn SnowPush Backup Errors & Recovery
119390edef80SJohn Snow-----------------------------
119490edef80SJohn Snow
119590edef80SJohn SnowIn the event of an error that occurs after a push backup job is successfully
119690edef80SJohn Snowlaunched, either by an individual QMP command or a QMP transaction, the user
119790edef80SJohn Snowwill receive a ``BLOCK_JOB_COMPLETE`` event with a failure message,
119890edef80SJohn Snowaccompanied by a ``BLOCK_JOB_ERROR`` event.
119990edef80SJohn Snow
120090edef80SJohn SnowIn the case of a job being cancelled, the user will receive a
120190edef80SJohn Snow``BLOCK_JOB_CANCELLED`` event instead of a pair of COMPLETE and ERROR
120290edef80SJohn Snowevents.
120390edef80SJohn Snow
120490edef80SJohn SnowIn either failure case, the bitmap used for the failed operation is not
120590edef80SJohn Snowcleared. It will contain all of the dirty bits it did at the start of the
120690edef80SJohn Snowoperation, plus any new bits that got marked during the operation.
120790edef80SJohn Snow
120890edef80SJohn SnowEffectively, the "point in time" that a bitmap is recording differences
120990edef80SJohn Snowagainst is kept at the issuance of the last successful incremental backup,
121090edef80SJohn Snowinstead of being moved forward to the start of this now-failed backup.
121190edef80SJohn Snow
121290edef80SJohn SnowOnce the underlying problem is addressed (e.g. more storage space is allocated
121390edef80SJohn Snowon the destination), the incremental backup command can be retried with the
121490edef80SJohn Snowsame bitmap.
121590edef80SJohn Snow
121690edef80SJohn SnowExample: Individual Failures
121790edef80SJohn Snow~~~~~~~~~~~~~~~~~~~~~~~~~~~~
121890edef80SJohn Snow
121990edef80SJohn SnowIncremental Push Backup jobs that fail individually behave simply as
122090edef80SJohn Snowdescribed above. This example demonstrates the single-job failure case:
122190edef80SJohn Snow
122290edef80SJohn Snow#. Create a target image:
122390edef80SJohn Snow
122490edef80SJohn Snow   .. code:: bash
122590edef80SJohn Snow
122690edef80SJohn Snow       $ qemu-img create -f qcow2 drive0.inc0.qcow2 \
122790edef80SJohn Snow         -b drive0.full.qcow2 -F qcow2
122890edef80SJohn Snow
122924d6cc1fSVladimir Sementsov-Ogievskiy#. Add target block node:
123024d6cc1fSVladimir Sementsov-Ogievskiy
123124d6cc1fSVladimir Sementsov-Ogievskiy   .. code-block:: QMP
123224d6cc1fSVladimir Sementsov-Ogievskiy
123324d6cc1fSVladimir Sementsov-Ogievskiy    -> {
123424d6cc1fSVladimir Sementsov-Ogievskiy         "execute": "blockdev-add",
123524d6cc1fSVladimir Sementsov-Ogievskiy         "arguments": {
123624d6cc1fSVladimir Sementsov-Ogievskiy           "node-name": "target0",
123724d6cc1fSVladimir Sementsov-Ogievskiy           "driver": "qcow2",
123824d6cc1fSVladimir Sementsov-Ogievskiy           "file": {
123924d6cc1fSVladimir Sementsov-Ogievskiy             "driver": "file",
124024d6cc1fSVladimir Sementsov-Ogievskiy             "filename": "drive0.inc0.qcow2"
124124d6cc1fSVladimir Sementsov-Ogievskiy           }
124224d6cc1fSVladimir Sementsov-Ogievskiy         }
124324d6cc1fSVladimir Sementsov-Ogievskiy       }
124424d6cc1fSVladimir Sementsov-Ogievskiy
124524d6cc1fSVladimir Sementsov-Ogievskiy    <- { "return": {} }
124624d6cc1fSVladimir Sementsov-Ogievskiy
124790edef80SJohn Snow#. Attempt to create an incremental backup via QMP:
124890edef80SJohn Snow
1249a7786bfbSJohn Snow   .. code-block:: QMP
125090edef80SJohn Snow
125190edef80SJohn Snow    -> {
125224d6cc1fSVladimir Sementsov-Ogievskiy         "execute": "blockdev-backup",
125390edef80SJohn Snow         "arguments": {
125490edef80SJohn Snow           "device": "drive0",
125590edef80SJohn Snow           "bitmap": "bitmap0",
125624d6cc1fSVladimir Sementsov-Ogievskiy           "target": "target0",
125724d6cc1fSVladimir Sementsov-Ogievskiy           "sync": "incremental"
125890edef80SJohn Snow         }
125990edef80SJohn Snow       }
126090edef80SJohn Snow
126190edef80SJohn Snow    <- { "return": {} }
126290edef80SJohn Snow
126390edef80SJohn Snow#. Receive a pair of events indicating failure:
126490edef80SJohn Snow
1265a7786bfbSJohn Snow   .. code-block:: QMP
126690edef80SJohn Snow
126790edef80SJohn Snow    <- {
126890edef80SJohn Snow         "timestamp": {...},
126990edef80SJohn Snow         "data": {
127090edef80SJohn Snow           "device": "drive0",
127190edef80SJohn Snow           "action": "report",
127290edef80SJohn Snow           "operation": "write"
127390edef80SJohn Snow         },
127490edef80SJohn Snow         "event": "BLOCK_JOB_ERROR"
127590edef80SJohn Snow       }
127690edef80SJohn Snow
127790edef80SJohn Snow    <- {
127890edef80SJohn Snow         "timestamp": {...},
127990edef80SJohn Snow         "data": {
128090edef80SJohn Snow           "speed": 0,
128190edef80SJohn Snow           "offset": 0,
128290edef80SJohn Snow           "len": 67108864,
128390edef80SJohn Snow           "error": "No space left on device",
128490edef80SJohn Snow           "device": "drive0",
128590edef80SJohn Snow           "type": "backup"
128690edef80SJohn Snow         },
128790edef80SJohn Snow         "event": "BLOCK_JOB_COMPLETED"
128890edef80SJohn Snow       }
128990edef80SJohn Snow
129024d6cc1fSVladimir Sementsov-Ogievskiy#. Remove target node:
129124d6cc1fSVladimir Sementsov-Ogievskiy
129224d6cc1fSVladimir Sementsov-Ogievskiy   .. code-block:: QMP
129324d6cc1fSVladimir Sementsov-Ogievskiy
129424d6cc1fSVladimir Sementsov-Ogievskiy    -> {
129524d6cc1fSVladimir Sementsov-Ogievskiy         "execute": "blockdev-del",
129624d6cc1fSVladimir Sementsov-Ogievskiy         "arguments": {
129724d6cc1fSVladimir Sementsov-Ogievskiy           "node-name": "target0",
129824d6cc1fSVladimir Sementsov-Ogievskiy         }
129924d6cc1fSVladimir Sementsov-Ogievskiy       }
130024d6cc1fSVladimir Sementsov-Ogievskiy
130124d6cc1fSVladimir Sementsov-Ogievskiy    <- { "return": {} }
130224d6cc1fSVladimir Sementsov-Ogievskiy
130390edef80SJohn Snow#. Delete the failed image, and re-create it.
130490edef80SJohn Snow
130590edef80SJohn Snow   .. code:: bash
130690edef80SJohn Snow
130790edef80SJohn Snow       $ rm drive0.inc0.qcow2
130890edef80SJohn Snow       $ qemu-img create -f qcow2 drive0.inc0.qcow2 \
130990edef80SJohn Snow         -b drive0.full.qcow2 -F qcow2
131090edef80SJohn Snow
131124d6cc1fSVladimir Sementsov-Ogievskiy#. Add target block node:
131224d6cc1fSVladimir Sementsov-Ogievskiy
131324d6cc1fSVladimir Sementsov-Ogievskiy   .. code-block:: QMP
131424d6cc1fSVladimir Sementsov-Ogievskiy
131524d6cc1fSVladimir Sementsov-Ogievskiy    -> {
131624d6cc1fSVladimir Sementsov-Ogievskiy         "execute": "blockdev-add",
131724d6cc1fSVladimir Sementsov-Ogievskiy         "arguments": {
131824d6cc1fSVladimir Sementsov-Ogievskiy           "node-name": "target0",
131924d6cc1fSVladimir Sementsov-Ogievskiy           "driver": "qcow2",
132024d6cc1fSVladimir Sementsov-Ogievskiy           "file": {
132124d6cc1fSVladimir Sementsov-Ogievskiy             "driver": "file",
132224d6cc1fSVladimir Sementsov-Ogievskiy             "filename": "drive0.inc0.qcow2"
132324d6cc1fSVladimir Sementsov-Ogievskiy           }
132424d6cc1fSVladimir Sementsov-Ogievskiy         }
132524d6cc1fSVladimir Sementsov-Ogievskiy       }
132624d6cc1fSVladimir Sementsov-Ogievskiy
132724d6cc1fSVladimir Sementsov-Ogievskiy    <- { "return": {} }
132824d6cc1fSVladimir Sementsov-Ogievskiy
132990edef80SJohn Snow#. Retry the command after fixing the underlying problem, such as
133090edef80SJohn Snow   freeing up space on the backup volume:
133190edef80SJohn Snow
1332a7786bfbSJohn Snow   .. code-block:: QMP
133390edef80SJohn Snow
133490edef80SJohn Snow    -> {
133524d6cc1fSVladimir Sementsov-Ogievskiy         "execute": "blockdev-backup",
133690edef80SJohn Snow         "arguments": {
133790edef80SJohn Snow           "device": "drive0",
133890edef80SJohn Snow           "bitmap": "bitmap0",
133924d6cc1fSVladimir Sementsov-Ogievskiy           "target": "target0",
134024d6cc1fSVladimir Sementsov-Ogievskiy           "sync": "incremental"
134190edef80SJohn Snow         }
134290edef80SJohn Snow       }
134390edef80SJohn Snow
134490edef80SJohn Snow    <- { "return": {} }
134590edef80SJohn Snow
134690edef80SJohn Snow#. Receive confirmation that the job completed successfully:
134790edef80SJohn Snow
1348a7786bfbSJohn Snow   .. code-block:: QMP
134990edef80SJohn Snow
135090edef80SJohn Snow    <- {
135190edef80SJohn Snow         "timestamp": {...},
135290edef80SJohn Snow         "data": {
135390edef80SJohn Snow           "device": "drive0",
135490edef80SJohn Snow           "type": "backup",
135590edef80SJohn Snow           "speed": 0,
135690edef80SJohn Snow           "len": 67108864,
135790edef80SJohn Snow           "offset": 67108864
135890edef80SJohn Snow         },
135990edef80SJohn Snow         "event": "BLOCK_JOB_COMPLETED"
136090edef80SJohn Snow       }
136190edef80SJohn Snow
136290edef80SJohn SnowExample: Partial Transactional Failures
136390edef80SJohn Snow~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
136490edef80SJohn Snow
136524d6cc1fSVladimir Sementsov-OgievskiyQMP commands like `blockdev-backup
136624d6cc1fSVladimir Sementsov-Ogievskiy<qemu-qmp-ref.html#index-blockdev_002dbackup>`_
136790edef80SJohn Snowconceptually only start a job, and so transactions containing these commands
136890edef80SJohn Snowmay succeed even if the job it created later fails. This might have surprising
136990edef80SJohn Snowinteractions with notions of how a "transaction" ought to behave.
137090edef80SJohn Snow
137190edef80SJohn SnowThis distinction means that on occasion, a transaction containing such job
137290edef80SJohn Snowlaunching commands may appear to succeed and return success, but later
137390edef80SJohn Snowindividual jobs associated with the transaction may fail. It is possible that
137490edef80SJohn Snowa management application may have to deal with a partial backup failure after
137590edef80SJohn Snowa "successful" transaction.
137690edef80SJohn Snow
137790edef80SJohn SnowIf multiple backup jobs are specified in a single transaction, if one of those
137890edef80SJohn Snowjobs fails, it will not interact with the other backup jobs in any way by
137990edef80SJohn Snowdefault. The job(s) that succeeded will clear the dirty bitmap associated with
138090edef80SJohn Snowthe operation, but the job(s) that failed will not. It is therefore not safe
138190edef80SJohn Snowto delete any incremental backups that were created successfully in this
138290edef80SJohn Snowscenario, even though others failed.
138390edef80SJohn Snow
138490edef80SJohn SnowThis example illustrates a transaction with two backup jobs, where one fails
138590edef80SJohn Snowand one succeeds:
138690edef80SJohn Snow
138790edef80SJohn Snow#. Issue the transaction to start a backup of both drives.
138890edef80SJohn Snow
1389a7786bfbSJohn Snow   .. code-block:: QMP
139090edef80SJohn Snow
139190edef80SJohn Snow    -> {
139290edef80SJohn Snow         "execute": "transaction",
139390edef80SJohn Snow         "arguments": {
139490edef80SJohn Snow           "actions": [
139590edef80SJohn Snow           {
139624d6cc1fSVladimir Sementsov-Ogievskiy             "type": "blockdev-backup",
139790edef80SJohn Snow             "data": {
139890edef80SJohn Snow               "device": "drive0",
139990edef80SJohn Snow               "bitmap": "bitmap0",
140090edef80SJohn Snow               "sync": "incremental",
140124d6cc1fSVladimir Sementsov-Ogievskiy               "target": "target0"
140290edef80SJohn Snow             }
140390edef80SJohn Snow           },
140490edef80SJohn Snow           {
140524d6cc1fSVladimir Sementsov-Ogievskiy             "type": "blockdev-backup",
140690edef80SJohn Snow             "data": {
140790edef80SJohn Snow               "device": "drive1",
140890edef80SJohn Snow               "bitmap": "bitmap0",
140990edef80SJohn Snow               "sync": "incremental",
141024d6cc1fSVladimir Sementsov-Ogievskiy               "target": "target1"
141190edef80SJohn Snow             }
141290edef80SJohn Snow           }]
141390edef80SJohn Snow         }
141490edef80SJohn Snow       }
141590edef80SJohn Snow
141690edef80SJohn Snow#. Receive notice that the Transaction was accepted, and jobs were
14177746cf8aSKashyap Chamarthy   launched:
14187746cf8aSKashyap Chamarthy
1419a7786bfbSJohn Snow   .. code-block:: QMP
14207746cf8aSKashyap Chamarthy
142190edef80SJohn Snow    <- { "return": {} }
14227746cf8aSKashyap Chamarthy
142390edef80SJohn Snow#. Receive notice that the first job has completed:
14247746cf8aSKashyap Chamarthy
1425a7786bfbSJohn Snow   .. code-block:: QMP
14267746cf8aSKashyap Chamarthy
142790edef80SJohn Snow    <- {
142890edef80SJohn Snow         "timestamp": {...},
142990edef80SJohn Snow         "data": {
143090edef80SJohn Snow           "device": "drive0",
143190edef80SJohn Snow           "type": "backup",
143290edef80SJohn Snow           "speed": 0,
143390edef80SJohn Snow           "len": 67108864,
143490edef80SJohn Snow           "offset": 67108864
143590edef80SJohn Snow         },
143690edef80SJohn Snow         "event": "BLOCK_JOB_COMPLETED"
143790edef80SJohn Snow       }
143890edef80SJohn Snow
143990edef80SJohn Snow#. Receive notice that the second job has failed:
14407746cf8aSKashyap Chamarthy
1441a7786bfbSJohn Snow   .. code-block:: QMP
14427746cf8aSKashyap Chamarthy
144390edef80SJohn Snow    <- {
144490edef80SJohn Snow         "timestamp": {...},
144590edef80SJohn Snow         "data": {
144690edef80SJohn Snow           "device": "drive1",
144790edef80SJohn Snow           "action": "report",
144890edef80SJohn Snow           "operation": "read"
144990edef80SJohn Snow         },
145090edef80SJohn Snow         "event": "BLOCK_JOB_ERROR"
145190edef80SJohn Snow       }
145290edef80SJohn Snow
145390edef80SJohn Snow    ...
145490edef80SJohn Snow
145590edef80SJohn Snow    <- {
145690edef80SJohn Snow         "timestamp": {...},
145790edef80SJohn Snow         "data": {
145890edef80SJohn Snow           "speed": 0,
145990edef80SJohn Snow           "offset": 0,
146090edef80SJohn Snow           "len": 67108864,
14617746cf8aSKashyap Chamarthy           "error": "Input/output error",
146290edef80SJohn Snow           "device": "drive1",
146390edef80SJohn Snow           "type": "backup"
146490edef80SJohn Snow         },
146590edef80SJohn Snow         "event": "BLOCK_JOB_COMPLETED"
146690edef80SJohn Snow       }
146790edef80SJohn Snow
146890edef80SJohn SnowAt the conclusion of the above example, ``drive0.inc0.qcow2`` is valid and
146990edef80SJohn Snowmust be kept, but ``drive1.inc0.qcow2`` is incomplete and should be
147090edef80SJohn Snowdeleted. If a VM-wide incremental backup of all drives at a point-in-time is
147190edef80SJohn Snowto be made, new backups for both drives will need to be made, taking into
147290edef80SJohn Snowaccount that a new incremental backup for drive0 needs to be based on top of
147390edef80SJohn Snow``drive0.inc0.qcow2``.
147490edef80SJohn Snow
147590edef80SJohn SnowFor this example, an incremental backup for ``drive0`` was created, but not
147690edef80SJohn Snowfor ``drive1``. The last VM-wide crash-consistent backup that is available in
147790edef80SJohn Snowthis case is the full backup:
147890edef80SJohn Snow
147990edef80SJohn Snow.. code:: text
148090edef80SJohn Snow
148190edef80SJohn Snow          [drive0.full.qcow2] <-- [drive0.inc0.qcow2]
148290edef80SJohn Snow          [drive1.full.qcow2]
148390edef80SJohn Snow
148490edef80SJohn SnowTo repair this, issue a new incremental backup across both drives. The result
148590edef80SJohn Snowwill be backup chains that resemble the following:
148690edef80SJohn Snow
148790edef80SJohn Snow.. code:: text
148890edef80SJohn Snow
148990edef80SJohn Snow          [drive0.full.qcow2] <-- [drive0.inc0.qcow2] <-- [drive0.inc1.qcow2]
149090edef80SJohn Snow          [drive1.full.qcow2] <-------------------------- [drive1.inc1.qcow2]
149190edef80SJohn Snow
149290edef80SJohn SnowExample: Grouped Completion Mode
149390edef80SJohn Snow~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
149490edef80SJohn Snow
149590edef80SJohn SnowWhile jobs launched by transactions normally complete or fail individually,
149690edef80SJohn Snowit's possible to instruct them to complete or fail together as a group. QMP
149790edef80SJohn Snowtransactions take an optional properties structure that can affect the
149890edef80SJohn Snowbehavior of the transaction.
149990edef80SJohn Snow
150090edef80SJohn SnowThe ``completion-mode`` transaction property can be either ``individual``
150190edef80SJohn Snowwhich is the default legacy behavior described above, or ``grouped``, detailed
150290edef80SJohn Snowbelow.
150390edef80SJohn Snow
150490edef80SJohn SnowIn ``grouped`` completion mode, no jobs will report success until all jobs are
150590edef80SJohn Snowready to report success. If any job fails, all other jobs will be cancelled.
150690edef80SJohn Snow
150790edef80SJohn SnowRegardless of if a participating incremental backup job failed or was
150890edef80SJohn Snowcancelled, their associated bitmaps will all be held at their existing
150990edef80SJohn Snowpoints-in-time, as in individual failure cases.
151090edef80SJohn Snow
151190edef80SJohn SnowHere's the same multi-drive backup scenario from `Example: Partial
151290edef80SJohn SnowTransactional Failures`_, but with the ``grouped`` completion-mode property
151390edef80SJohn Snowapplied:
151490edef80SJohn Snow
151590edef80SJohn Snow#. Issue the multi-drive incremental backup transaction:
15167746cf8aSKashyap Chamarthy
1517a7786bfbSJohn Snow   .. code-block:: QMP
15187746cf8aSKashyap Chamarthy
151990edef80SJohn Snow    -> {
152090edef80SJohn Snow         "execute": "transaction",
152190edef80SJohn Snow         "arguments": {
152290edef80SJohn Snow           "properties": {
152390edef80SJohn Snow             "completion-mode": "grouped"
152490edef80SJohn Snow           },
152590edef80SJohn Snow           "actions": [
152690edef80SJohn Snow           {
152724d6cc1fSVladimir Sementsov-Ogievskiy             "type": "blockdev-backup",
152890edef80SJohn Snow             "data": {
152990edef80SJohn Snow               "device": "drive0",
153090edef80SJohn Snow               "bitmap": "bitmap0",
153190edef80SJohn Snow               "sync": "incremental",
153224d6cc1fSVladimir Sementsov-Ogievskiy               "target": "target0"
153390edef80SJohn Snow             }
153490edef80SJohn Snow           },
153590edef80SJohn Snow           {
153624d6cc1fSVladimir Sementsov-Ogievskiy             "type": "blockdev-backup",
153790edef80SJohn Snow             "data": {
153890edef80SJohn Snow               "device": "drive1",
153990edef80SJohn Snow               "bitmap": "bitmap0",
154090edef80SJohn Snow               "sync": "incremental",
154124d6cc1fSVladimir Sementsov-Ogievskiy               "target": "target1"
154290edef80SJohn Snow             }
154390edef80SJohn Snow           }]
154490edef80SJohn Snow         }
154590edef80SJohn Snow       }
154690edef80SJohn Snow
154790edef80SJohn Snow#. Receive notice that the Transaction was accepted, and jobs were launched:
154890edef80SJohn Snow
1549a7786bfbSJohn Snow   .. code-block:: QMP
155090edef80SJohn Snow
155190edef80SJohn Snow    <- { "return": {} }
155290edef80SJohn Snow
155390edef80SJohn Snow#. Receive notification that the backup job for ``drive1`` has failed:
155490edef80SJohn Snow
1555a7786bfbSJohn Snow   .. code-block:: QMP
155690edef80SJohn Snow
155790edef80SJohn Snow    <- {
155890edef80SJohn Snow         "timestamp": {...},
155990edef80SJohn Snow         "data": {
156090edef80SJohn Snow           "device": "drive1",
156190edef80SJohn Snow           "action": "report",
156290edef80SJohn Snow           "operation": "read"
156390edef80SJohn Snow         },
156490edef80SJohn Snow         "event": "BLOCK_JOB_ERROR"
156590edef80SJohn Snow       }
156690edef80SJohn Snow
156790edef80SJohn Snow    <- {
156890edef80SJohn Snow         "timestamp": {...},
156990edef80SJohn Snow         "data": {
157090edef80SJohn Snow           "speed": 0,
157190edef80SJohn Snow           "offset": 0,
157290edef80SJohn Snow           "len": 67108864,
157390edef80SJohn Snow           "error": "Input/output error",
157490edef80SJohn Snow           "device": "drive1",
157590edef80SJohn Snow           "type": "backup"
157690edef80SJohn Snow         },
157790edef80SJohn Snow         "event": "BLOCK_JOB_COMPLETED"
157890edef80SJohn Snow       }
157990edef80SJohn Snow
158090edef80SJohn Snow#. Receive notification that the job for ``drive0`` has been cancelled:
158190edef80SJohn Snow
1582a7786bfbSJohn Snow   .. code-block:: QMP
158390edef80SJohn Snow
158490edef80SJohn Snow    <- {
1585575e6226SJohn Snow         "timestamp": {...},
158690edef80SJohn Snow         "data": {
158790edef80SJohn Snow           "device": "drive0",
158890edef80SJohn Snow           "type": "backup",
158990edef80SJohn Snow           "speed": 0,
159090edef80SJohn Snow           "len": 67108864,
159190edef80SJohn Snow           "offset": 16777216
159290edef80SJohn Snow         },
159390edef80SJohn Snow         "event": "BLOCK_JOB_CANCELLED"
159490edef80SJohn Snow       }
159590edef80SJohn Snow
159690edef80SJohn SnowAt the conclusion of *this* example, both jobs have been aborted due to a
159790edef80SJohn Snowfailure. Both destination images should be deleted and are no longer of use.
159890edef80SJohn Snow
159990edef80SJohn SnowThe transaction as a whole can simply be re-issued at a later time.
16007746cf8aSKashyap Chamarthy
16017746cf8aSKashyap Chamarthy.. raw:: html
16027746cf8aSKashyap Chamarthy
16037746cf8aSKashyap Chamarthy   <!--
16047746cf8aSKashyap Chamarthy   The FreeBSD Documentation License
16057746cf8aSKashyap Chamarthy
160690edef80SJohn Snow   Redistribution and use in source (ReST) and 'compiled' forms (SGML, HTML,
160790edef80SJohn Snow   PDF, PostScript, RTF and so forth) with or without modification, are
160890edef80SJohn Snow   permitted provided that the following conditions are met:
16097746cf8aSKashyap Chamarthy
161090edef80SJohn Snow   Redistributions of source code (ReST) must retain the above copyright notice,
161190edef80SJohn Snow   this list of conditions and the following disclaimer of this file unmodified.
16127746cf8aSKashyap Chamarthy
161390edef80SJohn Snow   Redistributions in compiled form (transformed to other DTDs, converted to
161490edef80SJohn Snow   PDF, PostScript, RTF and other formats) must reproduce the above copyright
161590edef80SJohn Snow   notice, this list of conditions and the following disclaimer in the
161690edef80SJohn Snow   documentation and/or other materials provided with the distribution.
16177746cf8aSKashyap Chamarthy
161890edef80SJohn Snow   THIS DOCUMENTATION IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
161990edef80SJohn Snow   IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
162090edef80SJohn Snow   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
162190edef80SJohn Snow   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
162290edef80SJohn Snow   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
162390edef80SJohn Snow   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
162490edef80SJohn Snow   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
162590edef80SJohn Snow   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
162690edef80SJohn Snow   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
162790edef80SJohn Snow   ARISING IN ANY WAY OUT OF THE USE OF THIS DOCUMENTATION, EVEN IF ADVISED OF
162890edef80SJohn Snow   THE POSSIBILITY OF SUCH DAMAGE.
16297746cf8aSKashyap Chamarthy   -->
1630