[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-block] [Qemu-devel] [PATCH v4 2/2] bitmaps.md: Convert to rST;
From: |
John Snow |
Subject: |
Re: [Qemu-block] [Qemu-devel] [PATCH v4 2/2] bitmaps.md: Convert to rST; move it into 'interop' dir |
Date: |
Thu, 29 Jun 2017 17:20:43 -0400 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.2.0 |
On 06/28/2017 10:58 AM, Kashyap Chamarthy wrote:
> This is part of the on-going effort to convert QEMU upstream
> documentation syntax to reStructuredText (rST).
>
> The conversion to rST was done using:
>
> $ pandoc -f markdown -t rst bitmaps.md -o bitmaps.rst
>
> Then, make a couple of small syntactical adjustments. While at it,
> reword a statement to avoid ambiguity. Addressing the feedback from
> this thread:
>
> https://lists.nongnu.org/archive/html/qemu-devel/2017-06/msg05428.html
>
> Signed-off-by: Kashyap Chamarthy <address@hidden>
Reviewed-by: John Snow <address@hidden>
> ---
> * A Sphinx-rendered HTML version is here:
> https://kashyapc.fedorapeople.org/v4-QEMU-Docs/_build/html/docs/bitmaps.html
>
> * The patch has "v4" subject prefix because I rolled this in along with
> the other document (live-block-operations.rst) that is in review,
> which is actually at v4.
> ---
> docs/devel/bitmaps.md | 505 ------------------------------------------
> docs/interop/bitmaps.rst | 555
> +++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 555 insertions(+), 505 deletions(-)
> delete mode 100644 docs/devel/bitmaps.md
> create mode 100644 docs/interop/bitmaps.rst
>
> diff --git a/docs/devel/bitmaps.md b/docs/devel/bitmaps.md
> deleted file mode 100644
> index a2e8d51..0000000
> --- a/docs/devel/bitmaps.md
> +++ /dev/null
> @@ -1,505 +0,0 @@
> -<!--
> -Copyright 2015 John Snow <address@hidden> and Red Hat, Inc.
> -All rights reserved.
> -
> -This file is licensed via The FreeBSD Documentation License, the full text of
> -which is included at the end of this document.
> --->
> -
> -# Dirty Bitmaps and Incremental Backup
> -
> -* Dirty Bitmaps are objects that track which data needs to be backed up for
> the
> - next incremental backup.
> -
> -* Dirty bitmaps can be created at any time and attached to any node
> - (not just complete drives.)
> -
> -## Dirty Bitmap Names
> -
> -* A dirty bitmap's name is unique to the node, but bitmaps attached to
> different
> - nodes can share the same name.
> -
> -* Dirty bitmaps created for internal use by QEMU may be anonymous and have no
> - name, but any user-created bitmaps may not be. There can be any number of
> - anonymous bitmaps per node.
> -
> -* The name of a user-created bitmap must not be empty ("").
> -
> -## Bitmap Modes
> -
> -* A Bitmap can be "frozen," which means that it is currently in-use by a
> backup
> - operation and cannot be deleted, renamed, written to, reset,
> - etc.
> -
> -* The normal operating mode for a bitmap is "active."
> -
> -## Basic QMP Usage
> -
> -### Supported Commands ###
> -
> -* block-dirty-bitmap-add
> -* block-dirty-bitmap-remove
> -* block-dirty-bitmap-clear
> -
> -### Creation
> -
> -* To create a new bitmap, enabled, on the drive with id=drive0:
> -
> -```json
> -{ "execute": "block-dirty-bitmap-add",
> - "arguments": {
> - "node": "drive0",
> - "name": "bitmap0"
> - }
> -}
> -```
> -
> -* This bitmap will have a default granularity that matches the cluster size
> of
> - its associated drive, if available, clamped to between [4KiB, 64KiB].
> - The current default for qcow2 is 64KiB.
> -
> -* To create a new bitmap that tracks changes in 32KiB segments:
> -
> -```json
> -{ "execute": "block-dirty-bitmap-add",
> - "arguments": {
> - "node": "drive0",
> - "name": "bitmap0",
> - "granularity": 32768
> - }
> -}
> -```
> -
> -### Deletion
> -
> -* Bitmaps that are frozen cannot be deleted.
> -
> -* Deleting the bitmap does not impact any other bitmaps attached to the same
> - node, nor does it affect any backups already created from this node.
> -
> -* Because bitmaps are only unique to the node to which they are attached,
> - you must specify the node/drive name here, too.
> -
> -```json
> -{ "execute": "block-dirty-bitmap-remove",
> - "arguments": {
> - "node": "drive0",
> - "name": "bitmap0"
> - }
> -}
> -```
> -
> -### Resetting
> -
> -* Resetting a bitmap will clear all information it holds.
> -
> -* An incremental backup created from an empty bitmap will copy no data,
> - as if nothing has changed.
> -
> -```json
> -{ "execute": "block-dirty-bitmap-clear",
> - "arguments": {
> - "node": "drive0",
> - "name": "bitmap0"
> - }
> -}
> -```
> -
> -## Transactions
> -
> -### Justification
> -
> -Bitmaps can be safely modified when the VM is paused or halted by using
> -the basic QMP commands. For instance, you might perform the following
> actions:
> -
> -1. Boot the VM in a paused state.
> -2. Create a full drive backup of drive0.
> -3. Create a new bitmap attached to drive0.
> -4. Resume execution of the VM.
> -5. Incremental backups are ready to be created.
> -
> -At this point, the bitmap and drive backup would be correctly in sync,
> -and incremental backups made from this point forward would be correctly
> aligned
> -to the full drive backup.
> -
> -This is not particularly useful if we decide we want to start incremental
> -backups after the VM has been running for a while, for which we will need to
> -perform actions such as the following:
> -
> -1. Boot the VM and begin execution.
> -2. Using a single transaction, perform the following operations:
> - * Create bitmap0.
> - * Create a full drive backup of drive0.
> -3. Incremental backups are now ready to be created.
> -
> -### Supported Bitmap Transactions
> -
> -* block-dirty-bitmap-add
> -* block-dirty-bitmap-clear
> -
> -The usages are identical to their respective QMP commands, but see below
> -for examples.
> -
> -### Example: New Incremental Backup
> -
> -As outlined in the justification, perhaps we want to create a new incremental
> -backup chain attached to a drive.
> -
> -```json
> -{ "execute": "transaction",
> - "arguments": {
> - "actions": [
> - {"type": "block-dirty-bitmap-add",
> - "data": {"node": "drive0", "name": "bitmap0"} },
> - {"type": "drive-backup",
> - "data": {"device": "drive0", "target": "/path/to/full_backup.img",
> - "sync": "full", "format": "qcow2"} }
> - ]
> - }
> -}
> -```
> -
> -### Example: New Incremental Backup Anchor Point
> -
> -Maybe we just want to create a new full backup with an existing bitmap and
> -want to reset the bitmap to track the new chain.
> -
> -```json
> -{ "execute": "transaction",
> - "arguments": {
> - "actions": [
> - {"type": "block-dirty-bitmap-clear",
> - "data": {"node": "drive0", "name": "bitmap0"} },
> - {"type": "drive-backup",
> - "data": {"device": "drive0", "target": "/path/to/new_full_backup.img",
> - "sync": "full", "format": "qcow2"} }
> - ]
> - }
> -}
> -```
> -
> -## Incremental Backups
> -
> -The star of the show.
> -
> -**Nota Bene!** Only incremental backups of entire drives are supported for
> now.
> -So despite the fact that you can attach a bitmap to any arbitrary node, they
> are
> -only currently useful when attached to the root node. This is because
> -drive-backup only supports drives/devices instead of arbitrary nodes.
> -
> -### Example: First Incremental Backup
> -
> -1. Create a full backup and sync it to the dirty bitmap, as in the
> transactional
> -examples above; or with the VM offline, manually create a full copy and then
> -create a new bitmap before the VM begins execution.
> -
> - * Let's assume the full backup is named 'full_backup.img'.
> - * Let's assume the bitmap you created is 'bitmap0' attached to 'drive0'.
> -
> -2. Create a destination image for the incremental backup that utilizes the
> -full backup as a backing image.
> -
> - * Let's assume it is named 'incremental.0.img'.
> -
> - ```sh
> - # qemu-img create -f qcow2 incremental.0.img -b full_backup.img -F qcow2
> - ```
> -
> -3. Issue the incremental backup command:
> -
> - ```json
> - { "execute": "drive-backup",
> - "arguments": {
> - "device": "drive0",
> - "bitmap": "bitmap0",
> - "target": "incremental.0.img",
> - "format": "qcow2",
> - "sync": "incremental",
> - "mode": "existing"
> - }
> - }
> - ```
> -
> -### Example: Second Incremental Backup
> -
> -1. Create a new destination image for the incremental backup that points to
> the
> - previous one, e.g.: 'incremental.1.img'
> -
> - ```sh
> - # qemu-img create -f qcow2 incremental.1.img -b incremental.0.img -F
> qcow2
> - ```
> -
> -2. Issue a new incremental backup command. The only difference here is that
> we
> - have changed the target image below.
> -
> - ```json
> - { "execute": "drive-backup",
> - "arguments": {
> - "device": "drive0",
> - "bitmap": "bitmap0",
> - "target": "incremental.1.img",
> - "format": "qcow2",
> - "sync": "incremental",
> - "mode": "existing"
> - }
> - }
> - ```
> -
> -## Errors
> -
> -* In the event of an error that occurs after a backup job is successfully
> - launched, either by a direct QMP command or a QMP transaction, the user
> - will receive a BLOCK_JOB_COMPLETE event with a failure message, accompanied
> - by a BLOCK_JOB_ERROR event.
> -
> -* In the case of an event being cancelled, the user will receive a
> - BLOCK_JOB_CANCELLED event instead of a pair of COMPLETE and ERROR events.
> -
> -* In either case, the incremental backup data contained within the bitmap is
> - safely rolled back, and the data within the bitmap is not lost. The image
> - file created for the failed attempt can be safely deleted.
> -
> -* Once the underlying problem is fixed (e.g. more storage space is freed up),
> - you can simply retry the incremental backup command with the same bitmap.
> -
> -### Example
> -
> -1. Create a target image:
> -
> - ```sh
> - # qemu-img create -f qcow2 incremental.0.img -b full_backup.img -F qcow2
> - ```
> -
> -2. Attempt to create an incremental backup via QMP:
> -
> - ```json
> - { "execute": "drive-backup",
> - "arguments": {
> - "device": "drive0",
> - "bitmap": "bitmap0",
> - "target": "incremental.0.img",
> - "format": "qcow2",
> - "sync": "incremental",
> - "mode": "existing"
> - }
> - }
> - ```
> -
> -3. Receive an event notifying us of failure:
> -
> - ```json
> - { "timestamp": { "seconds": 1424709442, "microseconds": 844524 },
> - "data": { "speed": 0, "offset": 0, "len": 67108864,
> - "error": "No space left on device",
> - "device": "drive1", "type": "backup" },
> - "event": "BLOCK_JOB_COMPLETED" }
> - ```
> -
> -4. Delete the failed incremental, and re-create the image.
> -
> - ```sh
> - # rm incremental.0.img
> - # qemu-img create -f qcow2 incremental.0.img -b full_backup.img -F qcow2
> - ```
> -
> -5. Retry the command after fixing the underlying problem,
> - such as freeing up space on the backup volume:
> -
> - ```json
> - { "execute": "drive-backup",
> - "arguments": {
> - "device": "drive0",
> - "bitmap": "bitmap0",
> - "target": "incremental.0.img",
> - "format": "qcow2",
> - "sync": "incremental",
> - "mode": "existing"
> - }
> - }
> - ```
> -
> -6. Receive confirmation that the job completed successfully:
> -
> - ```json
> - { "timestamp": { "seconds": 1424709668, "microseconds": 526525 },
> - "data": { "device": "drive1", "type": "backup",
> - "speed": 0, "len": 67108864, "offset": 67108864},
> - "event": "BLOCK_JOB_COMPLETED" }
> - ```
> -
> -### Partial Transactional Failures
> -
> -* Sometimes, a transaction will succeed in launching and return success,
> - but then later the backup jobs themselves may fail. It is possible that
> - a management application may have to deal with a partial backup failure
> - after a successful transaction.
> -
> -* If multiple backup jobs are specified in a single transaction, when one of
> - them fails, it will not interact with the other backup jobs in any way.
> -
> -* The job(s) that succeeded will clear the dirty bitmap associated with the
> - operation, but the job(s) that failed will not. It is not "safe" to delete
> - any incremental backups that were created successfully in this scenario,
> - even though others failed.
> -
> -#### Example
> -
> -* QMP example highlighting two backup jobs:
> -
> - ```json
> - { "execute": "transaction",
> - "arguments": {
> - "actions": [
> - { "type": "drive-backup",
> - "data": { "device": "drive0", "bitmap": "bitmap0",
> - "format": "qcow2", "mode": "existing",
> - "sync": "incremental", "target": "d0-incr-1.qcow2" } },
> - { "type": "drive-backup",
> - "data": { "device": "drive1", "bitmap": "bitmap1",
> - "format": "qcow2", "mode": "existing",
> - "sync": "incremental", "target": "d1-incr-1.qcow2" } },
> - ]
> - }
> - }
> - ```
> -
> -* QMP example response, highlighting one success and one failure:
> - * Acknowledgement that the Transaction was accepted and jobs were
> launched:
> - ```json
> - { "return": {} }
> - ```
> -
> - * Later, QEMU sends notice that the first job was completed:
> - ```json
> - { "timestamp": { "seconds": 1447192343, "microseconds": 615698 },
> - "data": { "device": "drive0", "type": "backup",
> - "speed": 0, "len": 67108864, "offset": 67108864 },
> - "event": "BLOCK_JOB_COMPLETED"
> - }
> - ```
> -
> - * Later yet, QEMU sends notice that the second job has failed:
> - ```json
> - { "timestamp": { "seconds": 1447192399, "microseconds": 683015 },
> - "data": { "device": "drive1", "action": "report",
> - "operation": "read" },
> - "event": "BLOCK_JOB_ERROR" }
> - ```
> -
> - ```json
> - { "timestamp": { "seconds": 1447192399, "microseconds": 685853 },
> - "data": { "speed": 0, "offset": 0, "len": 67108864,
> - "error": "Input/output error",
> - "device": "drive1", "type": "backup" },
> - "event": "BLOCK_JOB_COMPLETED" }
> -
> -* In the above example, "d0-incr-1.qcow2" is valid and must be kept,
> - but "d1-incr-1.qcow2" is invalid and should be deleted. If a VM-wide
> - incremental backup of all drives at a point-in-time is to be made,
> - new backups for both drives will need to be made, taking into account
> - that a new incremental backup for drive0 needs to be based on top of
> - "d0-incr-1.qcow2."
> -
> -### Grouped Completion Mode
> -
> -* While jobs launched by transactions normally complete or fail on their own,
> - it is possible to instruct them to complete or fail together as a group.
> -
> -* QMP transactions take an optional properties structure that can affect
> - the semantics of the transaction.
> -
> -* The "completion-mode" transaction property can be either "individual"
> - which is the default, legacy behavior described above, or "grouped,"
> - a new behavior detailed below.
> -
> -* Delayed Completion: In grouped completion mode, no jobs will report
> - success until all jobs are ready to report success.
> -
> -* Grouped failure: If any job fails in grouped completion mode, all remaining
> - jobs will be cancelled. Any incremental backups will restore their dirty
> - bitmap objects as if no backup command was ever issued.
> -
> - * Regardless of if QEMU reports a particular incremental backup job as
> - CANCELLED or as an ERROR, the in-memory bitmap will be restored.
> -
> -#### Example
> -
> -* Here's the same example scenario from above with the new property:
> -
> - ```json
> - { "execute": "transaction",
> - "arguments": {
> - "actions": [
> - { "type": "drive-backup",
> - "data": { "device": "drive0", "bitmap": "bitmap0",
> - "format": "qcow2", "mode": "existing",
> - "sync": "incremental", "target": "d0-incr-1.qcow2" } },
> - { "type": "drive-backup",
> - "data": { "device": "drive1", "bitmap": "bitmap1",
> - "format": "qcow2", "mode": "existing",
> - "sync": "incremental", "target": "d1-incr-1.qcow2" } },
> - ],
> - "properties": {
> - "completion-mode": "grouped"
> - }
> - }
> - }
> - ```
> -
> -* QMP example response, highlighting a failure for drive2:
> - * Acknowledgement that the Transaction was accepted and jobs were
> launched:
> - ```json
> - { "return": {} }
> - ```
> -
> - * Later, QEMU sends notice that the second job has errored out,
> - but that the first job was also cancelled:
> - ```json
> - { "timestamp": { "seconds": 1447193702, "microseconds": 632377 },
> - "data": { "device": "drive1", "action": "report",
> - "operation": "read" },
> - "event": "BLOCK_JOB_ERROR" }
> - ```
> -
> - ```json
> - { "timestamp": { "seconds": 1447193702, "microseconds": 640074 },
> - "data": { "speed": 0, "offset": 0, "len": 67108864,
> - "error": "Input/output error",
> - "device": "drive1", "type": "backup" },
> - "event": "BLOCK_JOB_COMPLETED" }
> - ```
> -
> - ```json
> - { "timestamp": { "seconds": 1447193702, "microseconds": 640163 },
> - "data": { "device": "drive0", "type": "backup", "speed": 0,
> - "len": 67108864, "offset": 16777216 },
> - "event": "BLOCK_JOB_CANCELLED" }
> - ```
> -
> -<!--
> -The FreeBSD Documentation License
> -
> -Redistribution and use in source (Markdown) and 'compiled' forms (SGML, HTML,
> -PDF, PostScript, RTF and so forth) with or without modification, are
> permitted
> -provided that the following conditions are met:
> -
> -Redistributions of source code (Markdown) must retain the above copyright
> -notice, this list of conditions and the following disclaimer of this file
> -unmodified.
> -
> -Redistributions in compiled form (transformed to other DTDs, converted to
> PDF,
> -PostScript, RTF and other formats) must reproduce the above copyright notice,
> -this list of conditions and the following disclaimer in the documentation
> and/or
> -other materials provided with the distribution.
> -
> -THIS DOCUMENTATION IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
> IS"
> -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> ARE
> -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
> -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
> -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
> -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
> -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
> -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
> USE OF
> -THIS DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> --->
> diff --git a/docs/interop/bitmaps.rst b/docs/interop/bitmaps.rst
> new file mode 100644
> index 0000000..b154d54
> --- /dev/null
> +++ b/docs/interop/bitmaps.rst
> @@ -0,0 +1,555 @@
> +..
> + Copyright 2015 John Snow <address@hidden> and Red Hat, Inc.
> + All rights reserved.
> +
> + This file is licensed via The FreeBSD Documentation License, the full
> + text of which is included at the end of this document.
> +
> +====================================
> +Dirty Bitmaps and Incremental Backup
> +====================================
> +
> +- Dirty Bitmaps are objects that track which data needs to be backed up
> + for the next incremental backup.
> +
> +- Dirty bitmaps can be created at any time and attached to any node
> + (not just complete drives.)
> +
> +.. contents::
> +
> +Dirty Bitmap Names
> +------------------
> +
> +- A dirty bitmap's name is unique to the node, but bitmaps attached to
> + different nodes can share the same name.
> +
> +- Dirty bitmaps created for internal use by QEMU may be anonymous and
> + have no name, but any user-created bitmaps may not be. There can be
> + any number of anonymous bitmaps per node.
> +
> +- The name of a user-created bitmap must not be empty ("").
> +
> +Bitmap Modes
> +------------
> +
> +- A bitmap can be "frozen," which means that it is currently in-use by
> + a backup operation and cannot be deleted, renamed, written to, reset,
> + etc.
> +
> +- The normal operating mode for a bitmap is "active."
> +
> +Basic QMP Usage
> +---------------
> +
> +Supported Commands
> +~~~~~~~~~~~~~~~~~~
> +
> +- ``block-dirty-bitmap-add``
> +- ``block-dirty-bitmap-remove``
> +- ``block-dirty-bitmap-clear``
> +
> +Creation
> +~~~~~~~~
> +
> +- To create a new bitmap, enabled, on the drive with id=drive0:
> +
> +.. code:: json
> +
> + { "execute": "block-dirty-bitmap-add",
> + "arguments": {
> + "node": "drive0",
> + "name": "bitmap0"
> + }
> + }
> +
> +- This bitmap will have a default granularity that matches the cluster
> + size of its associated drive, if available, clamped to between [4KiB,
> + 64KiB]. The current default for qcow2 is 64KiB.
> +
> +- To create a new bitmap that tracks changes in 32KiB segments:
> +
> +.. code:: json
> +
> + { "execute": "block-dirty-bitmap-add",
> + "arguments": {
> + "node": "drive0",
> + "name": "bitmap0",
> + "granularity": 32768
> + }
> + }
> +
> +Deletion
> +~~~~~~~~
> +
> +- Bitmaps that are frozen cannot be deleted.
> +
> +- Deleting the bitmap does not impact any other bitmaps attached to the
> + same node, nor does it affect any backups already created from this
> + node.
> +
> +- Because bitmaps are only unique to the node to which they are
> + attached, you must specify the node/drive name here, too.
> +
> +.. code:: json
> +
> + { "execute": "block-dirty-bitmap-remove",
> + "arguments": {
> + "node": "drive0",
> + "name": "bitmap0"
> + }
> + }
> +
> +Resetting
> +~~~~~~~~~
> +
> +- Resetting a bitmap will clear all information it holds.
> +
> +- An incremental backup created from an empty bitmap will copy no data,
> + as if nothing has changed.
> +
> +.. code:: json
> +
> + { "execute": "block-dirty-bitmap-clear",
> + "arguments": {
> + "node": "drive0",
> + "name": "bitmap0"
> + }
> + }
> +
> +Transactions
> +------------
> +
> +Justification
> +~~~~~~~~~~~~~
> +
> +Bitmaps can be safely modified when the VM is paused or halted by using
> +the basic QMP commands. For instance, you might perform the following
> +actions:
> +
> +1. Boot the VM in a paused state.
> +2. Create a full drive backup of drive0.
> +3. Create a new bitmap attached to drive0.
> +4. Resume execution of the VM.
> +5. Incremental backups are ready to be created.
> +
> +At this point, the bitmap and drive backup would be correctly in sync,
> +and incremental backups made from this point forward would be correctly
> +aligned to the full drive backup.
> +
> +This is not particularly useful if we decide we want to start
> +incremental backups after the VM has been running for a while, for which
> +we will need to perform actions such as the following:
> +
> +1. Boot the VM and begin execution.
> +2. Using a single transaction, perform the following operations:
> +
> + - Create ``bitmap0``.
> + - Create a full drive backup of ``drive0``.
> +
> +3. Incremental backups are now ready to be created.
> +
> +Supported Bitmap Transactions
> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +- ``block-dirty-bitmap-add``
> +- ``block-dirty-bitmap-clear``
> +
> +The usages are identical to their respective QMP commands, but see below
> +for examples.
> +
> +Example: New Incremental Backup
> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +As outlined in the justification, perhaps we want to create a new
> +incremental backup chain attached to a drive.
> +
> +.. code:: json
> +
> + { "execute": "transaction",
> + "arguments": {
> + "actions": [
> + {"type": "block-dirty-bitmap-add",
> + "data": {"node": "drive0", "name": "bitmap0"} },
> + {"type": "drive-backup",
> + "data": {"device": "drive0", "target": "/path/to/full_backup.img",
> + "sync": "full", "format": "qcow2"} }
> + ]
> + }
> + }
> +
> +Example: New Incremental Backup Anchor Point
> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +Maybe we just want to create a new full backup with an existing bitmap
> +and want to reset the bitmap to track the new chain.
> +
> +.. code:: json
> +
> + { "execute": "transaction",
> + "arguments": {
> + "actions": [
> + {"type": "block-dirty-bitmap-clear",
> + "data": {"node": "drive0", "name": "bitmap0"} },
> + {"type": "drive-backup",
> + "data": {"device": "drive0", "target":
> "/path/to/new_full_backup.img",
> + "sync": "full", "format": "qcow2"} }
> + ]
> + }
> + }
> +
> +Incremental Backups
> +-------------------
> +
> +The star of the show.
> +
> +**Nota Bene!** Only incremental backups of entire drives are supported
> +for now. So despite the fact that you can attach a bitmap to any
> +arbitrary node, they are only currently useful when attached to the root
> +node. This is because drive-backup only supports drives/devices instead
> +of arbitrary nodes.
> +
> +Example: First Incremental Backup
> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +1. Create a full backup and sync it to the dirty bitmap, as in the
> + transactional examples above; or with the VM offline, manually create
> + a full copy and then create a new bitmap before the VM begins
> + execution.
> +
> + - Let's assume the full backup is named ``full_backup.img``.
> + - Let's assume the bitmap you created is ``bitmap0`` attached to
> + ``drive0``.
> +
> +2. Create a destination image for the incremental backup that utilizes
> + the full backup as a backing image.
> +
> + - Let's assume the new incremental image is named
> + ``incremental.0.img``.
> +
> + .. code:: bash
> +
> + $ qemu-img create -f qcow2 incremental.0.img -b full_backup.img -F
> qcow2
> +
> +3. Issue the incremental backup command:
> +
> + .. code:: json
> +
> + { "execute": "drive-backup",
> + "arguments": {
> + "device": "drive0",
> + "bitmap": "bitmap0",
> + "target": "incremental.0.img",
> + "format": "qcow2",
> + "sync": "incremental",
> + "mode": "existing"
> + }
> + }
> +
> +Example: Second Incremental Backup
> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +1. Create a new destination image for the incremental backup that points
> + to the previous one, e.g.: ``incremental.1.img``
> +
> + .. code:: bash
> +
> + $ qemu-img create -f qcow2 incremental.1.img -b incremental.0.img -F
> qcow2
> +
> +2. Issue a new incremental backup command. The only difference here is
> + that we have changed the target image below.
> +
> + .. code:: json
> +
> + { "execute": "drive-backup",
> + "arguments": {
> + "device": "drive0",
> + "bitmap": "bitmap0",
> + "target": "incremental.1.img",
> + "format": "qcow2",
> + "sync": "incremental",
> + "mode": "existing"
> + }
> + }
> +
> +Errors
> +------
> +
> +- In the event of an error that occurs after a backup job is
> + successfully launched, either by a direct QMP command or a QMP
> + transaction, the user will receive a ``BLOCK_JOB_COMPLETE`` event with
> + a failure message, accompanied by a ``BLOCK_JOB_ERROR`` event.
> +
> +- In the case of an event being cancelled, the user will receive a
> + ``BLOCK_JOB_CANCELLED`` event instead of a pair of COMPLETE and ERROR
> + events.
> +
> +- In either case, the incremental backup data contained within the
> + bitmap is safely rolled back, and the data within the bitmap is not
> + lost. The image file created for the failed attempt can be safely
> + deleted.
> +
> +- Once the underlying problem is fixed (e.g. more storage space is
> + freed up), you can simply retry the incremental backup command with
> + the same bitmap.
> +
> +Example
> +~~~~~~~
> +
> +1. Create a target image:
> +
> + .. code:: bash
> +
> + $ qemu-img create -f qcow2 incremental.0.img -b full_backup.img -F
> qcow2
> +
> +2. Attempt to create an incremental backup via QMP:
> +
> + .. code:: json
> +
> + { "execute": "drive-backup",
> + "arguments": {
> + "device": "drive0",
> + "bitmap": "bitmap0",
> + "target": "incremental.0.img",
> + "format": "qcow2",
> + "sync": "incremental",
> + "mode": "existing"
> + }
> + }
> +
> +3. Receive an event notifying us of failure:
> +
> + .. code:: json
> +
> + { "timestamp": { "seconds": 1424709442, "microseconds": 844524 },
> + "data": { "speed": 0, "offset": 0, "len": 67108864,
> + "error": "No space left on device",
> + "device": "drive1", "type": "backup" },
> + "event": "BLOCK_JOB_COMPLETED" }
> +
> +4. Delete the failed incremental, and re-create the image.
> +
> + .. code:: bash
> +
> + $ rm incremental.0.img
> + $ qemu-img create -f qcow2 incremental.0.img -b full_backup.img -F
> qcow2
> +
> +5. Retry the command after fixing the underlying problem, such as
> + freeing up space on the backup volume:
> +
> + .. code:: json
> +
> + { "execute": "drive-backup",
> + "arguments": {
> + "device": "drive0",
> + "bitmap": "bitmap0",
> + "target": "incremental.0.img",
> + "format": "qcow2",
> + "sync": "incremental",
> + "mode": "existing"
> + }
> + }
> +
> +6. Receive confirmation that the job completed successfully:
> +
> + .. code:: json
> +
> + { "timestamp": { "seconds": 1424709668, "microseconds": 526525 },
> + "data": { "device": "drive1", "type": "backup",
> + "speed": 0, "len": 67108864, "offset": 67108864},
> + "event": "BLOCK_JOB_COMPLETED" }
> +
> +Partial Transactional Failures
> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +- Sometimes, a transaction will succeed in launching and return
> + success, but then later the backup jobs themselves may fail. It is
> + possible that a management application may have to deal with a
> + partial backup failure after a successful transaction.
> +
> +- If multiple backup jobs are specified in a single transaction, when
> + one of them fails, it will not interact with the other backup jobs in
> + any way.
> +
> +- The job(s) that succeeded will clear the dirty bitmap associated with
> + the operation, but the job(s) that failed will not. It is not "safe"
> + to delete any incremental backups that were created successfully in
> + this scenario, even though others failed.
> +
> +Example
> +^^^^^^^
> +
> +- QMP example highlighting two backup jobs:
> +
> + .. code:: json
> +
> + { "execute": "transaction",
> + "arguments": {
> + "actions": [
> + { "type": "drive-backup",
> + "data": { "device": "drive0", "bitmap": "bitmap0",
> + "format": "qcow2", "mode": "existing",
> + "sync": "incremental", "target": "d0-incr-1.qcow2"
> } },
> + { "type": "drive-backup",
> + "data": { "device": "drive1", "bitmap": "bitmap1",
> + "format": "qcow2", "mode": "existing",
> + "sync": "incremental", "target": "d1-incr-1.qcow2"
> } },
> + ]
> + }
> + }
> +
> +- QMP example response, highlighting one success and one failure:
> +
> + - Acknowledgement that the Transaction was accepted and jobs were
> + launched:
> +
> + .. code:: json
> +
> + { "return": {} }
> +
> + - Later, QEMU sends notice that the first job was completed:
> +
> + .. code:: json
> +
> + { "timestamp": { "seconds": 1447192343, "microseconds": 615698 },
> + "data": { "device": "drive0", "type": "backup",
> + "speed": 0, "len": 67108864, "offset": 67108864 },
> + "event": "BLOCK_JOB_COMPLETED"
> + }
> +
> + - Later yet, QEMU sends notice that the second job has failed:
> +
> + .. code:: json
> +
> + { "timestamp": { "seconds": 1447192399, "microseconds": 683015 },
> + "data": { "device": "drive1", "action": "report",
> + "operation": "read" },
> + "event": "BLOCK_JOB_ERROR" }
> +
> + .. code:: json
> +
> + { "timestamp": { "seconds": 1447192399, "microseconds":
> + 685853 }, "data": { "speed": 0, "offset": 0, "len": 67108864,
> + "error": "Input/output error", "device": "drive1", "type":
> + "backup" }, "event": "BLOCK_JOB_COMPLETED" }
> +
> +- In the above example, ``d0-incr-1.qcow2`` is valid and must be kept,
> + but ``d1-incr-1.qcow2`` is invalid and should be deleted. If a VM-wide
> + incremental backup of all drives at a point-in-time is to be made,
> + new backups for both drives will need to be made, taking into account
> + that a new incremental backup for drive0 needs to be based on top of
> + ``d0-incr-1.qcow2``.
> +
> +Grouped Completion Mode
> +~~~~~~~~~~~~~~~~~~~~~~~
> +
> +- While jobs launched by transactions normally complete or fail on
> + their own, it is possible to instruct them to complete or fail
> + together as a group.
> +
> +- QMP transactions take an optional properties structure that can
> + affect the semantics of the transaction.
> +
> +- The "completion-mode" transaction property can be either "individual"
> + which is the default, legacy behavior described above, or "grouped,"
> + a new behavior detailed below.
> +
> +- Delayed Completion: In grouped completion mode, no jobs will report
> + success until all jobs are ready to report success.
> +
> +- Grouped failure: If any job fails in grouped completion mode, all
> + remaining jobs will be cancelled. Any incremental backups will
> + restore their dirty bitmap objects as if no backup command was ever
> + issued.
> +
> + - Regardless of if QEMU reports a particular incremental backup job
> + as CANCELLED or as an ERROR, the in-memory bitmap will be
> + restored.
> +
> +Example
> +^^^^^^^
> +
> +- Here's the same example scenario from above with the new property:
> +
> + .. code:: json
> +
> + { "execute": "transaction",
> + "arguments": {
> + "actions": [
> + { "type": "drive-backup",
> + "data": { "device": "drive0", "bitmap": "bitmap0",
> + "format": "qcow2", "mode": "existing",
> + "sync": "incremental", "target": "d0-incr-1.qcow2"
> } },
> + { "type": "drive-backup",
> + "data": { "device": "drive1", "bitmap": "bitmap1",
> + "format": "qcow2", "mode": "existing",
> + "sync": "incremental", "target": "d1-incr-1.qcow2"
> } },
> + ],
> + "properties": {
> + "completion-mode": "grouped"
> + }
> + }
> + }
> +
> +- QMP example response, highlighting a failure for ``drive2``:
> +
> + - Acknowledgement that the Transaction was accepted and jobs were
> + launched:
> +
> + .. code:: json
> +
> + { "return": {} }
> +
> + - Later, QEMU sends notice that the second job has errored out, but
> + that the first job was also cancelled:
> +
> + .. code:: json
> +
> + { "timestamp": { "seconds": 1447193702, "microseconds": 632377 },
> + "data": { "device": "drive1", "action": "report",
> + "operation": "read" },
> + "event": "BLOCK_JOB_ERROR" }
> +
> + .. code:: json
> +
> + { "timestamp": { "seconds": 1447193702, "microseconds": 640074 },
> + "data": { "speed": 0, "offset": 0, "len": 67108864,
> + "error": "Input/output error",
> + "device": "drive1", "type": "backup" },
> + "event": "BLOCK_JOB_COMPLETED" }
> +
> + .. code:: json
> +
> + { "timestamp": { "seconds": 1447193702, "microseconds": 640163 },
> + "data": { "device": "drive0", "type": "backup", "speed": 0,
> + "len": 67108864, "offset": 16777216 },
> + "event": "BLOCK_JOB_CANCELLED" }
> +
> +.. raw:: html
> +
> + <!--
> + The FreeBSD Documentation License
> +
> + Redistribution and use in source (Markdown) and 'compiled' forms (SGML,
> HTML,
> + PDF, PostScript, RTF and so forth) with or without modification, are
> permitted
> + provided that the following conditions are met:
> +
> + Redistributions of source code (Markdown) must retain the above copyright
> + notice, this list of conditions and the following disclaimer of this file
> + unmodified.
> +
> + Redistributions in compiled form (transformed to other DTDs, converted to
> PDF,
> + PostScript, RTF and other formats) must reproduce the above copyright
> notice,
> + this list of conditions and the following disclaimer in the documentation
> and/or
> + other materials provided with the distribution.
> +
> + THIS DOCUMENTATION IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE ARE
> + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
> LIABLE
> + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
> + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
> + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
> + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
> LIABILITY,
> + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
> USE OF
> + THIS DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + -->
>
--
—js
- [Qemu-block] [PATCH v4 0/2] Rewrite 'live-block-ops.txt'; convert 'bitmaps.md' to rST, Kashyap Chamarthy, 2017/06/28
- [Qemu-block] [PATCH v4 0/2] Rewrite 'live-block-ops.txt'; convert 'bitmaps.md' to rST, Kashyap Chamarthy, 2017/06/28
- [Qemu-block] [PATCH v4 1/2] live-block-ops.txt: Rename, rewrite, and improve it, Kashyap Chamarthy, 2017/06/28
- Re: [Qemu-block] [PATCH v4 1/2] live-block-ops.txt: Rename, rewrite, and improve it, Alberto Garcia, 2017/06/28
- Re: [Qemu-block] [Qemu-devel] [PATCH v4 1/2] live-block-ops.txt: Rename, rewrite, and improve it, Eric Blake, 2017/06/28
- Re: [Qemu-block] [Qemu-devel] [PATCH v4 1/2] live-block-ops.txt: Rename, rewrite, and improve it, Alberto Garcia, 2017/06/29
- Re: [Qemu-block] [PATCH v4 1/2] live-block-ops.txt: Rename, rewrite, and improve it, Alberto Garcia, 2017/06/29
- [Qemu-block] [PATCH v4 2/2] bitmaps.md: Convert to rST; move it into 'interop' dir, Kashyap Chamarthy, 2017/06/28
- Re: [Qemu-block] [Qemu-devel] [PATCH v4 2/2] bitmaps.md: Convert to rST; move it into 'interop' dir,
John Snow <=