1# *-*- Mode: Python -*-* 2 3## 4# 5# General note concerning the use of guest agent interfaces: 6# 7# "unsupported" is a higher-level error than the errors that individual 8# commands might document. The caller should always be prepared to receive 9# QERR_UNSUPPORTED, even if the given command doesn't specify it, or doesn't 10# document any failure mode at all. 11# 12## 13 14## 15# 16# Echo back a unique integer value, and prepend to response a 17# leading sentinel byte (0xFF) the client can check scan for. 18# 19# This is used by clients talking to the guest agent over the 20# wire to ensure the stream is in sync and doesn't contain stale 21# data from previous client. It must be issued upon initial 22# connection, and after any client-side timeouts (including 23# timeouts on receiving a response to this command). 24# 25# After issuing this request, all guest agent responses should be 26# ignored until the response containing the unique integer value 27# the client passed in is returned. Receival of the 0xFF sentinel 28# byte must be handled as an indication that the client's 29# lexer/tokenizer/parser state should be flushed/reset in 30# preparation for reliably receiving the subsequent response. As 31# an optimization, clients may opt to ignore all data until a 32# sentinel value is receiving to avoid unnecessary processing of 33# stale data. 34# 35# Similarly, clients should also precede this *request* 36# with a 0xFF byte to make sure the guest agent flushes any 37# partially read JSON data from a previous client connection. 38# 39# @id: randomly generated 64-bit integer 40# 41# Returns: The unique integer id passed in by the client 42# 43# Since: 1.1 44# ## 45{ 'command': 'guest-sync-delimited', 46 'data': { 'id': 'int' }, 47 'returns': 'int' } 48 49## 50# @guest-sync: 51# 52# Echo back a unique integer value 53# 54# This is used by clients talking to the guest agent over the 55# wire to ensure the stream is in sync and doesn't contain stale 56# data from previous client. All guest agent responses should be 57# ignored until the provided unique integer value is returned, 58# and it is up to the client to handle stale whole or 59# partially-delivered JSON text in such a way that this response 60# can be obtained. 61# 62# In cases where a partial stale response was previously 63# received by the client, this cannot always be done reliably. 64# One particular scenario being if qemu-ga responses are fed 65# character-by-character into a JSON parser. In these situations, 66# using guest-sync-delimited may be optimal. 67# 68# For clients that fetch responses line by line and convert them 69# to JSON objects, guest-sync should be sufficient, but note that 70# in cases where the channel is dirty some attempts at parsing the 71# response may result in a parser error. 72# 73# Such clients should also precede this command 74# with a 0xFF byte to make sure the guest agent flushes any 75# partially read JSON data from a previous session. 76# 77# @id: randomly generated 64-bit integer 78# 79# Returns: The unique integer id passed in by the client 80# 81# Since: 0.15.0 82## 83{ 'command': 'guest-sync', 84 'data': { 'id': 'int' }, 85 'returns': 'int' } 86 87## 88# @guest-ping: 89# 90# Ping the guest agent, a non-error return implies success 91# 92# Since: 0.15.0 93## 94{ 'command': 'guest-ping' } 95 96## 97# @guest-get-time: 98# 99# Get the information about guest time relative to the Epoch 100# of 1970-01-01 in UTC. 101# 102# Returns: Time in nanoseconds. 103# 104# Since 1.5 105## 106{ 'command': 'guest-get-time', 107 'returns': 'int' } 108 109## 110# @guest-set-time: 111# 112# Set guest time. 113# 114# When a guest is paused or migrated to a file then loaded 115# from that file, the guest OS has no idea that there 116# was a big gap in the time. Depending on how long the 117# gap was, NTP might not be able to resynchronize the 118# guest. 119# 120# This command tries to set guest time to the given value, 121# then sets the Hardware Clock to the current System Time. 122# This will make it easier for a guest to resynchronize 123# without waiting for NTP. 124# 125# @time: time of nanoseconds, relative to the Epoch of 126# 1970-01-01 in UTC. 127# 128# Returns: Nothing on success. 129# 130# Since: 1.5 131## 132{ 'command': 'guest-set-time', 133 'data': { 'time': 'int' } } 134 135## 136# @GuestAgentCommandInfo: 137# 138# Information about guest agent commands. 139# 140# @name: name of the command 141# 142# @enabled: whether command is currently enabled by guest admin 143# 144# @success-response: whether command returns a response on success 145# (since 1.7) 146# 147# Since 1.1.0 148## 149{ 'type': 'GuestAgentCommandInfo', 150 'data': { 'name': 'str', 'enabled': 'bool', 'success-response': 'bool' } } 151 152## 153# @GuestAgentInfo 154# 155# Information about guest agent. 156# 157# @version: guest agent version 158# 159# @supported_commands: Information about guest agent commands 160# 161# Since 0.15.0 162## 163{ 'type': 'GuestAgentInfo', 164 'data': { 'version': 'str', 165 'supported_commands': ['GuestAgentCommandInfo'] } } 166## 167# @guest-info: 168# 169# Get some information about the guest agent. 170# 171# Returns: @GuestAgentInfo 172# 173# Since: 0.15.0 174## 175{ 'command': 'guest-info', 176 'returns': 'GuestAgentInfo' } 177 178## 179# @guest-shutdown: 180# 181# Initiate guest-activated shutdown. Note: this is an asynchronous 182# shutdown request, with no guarantee of successful shutdown. 183# 184# @mode: #optional "halt", "powerdown" (default), or "reboot" 185# 186# This command does NOT return a response on success. Success condition 187# is indicated by the VM exiting with a zero exit status or, when 188# running with --no-shutdown, by issuing the query-status QMP command 189# to confirm the VM status is "shutdown". 190# 191# Since: 0.15.0 192## 193{ 'command': 'guest-shutdown', 'data': { '*mode': 'str' }, 194 'success-response': 'no' } 195 196## 197# @guest-file-open: 198# 199# Open a file in the guest and retrieve a file handle for it 200# 201# @filepath: Full path to the file in the guest to open. 202# 203# @mode: #optional open mode, as per fopen(), "r" is the default. 204# 205# Returns: Guest file handle on success. 206# 207# Since: 0.15.0 208## 209{ 'command': 'guest-file-open', 210 'data': { 'path': 'str', '*mode': 'str' }, 211 'returns': 'int' } 212 213## 214# @guest-file-close: 215# 216# Close an open file in the guest 217# 218# @handle: filehandle returned by guest-file-open 219# 220# Returns: Nothing on success. 221# 222# Since: 0.15.0 223## 224{ 'command': 'guest-file-close', 225 'data': { 'handle': 'int' } } 226 227## 228# @GuestFileRead 229# 230# Result of guest agent file-read operation 231# 232# @count: number of bytes read (note: count is *before* 233# base64-encoding is applied) 234# 235# @buf-b64: base64-encoded bytes read 236# 237# @eof: whether EOF was encountered during read operation. 238# 239# Since: 0.15.0 240## 241{ 'type': 'GuestFileRead', 242 'data': { 'count': 'int', 'buf-b64': 'str', 'eof': 'bool' } } 243 244## 245# @guest-file-read: 246# 247# Read from an open file in the guest. Data will be base64-encoded 248# 249# @handle: filehandle returned by guest-file-open 250# 251# @count: #optional maximum number of bytes to read (default is 4KB) 252# 253# Returns: @GuestFileRead on success. 254# 255# Since: 0.15.0 256## 257{ 'command': 'guest-file-read', 258 'data': { 'handle': 'int', '*count': 'int' }, 259 'returns': 'GuestFileRead' } 260 261## 262# @GuestFileWrite 263# 264# Result of guest agent file-write operation 265# 266# @count: number of bytes written (note: count is actual bytes 267# written, after base64-decoding of provided buffer) 268# 269# @eof: whether EOF was encountered during write operation. 270# 271# Since: 0.15.0 272## 273{ 'type': 'GuestFileWrite', 274 'data': { 'count': 'int', 'eof': 'bool' } } 275 276## 277# @guest-file-write: 278# 279# Write to an open file in the guest. 280# 281# @handle: filehandle returned by guest-file-open 282# 283# @buf-b64: base64-encoded string representing data to be written 284# 285# @count: #optional bytes to write (actual bytes, after base64-decode), 286# default is all content in buf-b64 buffer after base64 decoding 287# 288# Returns: @GuestFileWrite on success. 289# 290# Since: 0.15.0 291## 292{ 'command': 'guest-file-write', 293 'data': { 'handle': 'int', 'buf-b64': 'str', '*count': 'int' }, 294 'returns': 'GuestFileWrite' } 295 296 297## 298# @GuestFileSeek 299# 300# Result of guest agent file-seek operation 301# 302# @position: current file position 303# 304# @eof: whether EOF was encountered during file seek 305# 306# Since: 0.15.0 307## 308{ 'type': 'GuestFileSeek', 309 'data': { 'position': 'int', 'eof': 'bool' } } 310 311## 312# @guest-file-seek: 313# 314# Seek to a position in the file, as with fseek(), and return the 315# current file position afterward. Also encapsulates ftell()'s 316# functionality, just Set offset=0, whence=SEEK_CUR. 317# 318# @handle: filehandle returned by guest-file-open 319# 320# @offset: bytes to skip over in the file stream 321# 322# @whence: SEEK_SET, SEEK_CUR, or SEEK_END, as with fseek() 323# 324# Returns: @GuestFileSeek on success. 325# 326# Since: 0.15.0 327## 328{ 'command': 'guest-file-seek', 329 'data': { 'handle': 'int', 'offset': 'int', 'whence': 'int' }, 330 'returns': 'GuestFileSeek' } 331 332## 333# @guest-file-flush: 334# 335# Write file changes bufferred in userspace to disk/kernel buffers 336# 337# @handle: filehandle returned by guest-file-open 338# 339# Returns: Nothing on success. 340# 341# Since: 0.15.0 342## 343{ 'command': 'guest-file-flush', 344 'data': { 'handle': 'int' } } 345 346## 347# @GuestFsFreezeStatus 348# 349# An enumeration of filesystem freeze states 350# 351# @thawed: filesystems thawed/unfrozen 352# 353# @frozen: all non-network guest filesystems frozen 354# 355# Since: 0.15.0 356## 357{ 'enum': 'GuestFsfreezeStatus', 358 'data': [ 'thawed', 'frozen' ] } 359 360## 361# @guest-fsfreeze-status: 362# 363# Get guest fsfreeze state. error state indicates 364# 365# Returns: GuestFsfreezeStatus ("thawed", "frozen", etc., as defined below) 366# 367# Note: This may fail to properly report the current state as a result of 368# some other guest processes having issued an fs freeze/thaw. 369# 370# Since: 0.15.0 371## 372{ 'command': 'guest-fsfreeze-status', 373 'returns': 'GuestFsfreezeStatus' } 374 375## 376# @guest-fsfreeze-freeze: 377# 378# Sync and freeze all freezable, local guest filesystems 379# 380# Returns: Number of file systems currently frozen. On error, all filesystems 381# will be thawed. 382# 383# Since: 0.15.0 384## 385{ 'command': 'guest-fsfreeze-freeze', 386 'returns': 'int' } 387 388## 389# @guest-fsfreeze-thaw: 390# 391# Unfreeze all frozen guest filesystems 392# 393# Returns: Number of file systems thawed by this call 394# 395# Note: if return value does not match the previous call to 396# guest-fsfreeze-freeze, this likely means some freezable 397# filesystems were unfrozen before this call, and that the 398# filesystem state may have changed before issuing this 399# command. 400# 401# Since: 0.15.0 402## 403{ 'command': 'guest-fsfreeze-thaw', 404 'returns': 'int' } 405 406## 407# @guest-fstrim: 408# 409# Discard (or "trim") blocks which are not in use by the filesystem. 410# 411# @minimum: 412# Minimum contiguous free range to discard, in bytes. Free ranges 413# smaller than this may be ignored (this is a hint and the guest 414# may not respect it). By increasing this value, the fstrim 415# operation will complete more quickly for filesystems with badly 416# fragmented free space, although not all blocks will be discarded. 417# The default value is zero, meaning "discard every free block". 418# 419# Returns: Nothing. 420# 421# Since: 1.2 422## 423{ 'command': 'guest-fstrim', 424 'data': { '*minimum': 'int' } } 425 426## 427# @guest-suspend-disk 428# 429# Suspend guest to disk. 430# 431# This command tries to execute the scripts provided by the pm-utils package. 432# If it's not available, the suspend operation will be performed by manually 433# writing to a sysfs file. 434# 435# For the best results it's strongly recommended to have the pm-utils 436# package installed in the guest. 437# 438# This command does NOT return a response on success. There is a high chance 439# the command succeeded if the VM exits with a zero exit status or, when 440# running with --no-shutdown, by issuing the query-status QMP command to 441# to confirm the VM status is "shutdown". However, the VM could also exit 442# (or set its status to "shutdown") due to other reasons. 443# 444# The following errors may be returned: 445# If suspend to disk is not supported, Unsupported 446# 447# Notes: It's strongly recommended to issue the guest-sync command before 448# sending commands when the guest resumes 449# 450# Since: 1.1 451## 452{ 'command': 'guest-suspend-disk', 'success-response': 'no' } 453 454## 455# @guest-suspend-ram 456# 457# Suspend guest to ram. 458# 459# This command tries to execute the scripts provided by the pm-utils package. 460# If it's not available, the suspend operation will be performed by manually 461# writing to a sysfs file. 462# 463# For the best results it's strongly recommended to have the pm-utils 464# package installed in the guest. 465# 466# IMPORTANT: guest-suspend-ram requires QEMU to support the 'system_wakeup' 467# command. Thus, it's *required* to query QEMU for the presence of the 468# 'system_wakeup' command before issuing guest-suspend-ram. 469# 470# This command does NOT return a response on success. There are two options 471# to check for success: 472# 1. Wait for the SUSPEND QMP event from QEMU 473# 2. Issue the query-status QMP command to confirm the VM status is 474# "suspended" 475# 476# The following errors may be returned: 477# If suspend to ram is not supported, Unsupported 478# 479# Notes: It's strongly recommended to issue the guest-sync command before 480# sending commands when the guest resumes 481# 482# Since: 1.1 483## 484{ 'command': 'guest-suspend-ram', 'success-response': 'no' } 485 486## 487# @guest-suspend-hybrid 488# 489# Save guest state to disk and suspend to ram. 490# 491# This command requires the pm-utils package to be installed in the guest. 492# 493# IMPORTANT: guest-suspend-hybrid requires QEMU to support the 'system_wakeup' 494# command. Thus, it's *required* to query QEMU for the presence of the 495# 'system_wakeup' command before issuing guest-suspend-hybrid. 496# 497# This command does NOT return a response on success. There are two options 498# to check for success: 499# 1. Wait for the SUSPEND QMP event from QEMU 500# 2. Issue the query-status QMP command to confirm the VM status is 501# "suspended" 502# 503# The following errors may be returned: 504# If hybrid suspend is not supported, Unsupported 505# 506# Notes: It's strongly recommended to issue the guest-sync command before 507# sending commands when the guest resumes 508# 509# Since: 1.1 510## 511{ 'command': 'guest-suspend-hybrid', 'success-response': 'no' } 512 513## 514# @GuestIpAddressType: 515# 516# An enumeration of supported IP address types 517# 518# @ipv4: IP version 4 519# 520# @ipv6: IP version 6 521# 522# Since: 1.1 523## 524{ 'enum': 'GuestIpAddressType', 525 'data': [ 'ipv4', 'ipv6' ] } 526 527## 528# @GuestIpAddress: 529# 530# @ip-address: IP address 531# 532# @ip-address-type: Type of @ip-address (e.g. ipv4, ipv6) 533# 534# @prefix: Network prefix length of @ip-address 535# 536# Since: 1.1 537## 538{ 'type': 'GuestIpAddress', 539 'data': {'ip-address': 'str', 540 'ip-address-type': 'GuestIpAddressType', 541 'prefix': 'int'} } 542 543## 544# @GuestNetworkInterface: 545# 546# @name: The name of interface for which info are being delivered 547# 548# @hardware-address: Hardware address of @name 549# 550# @ip-addresses: List of addresses assigned to @name 551# 552# Since: 1.1 553## 554{ 'type': 'GuestNetworkInterface', 555 'data': {'name': 'str', 556 '*hardware-address': 'str', 557 '*ip-addresses': ['GuestIpAddress'] } } 558 559## 560# @guest-network-get-interfaces: 561# 562# Get list of guest IP addresses, MAC addresses 563# and netmasks. 564# 565# Returns: List of GuestNetworkInfo on success. 566# 567# Since: 1.1 568## 569{ 'command': 'guest-network-get-interfaces', 570 'returns': ['GuestNetworkInterface'] } 571 572## 573# @GuestLogicalProcessor: 574# 575# @logical-id: Arbitrary guest-specific unique identifier of the VCPU. 576# 577# @online: Whether the VCPU is enabled. 578# 579# @can-offline: #optional Whether offlining the VCPU is possible. This member 580# is always filled in by the guest agent when the structure is 581# returned, and always ignored on input (hence it can be omitted 582# then). 583# 584# Since: 1.5 585## 586{ 'type': 'GuestLogicalProcessor', 587 'data': {'logical-id': 'int', 588 'online': 'bool', 589 '*can-offline': 'bool'} } 590 591## 592# @guest-get-vcpus: 593# 594# Retrieve the list of the guest's logical processors. 595# 596# This is a read-only operation. 597# 598# Returns: The list of all VCPUs the guest knows about. Each VCPU is put on the 599# list exactly once, but their order is unspecified. 600# 601# Since: 1.5 602## 603{ 'command': 'guest-get-vcpus', 604 'returns': ['GuestLogicalProcessor'] } 605 606## 607# @guest-set-vcpus: 608# 609# Attempt to reconfigure (currently: enable/disable) logical processors inside 610# the guest. 611# 612# The input list is processed node by node in order. In each node @logical-id 613# is used to look up the guest VCPU, for which @online specifies the requested 614# state. The set of distinct @logical-id's is only required to be a subset of 615# the guest-supported identifiers. There's no restriction on list length or on 616# repeating the same @logical-id (with possibly different @online field). 617# Preferably the input list should describe a modified subset of 618# @guest-get-vcpus' return value. 619# 620# Returns: The length of the initial sublist that has been successfully 621# processed. The guest agent maximizes this value. Possible cases: 622# 623# 0: if the @vcpus list was empty on input. Guest state 624# has not been changed. Otherwise, 625# 626# Error: processing the first node of @vcpus failed for the 627# reason returned. Guest state has not been changed. 628# Otherwise, 629# 630# < length(@vcpus): more than zero initial nodes have been processed, 631# but not the entire @vcpus list. Guest state has 632# changed accordingly. To retrieve the error 633# (assuming it persists), repeat the call with the 634# successfully processed initial sublist removed. 635# Otherwise, 636# 637# length(@vcpus): call successful. 638# 639# Since: 1.5 640## 641{ 'command': 'guest-set-vcpus', 642 'data': {'vcpus': ['GuestLogicalProcessor'] }, 643 'returns': 'int' } 644