#
# @duplicate: number of duplicate (zero) pages (since 1.2)
#
-# @skipped: number of skipped zero pages (since 1.5)
+# @skipped: number of skipped zero pages. Always zero, only provided for
+# compatibility (since 1.5)
#
# @normal: number of normal pages (since 1.2)
#
# between 0 and @dirty-sync-count * @multifd-channels. (since
# 7.1)
#
+# Features:
+#
+# @deprecated: Member @skipped is always zero since 1.5.3
+#
# Since: 0.14
+#
##
{ 'struct': 'MigrationStats',
'data': {'transferred': 'int', 'remaining': 'int', 'total': 'int' ,
- 'duplicate': 'int', 'skipped': 'int', 'normal': 'int',
+ 'duplicate': 'int',
+ 'skipped': { 'type': 'int', 'features': [ 'deprecated' ] },
+ 'normal': 'int',
'normal-bytes': 'int', 'dirty-pages-rate': 'int',
'mbps': 'number', 'dirty-sync-count': 'int',
'postcopy-requests': 'int', 'page-size': 'int',
# 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)
+# @error-desc: the human readable error description string. 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
# blocked. Present and non-empty when migration is blocked.
# (since 6.0)
#
+# @dirty-limit-throttle-time-per-round: Maximum throttle time
+# (in microseconds) of virtual CPUs each dirty ring full round,
+# which shows how MigrationCapability dirty-limit affects the
+# guest during live migration. (Since 8.1)
+#
+# @dirty-limit-ring-full-time: Estimated average dirty ring full time
+# (in microseconds) for each dirty ring full round. The value
+# equals the dirty ring memory size divided by the average dirty
+# page rate of the virtual CPU, which can be used to observe the
+# average memory load of the virtual CPU indirectly. Note that
+# zero means guest doesn't dirty memory. (Since 8.1)
+#
+# Features:
+#
+# @deprecated: Member @disk is deprecated because block migration is.
+# Member @compression is deprecated because it is unreliable and
+# untested. It is recommended to use multifd migration, which
+# offers an alternative compression implementation that is
+# reliable and tested.
+#
# Since: 0.14
##
{ 'struct': 'MigrationInfo',
'data': {'*status': 'MigrationStatus', '*ram': 'MigrationStats',
- '*disk': 'MigrationStats',
+ '*disk': { 'type': 'MigrationStats', 'features': [ 'deprecated' ] },
'*vfio': 'VfioStats',
'*xbzrle-cache': 'XBZRLECacheStats',
'*total-time': 'int',
'*blocked-reasons': ['str'],
'*postcopy-blocktime': 'uint32',
'*postcopy-vcpu-blocktime': ['uint32'],
- '*compression': 'CompressionStats',
- '*socket-address': ['SocketAddress'] } }
+ '*compression': { 'type': 'CompressionStats', 'features': [ 'deprecated' ] },
+ '*socket-address': ['SocketAddress'],
+ '*dirty-limit-throttle-time-per-round': 'uint64',
+ '*dirty-limit-ring-full-time': 'uint64'} }
##
# @query-migrate:
# 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 )
+# traffic. The feature is disabled by default. (since 2.4)
#
-# @events: generate events for each migration state change (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)
# are present. 'return-path' capability must be enabled to use
# it. (since 8.1)
#
+# @dirty-limit: If enabled, migration will throttle vCPUs as needed to
+# keep their dirty page rate within @vcpu-dirty-limit. This can
+# improve responsiveness of large guests during live migration,
+# and can result in more stable read performance. Requires KVM
+# with accelerator property "dirty-ring-size" set. (Since 8.1)
+#
# Features:
#
+# @deprecated: Member @block is deprecated. Use blockdev-mirror with
+# NBD instead. Member @compression is deprecated because it is
+# unreliable and untested. It is recommended to use multifd
+# migration, which offers an alternative compression
+# implementation that is reliable and tested.
+#
# @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',
+ { 'name': 'compress', 'features': [ 'deprecated' ] },
+ 'events', 'postcopy-ram',
{ 'name': 'x-colo', 'features': [ 'unstable' ] },
'release-ram',
- 'block', 'return-path', 'pause-before-switchover', 'multifd',
+ { 'name': 'block', 'features': [ 'deprecated' ] },
+ 'return-path', 'pause-before-switchover', 'multifd',
'dirty-bitmaps', 'postcopy-blocktime', 'late-block-activate',
{ 'name': 'x-ignore-shared', 'features': [ 'unstable' ] },
'validate-uuid', 'background-snapshot',
- 'zero-copy-send', 'postcopy-preempt', 'switchover-ack'] }
+ 'zero-copy-send', 'postcopy-preempt', 'switchover-ack',
+ 'dirty-limit'] }
##
# @MigrationCapabilityStatus:
# @max-bandwidth: to set maximum speed for migration. maximum speed
# in bytes per second. (Since 2.8)
#
+# @avail-switchover-bandwidth: to set the available bandwidth that
+# migration can use during switchover phase. NOTE! This does not
+# limit the bandwidth during switchover, but only for calculations when
+# making decisions to switchover. By default, this value is zero,
+# which means QEMU will estimate the bandwidth automatically. This can
+# be set when the estimated value is not accurate, while the user is
+# able to guarantee such bandwidth is available when switching over.
+# When specified correctly, this can make the switchover decision much
+# more accurate. (Since 8.2)
+#
# @downtime-limit: set maximum tolerated downtime for migration.
# maximum downtime in milliseconds (Since 2.8)
#
# Nodes are mapped to their block device name if there is one, and
# to their node name otherwise. (Since 5.2)
#
+# @x-vcpu-dirty-limit-period: Periodic time (in milliseconds) of dirty
+# limit during live migration. Should be in the range 1 to 1000ms.
+# Defaults to 1000ms. (Since 8.1)
+#
+# @vcpu-dirty-limit: Dirtyrate limit (MB/s) during live migration.
+# Defaults to 1. (Since 8.1)
+#
# Features:
#
-# @unstable: Member @x-checkpoint-delay is experimental.
+# @deprecated: Member @block-incremental is deprecated. Use
+# blockdev-mirror with NBD instead. Members @compress-level,
+# @compress-threads, @decompress-threads and @compress-wait-thread
+# are deprecated because @compression is deprecated.
+#
+# @unstable: Members @x-checkpoint-delay and @x-vcpu-dirty-limit-period
+# are experimental.
#
# Since: 2.4
##
{ 'enum': 'MigrationParameter',
'data': ['announce-initial', 'announce-max',
'announce-rounds', 'announce-step',
- 'compress-level', 'compress-threads', 'decompress-threads',
- 'compress-wait-thread', 'throttle-trigger-threshold',
+ { 'name': 'compress-level', 'features': [ 'deprecated' ] },
+ { 'name': 'compress-threads', 'features': [ 'deprecated' ] },
+ { 'name': 'decompress-threads', 'features': [ 'deprecated' ] },
+ { 'name': 'compress-wait-thread', 'features': [ 'deprecated' ] },
+ 'throttle-trigger-threshold',
'cpu-throttle-initial', 'cpu-throttle-increment',
'cpu-throttle-tailslow',
'tls-creds', 'tls-hostname', 'tls-authz', 'max-bandwidth',
- 'downtime-limit',
+ 'avail-switchover-bandwidth', 'downtime-limit',
{ 'name': 'x-checkpoint-delay', 'features': [ 'unstable' ] },
- 'block-incremental',
+ { 'name': 'block-incremental', 'features': [ 'deprecated' ] },
'multifd-channels',
'xbzrle-cache-size', 'max-postcopy-bandwidth',
'max-cpu-throttle', 'multifd-compression',
- 'multifd-zlib-level' ,'multifd-zstd-level',
- 'block-bitmap-mapping' ] }
+ 'multifd-zlib-level', 'multifd-zstd-level',
+ 'block-bitmap-mapping',
+ { 'name': 'x-vcpu-dirty-limit-period', 'features': ['unstable'] },
+ 'vcpu-dirty-limit'] }
##
# @MigrateSetParameters:
# @max-bandwidth: to set maximum speed for migration. maximum speed
# in bytes per second. (Since 2.8)
#
+# @avail-switchover-bandwidth: to set the available bandwidth that
+# migration can use during switchover phase. NOTE! This does not
+# limit the bandwidth during switchover, but only for calculations when
+# making decisions to switchover. By default, this value is zero,
+# which means QEMU will estimate the bandwidth automatically. This can
+# be set when the estimated value is not accurate, while the user is
+# able to guarantee such bandwidth is available when switching over.
+# When specified correctly, this can make the switchover decision much
+# more accurate. (Since 8.2)
+#
# @downtime-limit: set maximum tolerated downtime for migration.
# maximum downtime in milliseconds (Since 2.8)
#
# Nodes are mapped to their block device name if there is one, and
# to their node name otherwise. (Since 5.2)
#
+# @x-vcpu-dirty-limit-period: Periodic time (in milliseconds) of dirty
+# limit during live migration. Should be in the range 1 to 1000ms.
+# Defaults to 1000ms. (Since 8.1)
+#
+# @vcpu-dirty-limit: Dirtyrate limit (MB/s) during live migration.
+# Defaults to 1. (Since 8.1)
+#
# Features:
#
-# @unstable: Member @x-checkpoint-delay is experimental.
+# @deprecated: Member @block-incremental is deprecated. Use
+# blockdev-mirror with NBD instead. Members @compress-level,
+# @compress-threads, @decompress-threads and @compress-wait-thread
+# are deprecated because @compression is deprecated.
+#
+# @unstable: Members @x-checkpoint-delay and @x-vcpu-dirty-limit-period
+# are experimental.
#
# TODO: either fuse back into MigrationParameters, or make
# MigrationParameters members mandatory
'*announce-max': 'size',
'*announce-rounds': 'size',
'*announce-step': 'size',
- '*compress-level': 'uint8',
- '*compress-threads': 'uint8',
- '*compress-wait-thread': 'bool',
- '*decompress-threads': 'uint8',
+ '*compress-level': { 'type': 'uint8',
+ 'features': [ 'deprecated' ] },
+ '*compress-threads': { 'type': 'uint8',
+ 'features': [ 'deprecated' ] },
+ '*compress-wait-thread': { 'type': 'bool',
+ 'features': [ 'deprecated' ] },
+ '*decompress-threads': { 'type': 'uint8',
+ 'features': [ 'deprecated' ] },
'*throttle-trigger-threshold': 'uint8',
'*cpu-throttle-initial': 'uint8',
'*cpu-throttle-increment': 'uint8',
'*tls-hostname': 'StrOrNull',
'*tls-authz': 'StrOrNull',
'*max-bandwidth': 'size',
+ '*avail-switchover-bandwidth': 'size',
'*downtime-limit': 'uint64',
'*x-checkpoint-delay': { 'type': 'uint32',
'features': [ 'unstable' ] },
- '*block-incremental': 'bool',
+ '*block-incremental': { 'type': 'bool',
+ 'features': [ 'deprecated' ] },
'*multifd-channels': 'uint8',
'*xbzrle-cache-size': 'size',
'*max-postcopy-bandwidth': 'size',
'*multifd-compression': 'MultiFDCompression',
'*multifd-zlib-level': 'uint8',
'*multifd-zstd-level': 'uint8',
- '*block-bitmap-mapping': [ 'BitmapMigrationNodeAlias' ] } }
+ '*block-bitmap-mapping': [ 'BitmapMigrationNodeAlias' ],
+ '*x-vcpu-dirty-limit-period': { 'type': 'uint64',
+ 'features': [ 'unstable' ] },
+ '*vcpu-dirty-limit': 'uint64'} }
##
# @migrate-set-parameters:
# Example:
#
# -> { "execute": "migrate-set-parameters" ,
-# "arguments": { "compress-level": 1 } }
+# "arguments": { "multifd-channels": 5 } }
# <- { "return": {} }
##
{ 'command': 'migrate-set-parameters', 'boxed': true,
# @max-bandwidth: to set maximum speed for migration. maximum speed
# in bytes per second. (Since 2.8)
#
+# @avail-switchover-bandwidth: to set the available bandwidth that
+# migration can use during switchover phase. NOTE! This does not
+# limit the bandwidth during switchover, but only for calculations when
+# making decisions to switchover. By default, this value is zero,
+# which means QEMU will estimate the bandwidth automatically. This can
+# be set when the estimated value is not accurate, while the user is
+# able to guarantee such bandwidth is available when switching over.
+# When specified correctly, this can make the switchover decision much
+# more accurate. (Since 8.2)
+#
# @downtime-limit: set maximum tolerated downtime for migration.
# maximum downtime in milliseconds (Since 2.8)
#
# Nodes are mapped to their block device name if there is one, and
# to their node name otherwise. (Since 5.2)
#
+# @x-vcpu-dirty-limit-period: Periodic time (in milliseconds) of dirty
+# limit during live migration. Should be in the range 1 to 1000ms.
+# Defaults to 1000ms. (Since 8.1)
+#
+# @vcpu-dirty-limit: Dirtyrate limit (MB/s) during live migration.
+# Defaults to 1. (Since 8.1)
+#
# Features:
#
-# @unstable: Member @x-checkpoint-delay is experimental.
+# @deprecated: Member @block-incremental is deprecated. Use
+# blockdev-mirror with NBD instead. Members @compress-level,
+# @compress-threads, @decompress-threads and @compress-wait-thread
+# are deprecated because @compression is deprecated.
+#
+# @unstable: Members @x-checkpoint-delay and @x-vcpu-dirty-limit-period
+# are experimental.
#
# Since: 2.4
##
'*announce-max': 'size',
'*announce-rounds': 'size',
'*announce-step': 'size',
- '*compress-level': 'uint8',
- '*compress-threads': 'uint8',
- '*compress-wait-thread': 'bool',
- '*decompress-threads': 'uint8',
+ '*compress-level': { 'type': 'uint8',
+ 'features': [ 'deprecated' ] },
+ '*compress-threads': { 'type': 'uint8',
+ 'features': [ 'deprecated' ] },
+ '*compress-wait-thread': { 'type': 'bool',
+ 'features': [ 'deprecated' ] },
+ '*decompress-threads': { 'type': 'uint8',
+ 'features': [ 'deprecated' ] },
'*throttle-trigger-threshold': 'uint8',
'*cpu-throttle-initial': 'uint8',
'*cpu-throttle-increment': 'uint8',
'*tls-hostname': 'str',
'*tls-authz': 'str',
'*max-bandwidth': 'size',
+ '*avail-switchover-bandwidth': 'size',
'*downtime-limit': 'uint64',
'*x-checkpoint-delay': { 'type': 'uint32',
'features': [ 'unstable' ] },
- '*block-incremental': 'bool',
+ '*block-incremental': { 'type': 'bool',
+ 'features': [ 'deprecated' ] },
'*multifd-channels': 'uint8',
'*xbzrle-cache-size': 'size',
'*max-postcopy-bandwidth': 'size',
'*multifd-compression': 'MultiFDCompression',
'*multifd-zlib-level': 'uint8',
'*multifd-zstd-level': 'uint8',
- '*block-bitmap-mapping': [ 'BitmapMigrationNodeAlias' ] } }
+ '*block-bitmap-mapping': [ 'BitmapMigrationNodeAlias' ],
+ '*x-vcpu-dirty-limit-period': { 'type': 'uint64',
+ 'features': [ 'unstable' ] },
+ '*vcpu-dirty-limit': 'uint64'} }
##
# @query-migrate-parameters:
#
# -> { "execute": "query-migrate-parameters" }
# <- { "return": {
-# "decompress-threads": 2,
+# "multifd-channels": 2,
# "cpu-throttle-increment": 10,
-# "compress-threads": 8,
-# "compress-level": 1,
# "cpu-throttle-initial": 20,
# "max-bandwidth": 33554432,
# "downtime-limit": 300
#
# @resume: resume one paused migration, default "off". (since 3.0)
#
+# Features:
+#
+# @deprecated: Members @inc and @blk are deprecated. Use
+# blockdev-mirror with NBD instead.
+#
# Returns: nothing on success
#
# Since: 0.14
# <- { "return": {} }
##
{ 'command': 'migrate',
- 'data': {'uri': 'str', '*blk': 'bool', '*inc': 'bool',
+ 'data': {'uri': 'str',
+ '*blk': { 'type': 'bool', 'features': [ 'deprecated' ] },
+ '*inc': { 'type': 'bool', 'features': [ 'deprecated' ] },
'*detach': 'bool', '*resume': 'bool' } }
##
{ 'enum': 'DirtyRateMeasureMode',
'data': ['page-sampling', 'dirty-ring', 'dirty-bitmap'] }
+##
+# @TimeUnit:
+#
+# Specifies unit in which time-related value is specified.
+#
+# @second: value is in seconds
+#
+# @millisecond: value is in milliseconds
+#
+# Since 8.2
+#
+##
+{ 'enum': 'TimeUnit',
+ 'data': ['second', 'millisecond'] }
+
##
# @DirtyRateInfo:
#
#
# @start-time: start time in units of second for calculation
#
-# @calc-time: time period for which dirty page rate was measured
-# (in seconds)
+# @calc-time: time period for which dirty page rate was measured,
+# expressed and rounded down to @calc-time-unit.
+#
+# @calc-time-unit: time unit of @calc-time (Since 8.2)
#
# @sample-pages: number of sampled pages per GiB of guest memory.
# Valid only in page-sampling mode (Since 6.1)
'status': 'DirtyRateStatus',
'start-time': 'int64',
'calc-time': 'int64',
+ 'calc-time-unit': 'TimeUnit',
'sample-pages': 'uint64',
'mode': 'DirtyRateMeasureMode',
'*vcpu-dirty-rate': [ 'DirtyRateVcpu' ] } }
# This mode tracks page modification per each vCPU separately. It
# requires that KVM accelerator property "dirty-ring-size" is set.
#
-# @calc-time: time period in units of second for which dirty page rate
-# is calculated. Note that larger @calc-time values will
-# typically result in smaller dirty page rates because page
-# dirtying is a one-time event. Once some page is counted as
-# dirty during @calc-time period, further writes to this page will
-# not increase dirty page rate anymore.
+# @calc-time: time period for which dirty page rate is calculated.
+# By default it is specified in seconds, but the unit can be set
+# explicitly with @calc-time-unit. Note that larger @calc-time
+# values will typically result in smaller dirty page rates because
+# page dirtying is a one-time event. Once some page is counted
+# as dirty during @calc-time period, further writes to this page
+# will not increase dirty page rate anymore.
+#
+# @calc-time-unit: time unit in which @calc-time is specified.
+# By default it is seconds. (Since 8.2)
#
# @sample-pages: number of sampled pages per each GiB of guest memory.
# Default value is 512. For 4KiB guest pages this corresponds to
# -> {"execute": "calc-dirty-rate", "arguments": {"calc-time": 1,
# 'sample-pages': 512} }
# <- { "return": {} }
+#
+# Measure dirty rate using dirty bitmap for 500 milliseconds:
+#
+# -> {"execute": "calc-dirty-rate", "arguments": {"calc-time": 500,
+# "calc-time-unit": "millisecond", "mode": "dirty-bitmap"} }
+#
+# <- { "return": {} }
##
{ 'command': 'calc-dirty-rate', 'data': {'calc-time': 'int64',
+ '*calc-time-unit': 'TimeUnit',
'*sample-pages': 'int',
'*mode': 'DirtyRateMeasureMode'} }
#
# Query results of the most recent invocation of @calc-dirty-rate.
#
+# @calc-time-unit: time unit in which to report calculation time.
+# By default it is reported in seconds. (Since 8.2)
+#
# Since: 5.2
#
# Examples:
# 1. Measurement is in progress:
#
# <- {"status": "measuring", "sample-pages": 512,
-# "mode": "page-sampling", "start-time": 3665220, "calc-time": 10}
+# "mode": "page-sampling", "start-time": 1693900454, "calc-time": 10,
+# "calc-time-unit": "second"}
#
# 2. Measurement has been completed:
#
# <- {"status": "measured", "sample-pages": 512, "dirty-rate": 108,
-# "mode": "page-sampling", "start-time": 3665220, "calc-time": 10}
+# "mode": "page-sampling", "start-time": 1693900454, "calc-time": 10,
+# "calc-time-unit": "second"}
##
-{ 'command': 'query-dirty-rate', 'returns': 'DirtyRateInfo' }
+{ 'command': 'query-dirty-rate', 'data': {'*calc-time-unit': 'TimeUnit' },
+ 'returns': 'DirtyRateInfo' }
##
# @DirtyLimitInfo: