# -*- Mode: Python -*-
+# vim: filetype=python
#
##
# @normal-bytes: number of normal bytes sent (since 1.2)
#
# @dirty-pages-rate: number of pages dirtied by second by the
-# guest (since 1.3)
+# guest (since 1.3)
#
# @mbps: throughput in megabits/sec. (since 1.6)
#
# @dirty-sync-count: number of times that dirty ram was synchronized (since 2.1)
#
# @postcopy-requests: The number of page requests received from the destination
-# (since 2.7)
+# (since 2.7)
#
# @page-size: The number of bytes per page for the various page-based
-# statistics (since 2.10)
+# statistics (since 2.10)
#
# @multifd-bytes: The number of bytes sent through multifd (since 3.0)
#
# @pages-per-second: the number of memory pages transferred per second
-# (Since 4.0)
+# (Since 4.0)
#
-# Since: 0.14.0
+# @precopy-bytes: The number of bytes sent in the pre-copy phase
+# (since 7.0).
+#
+# @downtime-bytes: The number of bytes sent while the guest is paused
+# (since 7.0).
+#
+# @postcopy-bytes: The number of bytes sent during the post-copy phase
+# (since 7.0).
+#
+# Since: 0.14
##
{ 'struct': 'MigrationStats',
'data': {'transferred': 'int', 'remaining': 'int', 'total': 'int' ,
'normal-bytes': 'int', 'dirty-pages-rate' : 'int',
'mbps' : 'number', 'dirty-sync-count' : 'int',
'postcopy-requests' : 'int', 'page-size' : 'int',
- 'multifd-bytes' : 'uint64', 'pages-per-second' : 'uint64' } }
+ 'multifd-bytes' : 'uint64', 'pages-per-second' : 'uint64',
+ 'precopy-bytes' : 'uint64', 'downtime-bytes' : 'uint64',
+ 'postcopy-bytes' : 'uint64' } }
##
# @XBZRLECacheStats:
#
# @cache-miss-rate: rate of cache miss (since 2.1)
#
+# @encoding-rate: rate of encoded bytes (since 5.1)
+#
# @overflow: number of overflows
#
# Since: 1.2
##
{ 'struct': 'XBZRLECacheStats',
- 'data': {'cache-size': 'int', 'bytes': 'int', 'pages': 'int',
+ 'data': {'cache-size': 'size', 'bytes': 'int', 'pages': 'int',
'cache-miss': 'int', 'cache-miss-rate': 'number',
- 'overflow': 'int' } }
+ 'encoding-rate': 'number', 'overflow': 'int' } }
##
# @CompressionStats:
##
{ 'struct': 'CompressionStats',
'data': {'pages': 'int', 'busy': 'int', 'busy-rate': 'number',
- 'compressed-size': 'int', 'compression-rate': 'number' } }
+ 'compressed-size': 'int', 'compression-rate': 'number' } }
##
# @MigrationStatus:
# @pre-switchover: Paused before device serialisation. (since 2.11)
#
# @device: During device serialisation when pause-before-switchover is enabled
-# (since 2.11)
+# (since 2.11)
#
# @wait-unplug: wait for device unplug request by guest OS to be completed.
# (since 4.2)
'active', 'postcopy-active', 'postcopy-paused',
'postcopy-recover', 'completed', 'failed', 'colo',
'pre-switchover', 'device', 'wait-unplug' ] }
+##
+# @VfioStats:
+#
+# Detailed VFIO devices migration statistics
+#
+# @transferred: amount of bytes transferred to the target VM by VFIO devices
+#
+# Since: 5.2
+#
+##
+{ 'struct': 'VfioStats',
+ 'data': {'transferred': 'int' } }
##
# @MigrationInfo:
# status is 'active' or 'completed' (since 1.2)
#
# @total-time: total amount of milliseconds since migration started.
-# If migration has ended, it returns the total migration
-# time. (since 1.2)
+# If migration has ended, it returns the total migration
+# time. (since 1.2)
#
# @downtime: only present when migration finishes correctly
-# total downtime in milliseconds for the guest.
-# (since 1.3)
+# total downtime in milliseconds for the guest.
+# (since 1.3)
#
# @expected-downtime: only present while migration is active
-# expected downtime in milliseconds for the guest in last walk
-# of the dirty bitmap. (since 1.3)
+# expected downtime in milliseconds for the guest in last walk
+# of the dirty bitmap. (since 1.3)
#
-# @setup-time: amount of setup time in milliseconds _before_ the
-# iterations begin but _after_ the QMP command is issued. This is designed
-# to provide an accounting of any activities (such as RDMA pinning) which
-# may be expensive, but do not actually occur during the iterative
-# migration rounds themselves. (since 1.6)
+# @setup-time: amount of setup time in milliseconds *before* the
+# iterations begin but *after* the QMP command is issued. This is designed
+# to provide an accounting of any activities (such as RDMA pinning) which
+# may be expensive, but do not actually occur during the iterative
+# migration rounds themselves. (since 1.6)
#
# @cpu-throttle-percentage: percentage of time guest cpus are being
-# throttled during auto-converge. This is only present when auto-converge
-# has started throttling guest cpus. (Since 2.7)
+# throttled during auto-converge. This is only present when auto-converge
+# has started throttling guest cpus. (Since 2.7)
#
# @error-desc: the human readable error description string, when
# @status is 'failed'. Clients should not attempt to parse the
# error strings. (Since 2.7)
#
# @postcopy-blocktime: total time when all vCPU were blocked during postcopy
-# live migration. This is only present when the postcopy-blocktime
-# migration capability is enabled. (Since 3.0)
+# live migration. This is only present when the postcopy-blocktime
+# migration capability is enabled. (Since 3.0)
#
# @postcopy-vcpu-blocktime: list of the postcopy blocktime per vCPU. This is
-# only present when the postcopy-blocktime migration capability
-# is enabled. (Since 3.0)
+# only present when the postcopy-blocktime migration capability
+# is enabled. (Since 3.0)
#
# @compression: migration compression statistics, only returned if compression
-# feature is on and status is 'active' or 'completed' (Since 3.1)
+# feature is on and status is 'active' or 'completed' (Since 3.1)
#
# @socket-address: Only used for tcp, to know what the real port is (Since 4.0)
#
-# Since: 0.14.0
+# @vfio: @VfioStats containing detailed VFIO devices migration statistics,
+# only returned if VFIO device is present, migration is supported by all
+# VFIO devices and status is 'active' or 'completed' (since 5.2)
+#
+# @blocked-reasons: A list of reasons an outgoing migration is blocked.
+# Present and non-empty when migration is blocked.
+# (since 6.0)
+#
+# Since: 0.14
##
{ 'struct': 'MigrationInfo',
'data': {'*status': 'MigrationStatus', '*ram': 'MigrationStats',
'*disk': 'MigrationStats',
+ '*vfio': 'VfioStats',
'*xbzrle-cache': 'XBZRLECacheStats',
'*total-time': 'int',
'*expected-downtime': 'int',
'*setup-time': 'int',
'*cpu-throttle-percentage': 'int',
'*error-desc': 'str',
+ '*blocked-reasons': ['str'],
'*postcopy-blocktime' : 'uint32',
'*postcopy-vcpu-blocktime': ['uint32'],
'*compression': 'CompressionStats',
#
# Returns: @MigrationInfo
#
-# Since: 0.14.0
+# Since: 0.14
#
# Example:
#
# "pages":2444343,
# "cache-miss":2244,
# "cache-miss-rate":0.123,
+# "encoding-rate":80.1,
# "overflow":34434
# }
# }
# loads, by sending compressed difference of the pages
#
# @rdma-pin-all: Controls whether or not the entire VM memory footprint is
-# mlock()'d on demand or all at once. Refer to docs/rdma.txt for usage.
-# Disabled by default. (since 2.0)
+# mlock()'d on demand or all at once. Refer to docs/rdma.txt for usage.
+# Disabled by default. (since 2.0)
#
# @zero-blocks: During storage migration encode blocks of zeroes efficiently. This
-# essentially saves 1MB of zeroes per block on the wire. Enabling requires
-# source and target VM to support this feature. To enable it is sufficient
-# to enable the capability on the source VM. The feature is disabled by
-# default. (since 1.6)
+# essentially saves 1MB of zeroes per block on the wire. Enabling requires
+# source and target VM to support this feature. To enable it is sufficient
+# to enable the capability on the source VM. The feature is disabled by
+# default. (since 1.6)
#
# @compress: Use multiple compression threads to accelerate live migration.
-# This feature can help to reduce the migration traffic, by sending
-# compressed pages. Please note that if compress and xbzrle are both
-# on, compress only takes effect in the ram bulk stage, after that,
-# it will be disabled and only xbzrle takes effect, this can help to
-# minimize migration traffic. The feature is disabled by default.
-# (since 2.4 )
+# This feature can help to reduce the migration traffic, by sending
+# compressed pages. Please note that if compress and xbzrle are both
+# on, compress only takes effect in the ram bulk stage, after that,
+# it will be disabled and only xbzrle takes effect, this can help to
+# minimize migration traffic. The feature is disabled by default.
+# (since 2.4 )
#
# @events: generate events for each migration state change
# (since 2.4 )
#
# @auto-converge: If enabled, QEMU will automatically throttle down the guest
-# to speed up convergence of RAM migration. (since 1.6)
+# to speed up convergence of RAM migration. (since 1.6)
#
# @postcopy-ram: Start executing on the migration target before all of RAM has
-# been migrated, pulling the remaining pages along as needed. The
-# capacity must have the same setting on both source and target
-# or migration will not even start. NOTE: If the migration fails during
-# postcopy the VM will fail. (since 2.6)
+# been migrated, pulling the remaining pages along as needed. The
+# capacity must have the same setting on both source and target
+# or migration will not even start. NOTE: If the migration fails during
+# postcopy the VM will fail. (since 2.6)
#
# @x-colo: If enabled, migration will never end, and the state of the VM on the
-# primary side will be migrated continuously to the VM on secondary
-# side, this process is called COarse-Grain LOck Stepping (COLO) for
-# Non-stop Service. (since 2.8)
+# primary side will be migrated continuously to the VM on secondary
+# side, this process is called COarse-Grain LOck Stepping (COLO) for
+# Non-stop Service. (since 2.8)
#
# @release-ram: if enabled, qemu will free the migrated ram pages on the source
-# during postcopy-ram migration. (since 2.9)
+# during postcopy-ram migration. (since 2.9)
#
# @block: If enabled, QEMU will also migrate the contents of all block
-# devices. Default is disabled. A possible alternative uses
-# mirror jobs to a builtin NBD server on the destination, which
-# offers more flexibility.
-# (Since 2.10)
+# devices. Default is disabled. A possible alternative uses
+# mirror jobs to a builtin NBD server on the destination, which
+# offers more flexibility.
+# (Since 2.10)
#
# @return-path: If enabled, migration will use the return path even
# for precopy. (since 2.10)
#
# @pause-before-switchover: Pause outgoing migration before serialising device
-# state and before disabling block IO (since 2.11)
+# state and before disabling block IO (since 2.11)
#
# @multifd: Use more than one fd for migration (since 4.0)
#
# (since 2.12)
#
# @postcopy-blocktime: Calculate downtime for postcopy live migration
-# (since 3.0)
+# (since 3.0)
#
# @late-block-activate: If enabled, the destination will not activate block
-# devices (and thus take locks) immediately at the end of migration.
-# (since 3.0)
+# devices (and thus take locks) immediately at the end of migration.
+# (since 3.0)
#
# @x-ignore-shared: If enabled, QEMU will not migrate shared memory (since 4.0)
#
# @validate-uuid: Send the UUID of the source to allow the destination
# to ensure it is the same. (since 4.2)
#
+# @background-snapshot: If enabled, the migration stream will be a snapshot
+# of the VM exactly at the point when the migration
+# procedure starts. The VM RAM is saved with running VM.
+# (since 6.0)
+#
+# Features:
+# @unstable: Members @x-colo and @x-ignore-shared are experimental.
+#
# Since: 1.2
##
{ 'enum': 'MigrationCapability',
'data': ['xbzrle', 'rdma-pin-all', 'auto-converge', 'zero-blocks',
- 'compress', 'events', 'postcopy-ram', 'x-colo', 'release-ram',
+ 'compress', 'events', 'postcopy-ram',
+ { 'name': 'x-colo', 'features': [ 'unstable' ] },
+ 'release-ram',
'block', 'return-path', 'pause-before-switchover', 'multifd',
'dirty-bitmaps', 'postcopy-blocktime', 'late-block-activate',
- 'x-ignore-shared', 'validate-uuid' ] }
+ { 'name': 'x-ignore-shared', 'features': [ 'unstable' ] },
+ 'validate-uuid', 'background-snapshot'] }
##
# @MigrationCapabilityStatus:
##
{ 'command': 'query-migrate-capabilities', 'returns': ['MigrationCapabilityStatus']}
+##
+# @MultiFDCompression:
+#
+# An enumeration of multifd compression methods.
+#
+# @none: no compression.
+# @zlib: use zlib compression method.
+# @zstd: use zstd compression method.
+#
+# Since: 5.0
+#
+##
+{ 'enum': 'MultiFDCompression',
+ 'data': [ 'none', 'zlib',
+ { 'name': 'zstd', 'if': 'CONFIG_ZSTD' } ] }
+
+##
+# @BitmapMigrationBitmapAliasTransform:
+#
+# @persistent: If present, the bitmap will be made persistent
+# or transient depending on this parameter.
+#
+# Since: 6.0
+##
+{ 'struct': 'BitmapMigrationBitmapAliasTransform',
+ 'data': {
+ '*persistent': 'bool'
+ } }
+
+##
+# @BitmapMigrationBitmapAlias:
+#
+# @name: The name of the bitmap.
+#
+# @alias: An alias name for migration (for example the bitmap name on
+# the opposite site).
+#
+# @transform: Allows the modification of the migrated bitmap.
+# (since 6.0)
+#
+# Since: 5.2
+##
+{ 'struct': 'BitmapMigrationBitmapAlias',
+ 'data': {
+ 'name': 'str',
+ 'alias': 'str',
+ '*transform': 'BitmapMigrationBitmapAliasTransform'
+ } }
+
+##
+# @BitmapMigrationNodeAlias:
+#
+# Maps a block node name and the bitmaps it has to aliases for dirty
+# bitmap migration.
+#
+# @node-name: A block node name.
+#
+# @alias: An alias block node name for migration (for example the
+# node name on the opposite site).
+#
+# @bitmaps: Mappings for the bitmaps on this node.
+#
+# Since: 5.2
+##
+{ 'struct': 'BitmapMigrationNodeAlias',
+ 'data': {
+ 'node-name': 'str',
+ 'alias': 'str',
+ 'bitmaps': [ 'BitmapMigrationBitmapAlias' ]
+ } }
+
##
# @MigrationParameter:
#
# Migration parameters enumeration
#
# @announce-initial: Initial delay (in milliseconds) before sending the first
-# announce (Since 4.0)
+# announce (Since 4.0)
#
# @announce-max: Maximum delay (in milliseconds) between packets in the
-# announcement (Since 4.0)
+# announcement (Since 4.0)
#
# @announce-rounds: Number of self-announce packets sent after migration
-# (Since 4.0)
+# (Since 4.0)
#
# @announce-step: Increase in delay (in milliseconds) between subsequent
-# packets in the announcement (Since 4.0)
+# packets in the announcement (Since 4.0)
#
# @compress-level: Set the compression level to be used in live migration,
-# the compression level is an integer between 0 and 9, where 0 means
-# no compression, 1 means the best compression speed, and 9 means best
-# compression ratio which will consume more CPU.
+# the compression level is an integer between 0 and 9, where 0 means
+# no compression, 1 means the best compression speed, and 9 means best
+# compression ratio which will consume more CPU.
#
# @compress-threads: Set compression thread count to be used in live migration,
-# the compression thread count is an integer between 1 and 255.
+# the compression thread count is an integer between 1 and 255.
#
# @compress-wait-thread: Controls behavior when all compression threads are
# currently busy. If true (default), wait for a free
# send the page uncompressed. (Since 3.1)
#
# @decompress-threads: Set decompression thread count to be used in live
-# migration, the decompression thread count is an integer between 1
-# and 255. Usually, decompression is at least 4 times as fast as
-# compression, so set the decompress-threads to the number about 1/4
-# of compress-threads is adequate.
+# migration, the decompression thread count is an integer between 1
+# and 255. Usually, decompression is at least 4 times as fast as
+# compression, so set the decompress-threads to the number about 1/4
+# of compress-threads is adequate.
+#
+# @throttle-trigger-threshold: The ratio of bytes_dirty_period and bytes_xfer_period
+# to trigger throttling. It is expressed as percentage.
+# The default value is 50. (Since 5.0)
#
# @cpu-throttle-initial: Initial percentage of time guest cpus are throttled
# when migration auto-converge is activated. The
# auto-converge detects that migration is not making
# progress. The default value is 10. (Since 2.7)
#
+# @cpu-throttle-tailslow: Make CPU throttling slower at tail stage
+# At the tail stage of throttling, the Guest is very
+# sensitive to CPU percentage while the @cpu-throttle
+# -increment is excessive usually at tail stage.
+# If this parameter is true, we will compute the ideal
+# CPU percentage used by the Guest, which may exactly make
+# the dirty rate match the dirty rate threshold. Then we
+# will choose a smaller throttle increment between the
+# one specified by @cpu-throttle-increment and the one
+# generated by ideal CPU percentage.
+# Therefore, it is compatible to traditional throttling,
+# meanwhile the throttle increment won't be excessive
+# at tail stage.
+# The default value is false. (Since 5.1)
+#
# @tls-creds: ID of the 'tls-creds' object that provides credentials for
# establishing a TLS connection over the migration data channel.
# On the outgoing side of the migration, the credentials must
# downtime in milliseconds (Since 2.8)
#
# @x-checkpoint-delay: The delay time (in ms) between two COLO checkpoints in
-# periodic mode. (Since 2.8)
+# periodic mode. (Since 2.8)
#
# @block-incremental: Affects how much storage is migrated when the
-# block migration capability is enabled. When false, the entire
-# storage backing chain is migrated into a flattened image at
-# the destination; when true, only the active qcow2 layer is
-# migrated and the destination must already have access to the
-# same backing chain as was used on the source. (since 2.10)
+# block migration capability is enabled. When false, the entire
+# storage backing chain is migrated into a flattened image at
+# the destination; when true, only the active qcow2 layer is
+# migrated and the destination must already have access to the
+# same backing chain as was used on the source. (since 2.10)
#
# @multifd-channels: Number of channels used to migrate data in
# parallel. This is the same number that the
# (Since 2.11)
#
# @max-postcopy-bandwidth: Background transfer bandwidth during postcopy.
-# Defaults to 0 (unlimited). In bytes per second.
-# (Since 3.0)
+# Defaults to 0 (unlimited). In bytes per second.
+# (Since 3.0)
#
# @max-cpu-throttle: maximum cpu throttle percentage.
# Defaults to 99. (Since 3.1)
#
+# @multifd-compression: Which compression method to use.
+# Defaults to none. (Since 5.0)
+#
+# @multifd-zlib-level: Set the compression level to be used in live
+# migration, the compression level is an integer between 0
+# and 9, where 0 means no compression, 1 means the best
+# compression speed, and 9 means best compression ratio which
+# will consume more CPU.
+# Defaults to 1. (Since 5.0)
+#
+# @multifd-zstd-level: Set the compression level to be used in live
+# migration, the compression level is an integer between 0
+# and 20, where 0 means no compression, 1 means the best
+# compression speed, and 20 means best compression ratio which
+# will consume more CPU.
+# Defaults to 1. (Since 5.0)
+#
+# @block-bitmap-mapping: Maps block nodes and bitmaps on them to
+# aliases for the purpose of dirty bitmap migration. Such
+# aliases may for example be the corresponding names on the
+# opposite site.
+# The mapping must be one-to-one, but not necessarily
+# complete: On the source, unmapped bitmaps and all bitmaps
+# on unmapped nodes will be ignored. On the destination,
+# encountering an unmapped alias in the incoming migration
+# stream will result in a report, and all further bitmap
+# migration data will then be discarded.
+# Note that the destination does not know about bitmaps it
+# does not receive, so there is no limitation or requirement
+# regarding the number of bitmaps received, or how they are
+# named, or on which nodes they are placed.
+# By default (when this parameter has never been set), bitmap
+# names are mapped to themselves. Nodes are mapped to their
+# block device name if there is one, and to their node name
+# otherwise. (Since 5.2)
+#
+# Features:
+# @unstable: Member @x-checkpoint-delay is experimental.
+#
# Since: 2.4
##
{ 'enum': 'MigrationParameter',
'data': ['announce-initial', 'announce-max',
'announce-rounds', 'announce-step',
'compress-level', 'compress-threads', 'decompress-threads',
- 'compress-wait-thread',
+ 'compress-wait-thread', 'throttle-trigger-threshold',
'cpu-throttle-initial', 'cpu-throttle-increment',
+ 'cpu-throttle-tailslow',
'tls-creds', 'tls-hostname', 'tls-authz', 'max-bandwidth',
- 'downtime-limit', 'x-checkpoint-delay', 'block-incremental',
+ 'downtime-limit',
+ { 'name': 'x-checkpoint-delay', 'features': [ 'unstable' ] },
+ 'block-incremental',
'multifd-channels',
'xbzrle-cache-size', 'max-postcopy-bandwidth',
- 'max-cpu-throttle' ] }
+ 'max-cpu-throttle', 'multifd-compression',
+ 'multifd-zlib-level' ,'multifd-zstd-level',
+ 'block-bitmap-mapping' ] }
##
# @MigrateSetParameters:
#
# @announce-initial: Initial delay (in milliseconds) before sending the first
-# announce (Since 4.0)
+# announce (Since 4.0)
#
# @announce-max: Maximum delay (in milliseconds) between packets in the
-# announcement (Since 4.0)
+# announcement (Since 4.0)
#
# @announce-rounds: Number of self-announce packets sent after migration
-# (Since 4.0)
+# (Since 4.0)
#
# @announce-step: Increase in delay (in milliseconds) between subsequent
-# packets in the announcement (Since 4.0)
+# packets in the announcement (Since 4.0)
#
# @compress-level: compression level
#
#
# @decompress-threads: decompression thread count
#
+# @throttle-trigger-threshold: The ratio of bytes_dirty_period and bytes_xfer_period
+# to trigger throttling. It is expressed as percentage.
+# The default value is 50. (Since 5.0)
+#
# @cpu-throttle-initial: Initial percentage of time guest cpus are
# throttled when migration auto-converge is activated.
# The default value is 20. (Since 2.7)
# auto-converge detects that migration is not making
# progress. The default value is 10. (Since 2.7)
#
+# @cpu-throttle-tailslow: Make CPU throttling slower at tail stage
+# At the tail stage of throttling, the Guest is very
+# sensitive to CPU percentage while the @cpu-throttle
+# -increment is excessive usually at tail stage.
+# If this parameter is true, we will compute the ideal
+# CPU percentage used by the Guest, which may exactly make
+# the dirty rate match the dirty rate threshold. Then we
+# will choose a smaller throttle increment between the
+# one specified by @cpu-throttle-increment and the one
+# generated by ideal CPU percentage.
+# Therefore, it is compatible to traditional throttling,
+# meanwhile the throttle increment won't be excessive
+# at tail stage.
+# The default value is false. (Since 5.1)
+#
# @tls-creds: ID of the 'tls-creds' object that provides credentials
# for establishing a TLS connection over the migration data
# channel. On the outgoing side of the migration, the credentials
# @x-checkpoint-delay: the delay time between two COLO checkpoints. (Since 2.8)
#
# @block-incremental: Affects how much storage is migrated when the
-# block migration capability is enabled. When false, the entire
-# storage backing chain is migrated into a flattened image at
-# the destination; when true, only the active qcow2 layer is
-# migrated and the destination must already have access to the
-# same backing chain as was used on the source. (since 2.10)
+# block migration capability is enabled. When false, the entire
+# storage backing chain is migrated into a flattened image at
+# the destination; when true, only the active qcow2 layer is
+# migrated and the destination must already have access to the
+# same backing chain as was used on the source. (since 2.10)
#
# @multifd-channels: Number of channels used to migrate data in
# parallel. This is the same number that the
# (Since 2.11)
#
# @max-postcopy-bandwidth: Background transfer bandwidth during postcopy.
-# Defaults to 0 (unlimited). In bytes per second.
-# (Since 3.0)
+# Defaults to 0 (unlimited). In bytes per second.
+# (Since 3.0)
#
# @max-cpu-throttle: maximum cpu throttle percentage.
# The default value is 99. (Since 3.1)
#
+# @multifd-compression: Which compression method to use.
+# Defaults to none. (Since 5.0)
+#
+# @multifd-zlib-level: Set the compression level to be used in live
+# migration, the compression level is an integer between 0
+# and 9, where 0 means no compression, 1 means the best
+# compression speed, and 9 means best compression ratio which
+# will consume more CPU.
+# Defaults to 1. (Since 5.0)
+#
+# @multifd-zstd-level: Set the compression level to be used in live
+# migration, the compression level is an integer between 0
+# and 20, where 0 means no compression, 1 means the best
+# compression speed, and 20 means best compression ratio which
+# will consume more CPU.
+# Defaults to 1. (Since 5.0)
+#
+# @block-bitmap-mapping: Maps block nodes and bitmaps on them to
+# aliases for the purpose of dirty bitmap migration. Such
+# aliases may for example be the corresponding names on the
+# opposite site.
+# The mapping must be one-to-one, but not necessarily
+# complete: On the source, unmapped bitmaps and all bitmaps
+# on unmapped nodes will be ignored. On the destination,
+# encountering an unmapped alias in the incoming migration
+# stream will result in a report, and all further bitmap
+# migration data will then be discarded.
+# Note that the destination does not know about bitmaps it
+# does not receive, so there is no limitation or requirement
+# regarding the number of bitmaps received, or how they are
+# named, or on which nodes they are placed.
+# By default (when this parameter has never been set), bitmap
+# names are mapped to themselves. Nodes are mapped to their
+# block device name if there is one, and to their node name
+# otherwise. (Since 5.2)
+#
+# Features:
+# @unstable: Member @x-checkpoint-delay is experimental.
+#
# Since: 2.4
##
# TODO either fuse back into MigrationParameters, or make
'*announce-max': 'size',
'*announce-rounds': 'size',
'*announce-step': 'size',
- '*compress-level': 'int',
- '*compress-threads': 'int',
+ '*compress-level': 'uint8',
+ '*compress-threads': 'uint8',
'*compress-wait-thread': 'bool',
- '*decompress-threads': 'int',
- '*cpu-throttle-initial': 'int',
- '*cpu-throttle-increment': 'int',
+ '*decompress-threads': 'uint8',
+ '*throttle-trigger-threshold': 'uint8',
+ '*cpu-throttle-initial': 'uint8',
+ '*cpu-throttle-increment': 'uint8',
+ '*cpu-throttle-tailslow': 'bool',
'*tls-creds': 'StrOrNull',
'*tls-hostname': 'StrOrNull',
'*tls-authz': 'StrOrNull',
- '*max-bandwidth': 'int',
- '*downtime-limit': 'int',
- '*x-checkpoint-delay': 'int',
+ '*max-bandwidth': 'size',
+ '*downtime-limit': 'uint64',
+ '*x-checkpoint-delay': { 'type': 'uint32',
+ 'features': [ 'unstable' ] },
'*block-incremental': 'bool',
- '*multifd-channels': 'int',
+ '*multifd-channels': 'uint8',
'*xbzrle-cache-size': 'size',
'*max-postcopy-bandwidth': 'size',
- '*max-cpu-throttle': 'int' } }
+ '*max-cpu-throttle': 'uint8',
+ '*multifd-compression': 'MultiFDCompression',
+ '*multifd-zlib-level': 'uint8',
+ '*multifd-zstd-level': 'uint8',
+ '*block-bitmap-mapping': [ 'BitmapMigrationNodeAlias' ] } }
##
# @migrate-set-parameters:
# The optional members aren't actually optional.
#
# @announce-initial: Initial delay (in milliseconds) before sending the
-# first announce (Since 4.0)
+# first announce (Since 4.0)
#
# @announce-max: Maximum delay (in milliseconds) between packets in the
-# announcement (Since 4.0)
+# announcement (Since 4.0)
#
# @announce-rounds: Number of self-announce packets sent after migration
-# (Since 4.0)
+# (Since 4.0)
#
# @announce-step: Increase in delay (in milliseconds) between subsequent
-# packets in the announcement (Since 4.0)
+# packets in the announcement (Since 4.0)
#
# @compress-level: compression level
#
#
# @decompress-threads: decompression thread count
#
+# @throttle-trigger-threshold: The ratio of bytes_dirty_period and bytes_xfer_period
+# to trigger throttling. It is expressed as percentage.
+# The default value is 50. (Since 5.0)
+#
# @cpu-throttle-initial: Initial percentage of time guest cpus are
# throttled when migration auto-converge is activated.
# (Since 2.7)
# auto-converge detects that migration is not making
# progress. (Since 2.7)
#
+# @cpu-throttle-tailslow: Make CPU throttling slower at tail stage
+# At the tail stage of throttling, the Guest is very
+# sensitive to CPU percentage while the @cpu-throttle
+# -increment is excessive usually at tail stage.
+# If this parameter is true, we will compute the ideal
+# CPU percentage used by the Guest, which may exactly make
+# the dirty rate match the dirty rate threshold. Then we
+# will choose a smaller throttle increment between the
+# one specified by @cpu-throttle-increment and the one
+# generated by ideal CPU percentage.
+# Therefore, it is compatible to traditional throttling,
+# meanwhile the throttle increment won't be excessive
+# at tail stage.
+# The default value is false. (Since 5.1)
+#
# @tls-creds: ID of the 'tls-creds' object that provides credentials
# for establishing a TLS connection over the migration data
# channel. On the outgoing side of the migration, the credentials
# @x-checkpoint-delay: the delay time between two COLO checkpoints. (Since 2.8)
#
# @block-incremental: Affects how much storage is migrated when the
-# block migration capability is enabled. When false, the entire
-# storage backing chain is migrated into a flattened image at
-# the destination; when true, only the active qcow2 layer is
-# migrated and the destination must already have access to the
-# same backing chain as was used on the source. (since 2.10)
+# block migration capability is enabled. When false, the entire
+# storage backing chain is migrated into a flattened image at
+# the destination; when true, only the active qcow2 layer is
+# migrated and the destination must already have access to the
+# same backing chain as was used on the source. (since 2.10)
#
# @multifd-channels: Number of channels used to migrate data in
# parallel. This is the same number that the
# (Since 2.11)
#
# @max-postcopy-bandwidth: Background transfer bandwidth during postcopy.
-# Defaults to 0 (unlimited). In bytes per second.
-# (Since 3.0)
+# Defaults to 0 (unlimited). In bytes per second.
+# (Since 3.0)
#
# @max-cpu-throttle: maximum cpu throttle percentage.
# Defaults to 99.
-# (Since 3.1)
+# (Since 3.1)
+#
+# @multifd-compression: Which compression method to use.
+# Defaults to none. (Since 5.0)
+#
+# @multifd-zlib-level: Set the compression level to be used in live
+# migration, the compression level is an integer between 0
+# and 9, where 0 means no compression, 1 means the best
+# compression speed, and 9 means best compression ratio which
+# will consume more CPU.
+# Defaults to 1. (Since 5.0)
+#
+# @multifd-zstd-level: Set the compression level to be used in live
+# migration, the compression level is an integer between 0
+# and 20, where 0 means no compression, 1 means the best
+# compression speed, and 20 means best compression ratio which
+# will consume more CPU.
+# Defaults to 1. (Since 5.0)
+#
+# @block-bitmap-mapping: Maps block nodes and bitmaps on them to
+# aliases for the purpose of dirty bitmap migration. Such
+# aliases may for example be the corresponding names on the
+# opposite site.
+# The mapping must be one-to-one, but not necessarily
+# complete: On the source, unmapped bitmaps and all bitmaps
+# on unmapped nodes will be ignored. On the destination,
+# encountering an unmapped alias in the incoming migration
+# stream will result in a report, and all further bitmap
+# migration data will then be discarded.
+# Note that the destination does not know about bitmaps it
+# does not receive, so there is no limitation or requirement
+# regarding the number of bitmaps received, or how they are
+# named, or on which nodes they are placed.
+# By default (when this parameter has never been set), bitmap
+# names are mapped to themselves. Nodes are mapped to their
+# block device name if there is one, and to their node name
+# otherwise. (Since 5.2)
+#
+# Features:
+# @unstable: Member @x-checkpoint-delay is experimental.
#
# Since: 2.4
##
'*compress-threads': 'uint8',
'*compress-wait-thread': 'bool',
'*decompress-threads': 'uint8',
+ '*throttle-trigger-threshold': 'uint8',
'*cpu-throttle-initial': 'uint8',
'*cpu-throttle-increment': 'uint8',
+ '*cpu-throttle-tailslow': 'bool',
'*tls-creds': 'str',
'*tls-hostname': 'str',
'*tls-authz': 'str',
'*max-bandwidth': 'size',
'*downtime-limit': 'uint64',
- '*x-checkpoint-delay': 'uint32',
- '*block-incremental': 'bool' ,
+ '*x-checkpoint-delay': { 'type': 'uint32',
+ 'features': [ 'unstable' ] },
+ '*block-incremental': 'bool',
'*multifd-channels': 'uint8',
'*xbzrle-cache-size': 'size',
- '*max-postcopy-bandwidth': 'size',
- '*max-cpu-throttle':'uint8'} }
+ '*max-postcopy-bandwidth': 'size',
+ '*max-cpu-throttle': 'uint8',
+ '*multifd-compression': 'MultiFDCompression',
+ '*multifd-zlib-level': 'uint8',
+ '*multifd-zstd-level': 'uint8',
+ '*block-bitmap-mapping': [ 'BitmapMigrationNodeAlias' ] } }
##
# @query-migrate-parameters:
# @tls-port: spice tcp port for tls-secured channels
# @cert-subject: server certificate subject
#
-# Since: 0.14.0
+# Since: 0.14
#
# Example:
#
# The reason for a COLO exit.
#
# @none: failover has never happened. This state does not occur
-# in the COLO_EXIT event, and is only visible in the result of
-# query-colo-status.
+# in the COLO_EXIT event, and is only visible in the result of
+# query-colo-status.
#
# @request: COLO exit is due to an external request.
#
# If sent to the Secondary, the Secondary side will run failover work,
# then takes over server operation to become the service VM.
#
+# Features:
+# @unstable: This command is experimental.
+#
# Since: 2.8
#
# Example:
# <- { "return": {} }
#
##
-{ 'command': 'x-colo-lost-heartbeat' }
+{ 'command': 'x-colo-lost-heartbeat',
+ 'features': [ 'unstable' ] }
##
# @migrate_cancel:
#
# Notes: This command succeeds even if there is no migration process running.
#
-# Since: 0.14.0
+# Since: 0.14
#
# Example:
#
##
{ 'command': 'migrate-continue', 'data': {'state': 'MigrationStatus'} }
-##
-# @migrate_set_downtime:
-#
-# Set maximum tolerated downtime for migration.
-#
-# @value: maximum downtime in seconds
-#
-# Returns: nothing on success
-#
-# Notes: This command is deprecated in favor of 'migrate-set-parameters'
-#
-# Since: 0.14.0
-#
-# Example:
-#
-# -> { "execute": "migrate_set_downtime", "arguments": { "value": 0.1 } }
-# <- { "return": {} }
-#
-##
-{ 'command': 'migrate_set_downtime', 'data': {'value': 'number'} }
-
-##
-# @migrate_set_speed:
-#
-# Set maximum speed for migration.
-#
-# @value: maximum speed in bytes per second.
-#
-# Returns: nothing on success
-#
-# Notes: This command is deprecated in favor of 'migrate-set-parameters'
-#
-# Since: 0.14.0
-#
-# Example:
-#
-# -> { "execute": "migrate_set_speed", "arguments": { "value": 1024 } }
-# <- { "return": {} }
-#
-##
-{ 'command': 'migrate_set_speed', 'data': {'value': 'int'} }
-
-##
-# @migrate-set-cache-size:
-#
-# Set cache size to be used by XBZRLE migration
-#
-# @value: cache size in bytes
-#
-# The size will be rounded down to the nearest power of 2.
-# The cache size can be modified before and during ongoing migration
-#
-# Returns: nothing on success
-#
-# Notes: This command is deprecated in favor of 'migrate-set-parameters'
-#
-# Since: 1.2
-#
-# Example:
-#
-# -> { "execute": "migrate-set-cache-size",
-# "arguments": { "value": 536870912 } }
-# <- { "return": {} }
-#
-##
-{ 'command': 'migrate-set-cache-size', 'data': {'value': 'int'} }
-
-##
-# @query-migrate-cache-size:
-#
-# Query migration XBZRLE cache size
-#
-# Returns: XBZRLE cache size in bytes
-#
-# Notes: This command is deprecated in favor of 'query-migrate-parameters'
-#
-# Since: 1.2
-#
-# Example:
-#
-# -> { "execute": "query-migrate-cache-size" }
-# <- { "return": 67108864 }
-#
-##
-{ 'command': 'query-migrate-cache-size', 'returns': 'int' }
-
##
# @migrate:
#
#
# Returns: nothing on success
#
-# Since: 0.14.0
+# Since: 0.14
#
# Notes:
#
# of the VM are not saved by this command.
#
# @filename: the file to save the state of the devices to as binary
-# data. See xen-save-devices-state.txt for a description of the binary
-# format.
+# data. See xen-save-devices-state.txt for a description of the binary
+# format.
#
# @live: Optional argument to ask QEMU to treat this command as part of a live
-# migration. Default to true. (since 2.11)
+# migration. Default to true. (since 2.11)
#
# Returns: Nothing on success
#
{ 'command': 'xen-save-devices-state',
'data': {'filename': 'str', '*live':'bool' } }
+##
+# @xen-set-global-dirty-log:
+#
+# Enable or disable the global dirty log mode.
+#
+# @enable: true to enable, false to disable.
+#
+# Returns: nothing
+#
+# Since: 1.3
+#
+# Example:
+#
+# -> { "execute": "xen-set-global-dirty-log",
+# "arguments": { "enable": true } }
+# <- { "return": {} }
+#
+##
+{ 'command': 'xen-set-global-dirty-log', 'data': { 'enable': 'bool' } }
+
+##
+# @xen-load-devices-state:
+#
+# Load the state of all devices from file. The RAM and the block devices
+# of the VM are not loaded by this command.
+#
+# @filename: the file to load the state of the devices from as binary
+# data. See xen-save-devices-state.txt for a description of the binary
+# format.
+#
+# Since: 2.7
+#
+# Example:
+#
+# -> { "execute": "xen-load-devices-state",
+# "arguments": { "filename": "/tmp/resume" } }
+# <- { "return": {} }
+#
+##
+{ 'command': 'xen-load-devices-state', 'data': {'filename': 'str'} }
+
##
# @xen-set-replication:
#
##
{ 'command': 'xen-set-replication',
'data': { 'enable': 'bool', 'primary': 'bool', '*failover' : 'bool' },
- 'if': 'defined(CONFIG_REPLICATION)' }
+ 'if': 'CONFIG_REPLICATION' }
##
# @ReplicationStatus:
##
{ 'struct': 'ReplicationStatus',
'data': { 'error': 'bool', '*desc': 'str' },
- 'if': 'defined(CONFIG_REPLICATION)' }
+ 'if': 'CONFIG_REPLICATION' }
##
# @query-xen-replication-status:
##
{ 'command': 'query-xen-replication-status',
'returns': 'ReplicationStatus',
- 'if': 'defined(CONFIG_REPLICATION)' }
+ 'if': 'CONFIG_REPLICATION' }
##
# @xen-colo-do-checkpoint:
# Since: 2.9
##
{ 'command': 'xen-colo-do-checkpoint',
- 'if': 'defined(CONFIG_REPLICATION)' }
+ 'if': 'CONFIG_REPLICATION' }
##
# @COLOStatus:
##
{ 'event': 'UNPLUG_PRIMARY',
'data': { 'device-id': 'str' } }
+
+##
+# @DirtyRateVcpu:
+#
+# Dirty rate of vcpu.
+#
+# @id: vcpu index.
+#
+# @dirty-rate: dirty rate.
+#
+# Since: 6.2
+#
+##
+{ 'struct': 'DirtyRateVcpu',
+ 'data': { 'id': 'int', 'dirty-rate': 'int64' } }
+
+##
+# @DirtyRateStatus:
+#
+# An enumeration of dirtyrate status.
+#
+# @unstarted: the dirtyrate thread has not been started.
+#
+# @measuring: the dirtyrate thread is measuring.
+#
+# @measured: the dirtyrate thread has measured and results are available.
+#
+# Since: 5.2
+#
+##
+{ 'enum': 'DirtyRateStatus',
+ 'data': [ 'unstarted', 'measuring', 'measured'] }
+
+##
+# @DirtyRateMeasureMode:
+#
+# An enumeration of mode of measuring dirtyrate.
+#
+# @page-sampling: calculate dirtyrate by sampling pages.
+#
+# @dirty-ring: calculate dirtyrate by dirty ring.
+#
+# @dirty-bitmap: calculate dirtyrate by dirty bitmap.
+#
+# Since: 6.2
+#
+##
+{ 'enum': 'DirtyRateMeasureMode',
+ 'data': ['page-sampling', 'dirty-ring', 'dirty-bitmap'] }
+
+##
+# @DirtyRateInfo:
+#
+# Information about current dirty page rate of vm.
+#
+# @dirty-rate: an estimate of the dirty page rate of the VM in units of
+# MB/s, present only when estimating the rate has completed.
+#
+# @status: status containing dirtyrate query status includes
+# 'unstarted' or 'measuring' or 'measured'
+#
+# @start-time: start time in units of second for calculation
+#
+# @calc-time: time in units of second for sample dirty pages
+#
+# @sample-pages: page count per GB for sample dirty pages
+# the default value is 512 (since 6.1)
+#
+# @mode: mode containing method of calculate dirtyrate includes
+# 'page-sampling' and 'dirty-ring' (Since 6.2)
+#
+# @vcpu-dirty-rate: dirtyrate for each vcpu if dirty-ring
+# mode specified (Since 6.2)
+#
+# Since: 5.2
+#
+##
+{ 'struct': 'DirtyRateInfo',
+ 'data': {'*dirty-rate': 'int64',
+ 'status': 'DirtyRateStatus',
+ 'start-time': 'int64',
+ 'calc-time': 'int64',
+ 'sample-pages': 'uint64',
+ 'mode': 'DirtyRateMeasureMode',
+ '*vcpu-dirty-rate': [ 'DirtyRateVcpu' ] } }
+
+##
+# @calc-dirty-rate:
+#
+# start calculating dirty page rate for vm
+#
+# @calc-time: time in units of second for sample dirty pages
+#
+# @sample-pages: page count per GB for sample dirty pages
+# the default value is 512 (since 6.1)
+#
+# @mode: mechanism of calculating dirtyrate includes
+# 'page-sampling' and 'dirty-ring' (Since 6.1)
+#
+# Since: 5.2
+#
+# Example:
+# {"command": "calc-dirty-rate", "arguments": {"calc-time": 1,
+# 'sample-pages': 512} }
+#
+##
+{ 'command': 'calc-dirty-rate', 'data': {'calc-time': 'int64',
+ '*sample-pages': 'int',
+ '*mode': 'DirtyRateMeasureMode'} }
+
+##
+# @query-dirty-rate:
+#
+# query dirty page rate in units of MB/s for vm
+#
+# Since: 5.2
+##
+{ 'command': 'query-dirty-rate', 'returns': 'DirtyRateInfo' }
+
+##
+# @snapshot-save:
+#
+# Save a VM snapshot
+#
+# @job-id: identifier for the newly created job
+# @tag: name of the snapshot to create
+# @vmstate: block device node name to save vmstate to
+# @devices: list of block device node names to save a snapshot to
+#
+# Applications should not assume that the snapshot save is complete
+# when this command returns. The job commands / events must be used
+# to determine completion and to fetch details of any errors that arise.
+#
+# Note that execution of the guest CPUs may be stopped during the
+# time it takes to save the snapshot. A future version of QEMU
+# may ensure CPUs are executing continuously.
+#
+# It is strongly recommended that @devices contain all writable
+# block device nodes if a consistent snapshot is required.
+#
+# If @tag already exists, an error will be reported
+#
+# Returns: nothing
+#
+# Example:
+#
+# -> { "execute": "snapshot-save",
+# "arguments": {
+# "job-id": "snapsave0",
+# "tag": "my-snap",
+# "vmstate": "disk0",
+# "devices": ["disk0", "disk1"]
+# }
+# }
+# <- { "return": { } }
+# <- {"event": "JOB_STATUS_CHANGE",
+# "data": {"status": "created", "id": "snapsave0"}}
+# <- {"event": "JOB_STATUS_CHANGE",
+# "data": {"status": "running", "id": "snapsave0"}}
+# <- {"event": "STOP"}
+# <- {"event": "RESUME"}
+# <- {"event": "JOB_STATUS_CHANGE",
+# "data": {"status": "waiting", "id": "snapsave0"}}
+# <- {"event": "JOB_STATUS_CHANGE",
+# "data": {"status": "pending", "id": "snapsave0"}}
+# <- {"event": "JOB_STATUS_CHANGE",
+# "data": {"status": "concluded", "id": "snapsave0"}}
+# -> {"execute": "query-jobs"}
+# <- {"return": [{"current-progress": 1,
+# "status": "concluded",
+# "total-progress": 1,
+# "type": "snapshot-save",
+# "id": "snapsave0"}]}
+#
+# Since: 6.0
+##
+{ 'command': 'snapshot-save',
+ 'data': { 'job-id': 'str',
+ 'tag': 'str',
+ 'vmstate': 'str',
+ 'devices': ['str'] } }
+
+##
+# @snapshot-load:
+#
+# Load a VM snapshot
+#
+# @job-id: identifier for the newly created job
+# @tag: name of the snapshot to load.
+# @vmstate: block device node name to load vmstate from
+# @devices: list of block device node names to load a snapshot from
+#
+# Applications should not assume that the snapshot load is complete
+# when this command returns. The job commands / events must be used
+# to determine completion and to fetch details of any errors that arise.
+#
+# Note that execution of the guest CPUs will be stopped during the
+# time it takes to load the snapshot.
+#
+# It is strongly recommended that @devices contain all writable
+# block device nodes that can have changed since the original
+# @snapshot-save command execution.
+#
+# Returns: nothing
+#
+# Example:
+#
+# -> { "execute": "snapshot-load",
+# "arguments": {
+# "job-id": "snapload0",
+# "tag": "my-snap",
+# "vmstate": "disk0",
+# "devices": ["disk0", "disk1"]
+# }
+# }
+# <- { "return": { } }
+# <- {"event": "JOB_STATUS_CHANGE",
+# "data": {"status": "created", "id": "snapload0"}}
+# <- {"event": "JOB_STATUS_CHANGE",
+# "data": {"status": "running", "id": "snapload0"}}
+# <- {"event": "STOP"}
+# <- {"event": "RESUME"}
+# <- {"event": "JOB_STATUS_CHANGE",
+# "data": {"status": "waiting", "id": "snapload0"}}
+# <- {"event": "JOB_STATUS_CHANGE",
+# "data": {"status": "pending", "id": "snapload0"}}
+# <- {"event": "JOB_STATUS_CHANGE",
+# "data": {"status": "concluded", "id": "snapload0"}}
+# -> {"execute": "query-jobs"}
+# <- {"return": [{"current-progress": 1,
+# "status": "concluded",
+# "total-progress": 1,
+# "type": "snapshot-load",
+# "id": "snapload0"}]}
+#
+# Since: 6.0
+##
+{ 'command': 'snapshot-load',
+ 'data': { 'job-id': 'str',
+ 'tag': 'str',
+ 'vmstate': 'str',
+ 'devices': ['str'] } }
+
+##
+# @snapshot-delete:
+#
+# Delete a VM snapshot
+#
+# @job-id: identifier for the newly created job
+# @tag: name of the snapshot to delete.
+# @devices: list of block device node names to delete a snapshot from
+#
+# Applications should not assume that the snapshot delete is complete
+# when this command returns. The job commands / events must be used
+# to determine completion and to fetch details of any errors that arise.
+#
+# Returns: nothing
+#
+# Example:
+#
+# -> { "execute": "snapshot-delete",
+# "arguments": {
+# "job-id": "snapdelete0",
+# "tag": "my-snap",
+# "devices": ["disk0", "disk1"]
+# }
+# }
+# <- { "return": { } }
+# <- {"event": "JOB_STATUS_CHANGE",
+# "data": {"status": "created", "id": "snapdelete0"}}
+# <- {"event": "JOB_STATUS_CHANGE",
+# "data": {"status": "running", "id": "snapdelete0"}}
+# <- {"event": "JOB_STATUS_CHANGE",
+# "data": {"status": "waiting", "id": "snapdelete0"}}
+# <- {"event": "JOB_STATUS_CHANGE",
+# "data": {"status": "pending", "id": "snapdelete0"}}
+# <- {"event": "JOB_STATUS_CHANGE",
+# "data": {"status": "concluded", "id": "snapdelete0"}}
+# -> {"execute": "query-jobs"}
+# <- {"return": [{"current-progress": 1,
+# "status": "concluded",
+# "total-progress": 1,
+# "type": "snapshot-delete",
+# "id": "snapdelete0"}]}
+#
+# Since: 6.0
+##
+{ 'command': 'snapshot-delete',
+ 'data': { 'job-id': 'str',
+ 'tag': 'str',
+ 'devices': ['str'] } }