#
# @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',
- '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',
- 'precopy-bytes' : 'uint64', 'downtime-bytes' : 'uint64',
- 'postcopy-bytes' : 'uint64',
- 'dirty-sync-missed-zero-copy' : 'uint64' } }
+ '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',
+ 'multifd-bytes': 'uint64', 'pages-per-second': 'uint64',
+ 'precopy-bytes': 'uint64', 'downtime-bytes': 'uint64',
+ 'postcopy-bytes': 'uint64',
+ 'dirty-sync-missed-zero-copy': 'uint64' } }
##
# @XBZRLECacheStats:
# 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',
'*cpu-throttle-percentage': 'int',
'*error-desc': 'str',
'*blocked-reasons': ['str'],
- '*postcopy-blocktime' : 'uint32',
+ '*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)
# block 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 that is
-# accessible on the destination machine. (since 4.0)
+# @x-ignore-shared: If enabled, QEMU will not migrate shared memory
+# that is accessible on the destination machine. (since 4.0)
#
# @validate-uuid: Send the UUID of the source to allow the destination
# to ensure it is the same. (since 4.2)
# and should not affect the correctness of postcopy migration.
# (since 7.1)
#
+# @switchover-ack: If enabled, migration will not stop the source VM
+# and complete the migration until an ACK is received from the
+# destination that it's OK to do so. Exactly when this ACK is
+# sent depends on the migrated devices that use this feature. For
+# example, a device can use it to make sure some of its data is
+# sent and loaded in the destination before doing switchover.
+# This can reduce downtime if devices that support this capability
+# 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'] }
+ 'zero-copy-send', 'postcopy-preempt', 'switchover-ack',
+ 'dirty-limit'] }
##
# @MigrationCapabilityStatus:
# Since: 1.2
##
{ 'struct': 'MigrationCapabilityStatus',
- 'data': { 'capability' : 'MigrationCapability', 'state' : 'bool' } }
+ 'data': { 'capability': 'MigrationCapability', 'state': 'bool' } }
##
# @migrate-set-capabilities:
'data': [ 'none', 'zlib',
{ 'name': 'zstd', 'if': 'CONFIG_ZSTD' } ] }
+##
+# @MigMode:
+#
+# @normal: the original form of migration. (since 8.2)
+#
+# @cpr-reboot: The migrate command saves state to a file, allowing one to
+# quit qemu, reboot to an updated kernel, and restart an updated
+# version of qemu. The caller must specify a migration URI
+# that writes to and reads from a file. Unlike normal mode,
+# the use of certain local storage options does not block the
+# migration, but the caller must not modify guest block devices
+# between the quit and restart. To avoid saving guest RAM to the
+# file, the memory backend must be shared, and the @x-ignore-shared
+# migration capability must be set. Guest RAM must be non-volatile
+# across reboot, such as by backing it with a dax device, but this
+# is not enforced. The restarted qemu arguments must match those
+# used to initially start qemu, plus the -incoming option.
+# (since 8.2)
+##
+{ 'enum': 'MigMode',
+ 'data': [ 'normal', 'cpr-reboot' ] }
+
##
# @BitmapMigrationBitmapAliasTransform:
#
# @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)
+#
+# @mode: Migration mode. See description in @MigMode. Default is 'normal'.
+# (Since 8.2)
+#
# 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',
+ 'mode'] }
##
# @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)
+#
+# @mode: Migration mode. See description in @MigMode. Default is 'normal'.
+# (Since 8.2)
+#
# 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',
+ '*mode': 'MigMode'} }
##
# @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)
+#
+# @mode: Migration mode. See description in @MigMode. Default is 'normal'.
+# (Since 8.2)
+#
# 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',
+ '*mode': 'MigMode'} }
##
# @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
##
{ 'command': 'migrate-continue', 'data': {'state': 'MigrationStatus'} }
+##
+# @MigrationAddressType:
+#
+# The migration stream transport mechanisms.
+#
+# @socket: Migrate via socket.
+#
+# @exec: Direct the migration stream to another process.
+#
+# @rdma: Migrate via RDMA.
+#
+# @file: Direct the migration stream to a file.
+#
+# Since 8.2
+##
+{ 'enum': 'MigrationAddressType',
+ 'data': [ 'socket', 'exec', 'rdma', 'file' ] }
+
+##
+# @FileMigrationArgs:
+#
+# @filename: The file to receive the migration stream
+#
+# @offset: The file offset where the migration stream will start
+#
+# Since 8.2
+##
+{ 'struct': 'FileMigrationArgs',
+ 'data': { 'filename': 'str',
+ 'offset': 'uint64' } }
+
+##
+# @MigrationExecCommand:
+#
+# @args: command (list head) and arguments to execute.
+#
+# Since 8.2
+##
+{ 'struct': 'MigrationExecCommand',
+ 'data': {'args': [ 'str' ] } }
+
+##
+# @MigrationAddress:
+#
+# Migration endpoint configuration.
+#
+# Since 8.2
+##
+{ 'union': 'MigrationAddress',
+ 'base': { 'transport' : 'MigrationAddressType'},
+ 'discriminator': 'transport',
+ 'data': {
+ 'socket': 'SocketAddress',
+ 'exec': 'MigrationExecCommand',
+ 'rdma': 'InetSocketAddress',
+ 'file': 'FileMigrationArgs' } }
+
+##
+# @MigrationChannelType:
+#
+# The migration channel-type request options.
+#
+# @main: Main outbound migration channel.
+#
+# Since 8.1
+##
+{ 'enum': 'MigrationChannelType',
+ 'data': [ 'main' ] }
+
+##
+# @MigrationChannel:
+#
+# Migration stream channel parameters.
+#
+# @channel-type: Channel type for transferring packet information.
+#
+# @addr: Migration endpoint configuration on destination interface.
+#
+# Since 8.1
+##
+{ 'struct': 'MigrationChannel',
+ 'data': {
+ 'channel-type': 'MigrationChannelType',
+ 'addr': 'MigrationAddress' } }
+
##
# @migrate:
#
#
# @uri: the Uniform Resource Identifier of the destination VM
#
+# @channels: list of migration stream channels with each stream in the
+# list connected to a destination interface endpoint.
+#
# @blk: do block migration (full disk copy)
#
# @inc: incremental disk copy migration
#
# @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
# 3. The user Monitor's "detach" argument is invalid in QMP and should
# not be used
#
+# 4. The uri argument should have the Uniform Resource Identifier of
+# default destination VM. This connection will be bound to default
+# network.
+#
+# 5. For now, number of migration streams is restricted to one, i.e
+# number of items in 'channels' list is just 1.
+#
+# 6. The 'uri' and 'channels' arguments are mutually exclusive;
+# exactly one of the two should be present.
+#
# Example:
#
# -> { "execute": "migrate", "arguments": { "uri": "tcp:0:4446" } }
# <- { "return": {} }
+# -> { "execute": "migrate",
+# "arguments": {
+# "channels": [ { "channel-type": "main",
+# "addr": { "transport": "socket",
+# "type": "inet",
+# "host": "10.12.34.9",
+# "port": "1050" } } ] } }
+# <- { "return": {} }
+#
+# -> { "execute": "migrate",
+# "arguments": {
+# "channels": [ { "channel-type": "main",
+# "addr": { "transport": "exec",
+# "args": [ "/bin/nc", "-p", "6000",
+# "/some/sock" ] } } ] } }
+# <- { "return": {} }
+#
+# -> { "execute": "migrate",
+# "arguments": {
+# "channels": [ { "channel-type": "main",
+# "addr": { "transport": "rdma",
+# "host": "10.12.34.9",
+# "port": "1050" } } ] } }
+# <- { "return": {} }
+#
+# -> { "execute": "migrate",
+# "arguments": {
+# "channels": [ { "channel-type": "main",
+# "addr": { "transport": "file",
+# "filename": "/tmp/migfile",
+# "offset": "0x1000" } } ] } }
+# <- { "return": {} }
+#
##
{ 'command': 'migrate',
- 'data': {'uri': 'str', '*blk': 'bool', '*inc': 'bool',
+ 'data': {'uri': 'str',
+ '*channels': [ 'MigrationChannel' ],
+ '*blk': { 'type': 'bool', 'features': [ 'deprecated' ] },
+ '*inc': { 'type': 'bool', 'features': [ 'deprecated' ] },
'*detach': 'bool', '*resume': 'bool' } }
##
# @uri: The Uniform Resource Identifier identifying the source or
# address to listen on
#
+# @channels: list of migration stream channels with each stream in the
+# list connected to a destination interface endpoint.
+#
# Returns: nothing on success
#
# Since: 2.3
#
# 3. The uri format is the same as for -incoming
#
+# 5. For now, number of migration streams is restricted to one, i.e
+# number of items in 'channels' list is just 1.
+#
+# 4. The 'uri' and 'channels' arguments are mutually exclusive;
+# exactly one of the two should be present.
+#
# Example:
#
# -> { "execute": "migrate-incoming",
# "arguments": { "uri": "tcp::4446" } }
# <- { "return": {} }
+#
+# -> { "execute": "migrate",
+# "arguments": {
+# "channels": [ { "channel-type": "main",
+# "addr": { "transport": "socket",
+# "type": "inet",
+# "host": "10.12.34.9",
+# "port": "1050" } } ] } }
+# <- { "return": {} }
+#
+# -> { "execute": "migrate",
+# "arguments": {
+# "channels": [ { "channel-type": "main",
+# "addr": { "transport": "exec",
+# "args": [ "/bin/nc", "-p", "6000",
+# "/some/sock" ] } } ] } }
+# <- { "return": {} }
+#
+# -> { "execute": "migrate",
+# "arguments": {
+# "channels": [ { "channel-type": "main",
+# "addr": { "transport": "rdma",
+# "host": "10.12.34.9",
+# "port": "1050" } } ] } }
+# <- { "return": {} }
##
-{ 'command': 'migrate-incoming', 'data': {'uri': 'str' } }
+{ 'command': 'migrate-incoming',
+ 'data': {'*uri': 'str',
+ '*channels': [ 'MigrationChannel' ] } }
##
# @xen-save-devices-state:
# Since: 2.9
##
{ 'command': 'xen-set-replication',
- 'data': { 'enable': 'bool', 'primary': 'bool', '*failover' : 'bool' },
+ 'data': { 'enable': 'bool', 'primary': 'bool', '*failover': 'bool' },
'if': 'CONFIG_REPLICATION' }
##
##
# @DirtyRateStatus:
#
-# An enumeration of dirtyrate status.
+# Dirty page rate measurement status.
#
-# @unstarted: the dirtyrate thread has not been started.
+# @unstarted: measuring thread has not been started yet
#
-# @measuring: the dirtyrate thread is measuring.
+# @measuring: measuring thread is running
#
-# @measured: the dirtyrate thread has measured and results are
-# available.
+# @measured: dirty page rate is measured and the results are available
#
# Since: 5.2
##
##
# @DirtyRateMeasureMode:
#
-# An enumeration of mode of measuring dirtyrate.
+# Method used to measure dirty page rate. Differences between
+# available methods are explained in @calc-dirty-rate.
#
-# @page-sampling: calculate dirtyrate by sampling pages.
+# @page-sampling: use page sampling
#
-# @dirty-ring: calculate dirtyrate by dirty ring.
+# @dirty-ring: use dirty ring
#
-# @dirty-bitmap: calculate dirtyrate by dirty bitmap.
+# @dirty-bitmap: use dirty bitmap
#
# Since: 6.2
##
{ '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:
#
-# Information about current dirty page rate of vm.
+# Information about measured dirty page rate.
#
# @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.
+# of MiB/s. Value is present only when @status is 'measured'.
#
-# @status: status containing dirtyrate query status includes
-# 'unstarted' or 'measuring' or 'measured'
+# @status: current status of dirty page rate measurements
#
# @start-time: start time in units of second for calculation
#
-# @calc-time: time in units of second for sample dirty pages
+# @calc-time: time period for which dirty page rate was measured,
+# expressed and rounded down to @calc-time-unit.
#
-# @sample-pages: page count per GB for sample dirty pages the default
-# value is 512 (since 6.1)
+# @calc-time-unit: time unit of @calc-time (Since 8.2)
#
-# @mode: mode containing method of calculate dirtyrate includes
-# 'page-sampling' and 'dirty-ring' (Since 6.2)
+# @sample-pages: number of sampled pages per GiB of guest memory.
+# Valid only in page-sampling mode (Since 6.1)
#
-# @vcpu-dirty-rate: dirtyrate for each vcpu if dirty-ring mode
+# @mode: mode that was used to measure dirty page rate (Since 6.2)
+#
+# @vcpu-dirty-rate: dirty rate for each vCPU if dirty-ring mode was
# specified (Since 6.2)
#
# Since: 5.2
'status': 'DirtyRateStatus',
'start-time': 'int64',
'calc-time': 'int64',
+ 'calc-time-unit': 'TimeUnit',
'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)
+# Start measuring dirty page rate of the VM. Results can be retrieved
+# with @query-dirty-rate after measurements are completed.
+#
+# Dirty page rate is the number of pages changed in a given time
+# period expressed in MiB/s. The following methods of calculation are
+# available:
+#
+# 1. In page sampling mode, a random subset of pages are selected and
+# hashed twice: once at the beginning of measurement time period,
+# and once again at the end. If two hashes for some page are
+# different, the page is counted as changed. Since this method
+# relies on sampling and hashing, calculated dirty page rate is
+# only an estimate of its true value. Increasing @sample-pages
+# improves estimation quality at the cost of higher computational
+# overhead.
+#
+# 2. Dirty bitmap mode captures writes to memory (for example by
+# temporarily revoking write access to all pages) and counting page
+# faults. Information about modified pages is collected into a
+# bitmap, where each bit corresponds to one guest page. This mode
+# requires that KVM accelerator property "dirty-ring-size" is *not*
+# set.
+#
+# 3. Dirty ring mode is similar to dirty bitmap mode, but the
+# information about modified pages is collected into ring buffer.
+# This mode tracks page modification per each vCPU separately. It
+# requires that KVM accelerator property "dirty-ring-size" is set.
+#
+# @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
+# sampling ratio of 0.2%. This argument is used only in page
+# sampling mode. (Since 6.1)
+#
+# @mode: mechanism for tracking dirty pages. Default value is
+# 'page-sampling'. Others are 'dirty-bitmap' and 'dirty-ring'.
+# (Since 6.1)
#
# Since: 5.2
#
# -> {"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-dirty-rate:
#
-# query dirty page rate in units of MB/s for vm
+# 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": 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": 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: