QMP Protocol
QMP Protocol Implementation
This module provides the QMPClient class, which can be used to connect
and send commands to a QMP server such as QEMU. The QMP class can be
used to either connect to a listening server, or used to listen and
accept an incoming connection from that server.
- exception qemu.qmp.qmp_client.GreetingError(error_message: str, exc: Exception)[source]
Bases:
_WrappedProtocolErrorAn exception occurred during the Greeting phase.
- Parameters:
error_message – Human-readable string describing the error.
exc – The root-cause exception.
- exception qemu.qmp.qmp_client.NegotiationError(error_message: str, exc: Exception)[source]
Bases:
_WrappedProtocolErrorAn exception occurred during the Negotiation phase.
- Parameters:
error_message – Human-readable string describing the error.
exc – The root-cause exception.
- exception qemu.qmp.qmp_client.ExecuteError(error_response: ErrorResponse, sent: Message, received: Message)[source]
Bases:
QMPErrorException raised by
QMPClient.execute()on RPC failure.This exception is raised when the server received, interpreted, and replied to a command successfully; but the command itself returned a failure status.
For example:
await qmp.execute('block-dirty-bitmap-add', {'node': 'foo', 'name': 'my_bitmap'}) # qemu.qmp.qmp_client.ExecuteError: # Cannot find device='foo' nor node-name='foo'
- Parameters:
error_response – The RPC error response object.
sent – The sent RPC message that caused the failure.
received – The raw RPC error reply received.
- error: ErrorResponse
The parsed error response
- exception qemu.qmp.qmp_client.ExecInterruptedError[source]
Bases:
QMPErrorException raised by
execute()(et al) when an RPC is interrupted.This error is raised when an
execute()statement could not be completed. This can occur because the connection itself was terminated before a reply was received. The true cause of the interruption will be available viadisconnect().The QMP protocol does not make it possible to know if a command succeeded or failed after such an event; the client will need to query the server to determine the state of the server on a case-by-case basis.
For example, ECONNRESET might look like this:
try: await qmp.execute('query-block') # ExecInterruptedError: Disconnected except ExecInterruptedError: await qmp.disconnect() # ConnectionResetError: [Errno 104] Connection reset by peer
- exception qemu.qmp.qmp_client.ServerParseError(error_message: str, msg: Message, *args: object)[source]
Bases:
_MsgProtocolErrorThe Server sent a
Messageindicating parsing failure.i.e. A reply has arrived from the server, but it is missing the “ID” field, indicating a parsing error.
- Parameters:
error_message – Human-readable string describing the error.
msg – The QMP
Messagethat caused the error.
- exception qemu.qmp.qmp_client.BadReplyError(error_message: str, msg: Message, sent: Message)[source]
Bases:
_MsgProtocolErrorAn execution reply was successfully routed, but not understood.
If a QMP message is received with an ‘id’ field to allow it to be routed, but is otherwise malformed, this exception will be raised.
A reply message is malformed if it is missing either the ‘return’ or ‘error’ keys, or if the ‘error’ value has missing keys or members of the wrong type.
- Parameters:
error_message – Human-readable string describing the error.
msg – The malformed reply that was received.
sent – The message that was sent that prompted the error.
- class qemu.qmp.qmp_client.QMPClient(name: str | None = None)[source]
Bases:
AsyncProtocol[Message],EventsImplements a QMP client connection.
QMPClientcan be used to either connect or listen to a QMP server, but always acts as the QMP client.- Parameters:
name – Optional nickname for the connection, used to differentiate instances when logging.
Basic script-style usage looks like this:
import asyncio from qemu.qmp import QMPClient async def main(): qmp = QMPClient('my_virtual_machine_name') await qmp.connect(('127.0.0.1', 1234)) ... res = await qmp.execute('query-block') ... await qmp.disconnect() asyncio.run(main())
A more advanced example that starts to take advantage of asyncio might look like this:
class Client: def __init__(self, name: str): self.qmp = QMPClient(name) async def watch_events(self): try: async for event in self.qmp.events: print(f"Event: {event['event']}") except asyncio.CancelledError: return async def run(self, address='/tmp/qemu.socket'): await self.qmp.connect(address) asyncio.create_task(self.watch_events()) await self.qmp.runstate_changed.wait() await self.disconnect()
See
qmp.eventsfor more detail on event handling patterns.- logger: logging.Logger = <Logger qemu.qmp.qmp_client (WARNING)>
Logger object used for debugging messages.
- await_greeting: bool
Whether or not to await a greeting after establishing a connection. Defaults to True; QGA servers expect this to be False.
- negotiate: bool
Whether or not to perform capabilities negotiation upon connection. Implies
await_greeting. Defaults to True; QGA servers expect this to be False.
- property greeting: Greeting | None
The
Greetingfrom the QMP server, if any.Defaults to
None, and will be set after a greeting is received during the connection process. It is reset at the start of each connection attempt.
- async execute_msg(msg: Message) object[source]
Execute a QMP command on the server and return its value.
- Parameters:
msg – The QMP
Messageto execute.- Returns:
The command execution return value from the server. The type of object returned depends on the command that was issued, though most in QEMU return a
dict.- Raises:
ValueError – If the QMP
Messagedoes not have either the ‘execute’ or ‘exec-oob’ fields set.ExecuteError – When the server returns an error response.
ExecInterruptedError – If the connection was disrupted before receiving a reply from the server.
- classmethod make_execute_msg(cmd: str, arguments: Mapping[str, object] | None = None, oob: bool = False) Message[source]
Create an executable message to be sent by
execute_msglater.- Parameters:
cmd – QMP command name.
arguments – Arguments (if any). Must be JSON-serializable.
oob – If
True, execute “out of band”.
- Returns:
A QMP
Messagethat can be executed withexecute_msg().
- async execute(cmd: str, arguments: Mapping[str, object] | None = None, oob: bool = False) object[source]
Execute a QMP command on the server and return its value.
- Parameters:
cmd – QMP command name.
arguments – Arguments (if any). Must be JSON-serializable.
oob –
If
True, execute “out of band”.
- Returns:
The command execution return value from the server. The type of object returned depends on the command that was issued, though most in QEMU return a
dict.- Raises:
ExecuteError – When the server returns an error response.
ExecInterruptedError – If the connection was disrupted before receiving a reply from the server.
- send_fd_scm(fd: int) None[source]
Send a file descriptor to the remote via SCM_RIGHTS.
This method does not close the file descriptor.
- Parameters:
fd – The file descriptor to send to QEMU.
This is an advanced feature of QEMU where file descriptors can be passed from client to server. This is usually used as a security measure to isolate the QEMU process from being able to open its own files. See the QMP commands
getfdandadd-fdfor more information.See
socket.socket.sendmsgfor more information on the Python implementation for sending file descriptors over a UNIX socket.
- events: EventListener
Default, all-events
EventListener. Seeqmp.eventsfor more info.