ppc/pnv: add a PnvICPState object
[qemu.git] / scripts / qmp / qmp.py
1 # QEMU Monitor Protocol Python class
2 #
3 # Copyright (C) 2009, 2010 Red Hat Inc.
4 #
5 # Authors:
6 # Luiz Capitulino <lcapitulino@redhat.com>
7 #
8 # This work is licensed under the terms of the GNU GPL, version 2. See
9 # the COPYING file in the top-level directory.
10
11 import json
12 import errno
13 import socket
14 import sys
15
16 class QMPError(Exception):
17 pass
18
19 class QMPConnectError(QMPError):
20 pass
21
22 class QMPCapabilitiesError(QMPError):
23 pass
24
25 class QMPTimeoutError(QMPError):
26 pass
27
28 class QEMUMonitorProtocol:
29 def __init__(self, address, server=False, debug=False):
30 """
31 Create a QEMUMonitorProtocol class.
32
33 @param address: QEMU address, can be either a unix socket path (string)
34 or a tuple in the form ( address, port ) for a TCP
35 connection
36 @param server: server mode listens on the socket (bool)
37 @raise socket.error on socket connection errors
38 @note No connection is established, this is done by the connect() or
39 accept() methods
40 """
41 self.__events = []
42 self.__address = address
43 self._debug = debug
44 self.__sock = self.__get_sock()
45 if server:
46 self.__sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
47 self.__sock.bind(self.__address)
48 self.__sock.listen(1)
49
50 def __get_sock(self):
51 if isinstance(self.__address, tuple):
52 family = socket.AF_INET
53 else:
54 family = socket.AF_UNIX
55 return socket.socket(family, socket.SOCK_STREAM)
56
57 def __negotiate_capabilities(self):
58 greeting = self.__json_read()
59 if greeting is None or not greeting.has_key('QMP'):
60 raise QMPConnectError
61 # Greeting seems ok, negotiate capabilities
62 resp = self.cmd('qmp_capabilities')
63 if "return" in resp:
64 return greeting
65 raise QMPCapabilitiesError
66
67 def __json_read(self, only_event=False):
68 while True:
69 data = self.__sockfile.readline()
70 if not data:
71 return
72 resp = json.loads(data)
73 if 'event' in resp:
74 if self._debug:
75 print >>sys.stderr, "QMP:<<< %s" % resp
76 self.__events.append(resp)
77 if not only_event:
78 continue
79 return resp
80
81 error = socket.error
82
83 def __get_events(self, wait=False):
84 """
85 Check for new events in the stream and cache them in __events.
86
87 @param wait (bool): block until an event is available.
88 @param wait (float): If wait is a float, treat it as a timeout value.
89
90 @raise QMPTimeoutError: If a timeout float is provided and the timeout
91 period elapses.
92 @raise QMPConnectError: If wait is True but no events could be retrieved
93 or if some other error occurred.
94 """
95
96 # Check for new events regardless and pull them into the cache:
97 self.__sock.setblocking(0)
98 try:
99 self.__json_read()
100 except socket.error as err:
101 if err[0] == errno.EAGAIN:
102 # No data available
103 pass
104 self.__sock.setblocking(1)
105
106 # Wait for new events, if needed.
107 # if wait is 0.0, this means "no wait" and is also implicitly false.
108 if not self.__events and wait:
109 if isinstance(wait, float):
110 self.__sock.settimeout(wait)
111 try:
112 ret = self.__json_read(only_event=True)
113 except socket.timeout:
114 raise QMPTimeoutError("Timeout waiting for event")
115 except:
116 raise QMPConnectError("Error while reading from socket")
117 if ret is None:
118 raise QMPConnectError("Error while reading from socket")
119 self.__sock.settimeout(None)
120
121 def connect(self, negotiate=True):
122 """
123 Connect to the QMP Monitor and perform capabilities negotiation.
124
125 @return QMP greeting dict
126 @raise socket.error on socket connection errors
127 @raise QMPConnectError if the greeting is not received
128 @raise QMPCapabilitiesError if fails to negotiate capabilities
129 """
130 self.__sock.connect(self.__address)
131 self.__sockfile = self.__sock.makefile()
132 if negotiate:
133 return self.__negotiate_capabilities()
134
135 def accept(self):
136 """
137 Await connection from QMP Monitor and perform capabilities negotiation.
138
139 @return QMP greeting dict
140 @raise socket.error on socket connection errors
141 @raise QMPConnectError if the greeting is not received
142 @raise QMPCapabilitiesError if fails to negotiate capabilities
143 """
144 self.__sock.settimeout(15)
145 self.__sock, _ = self.__sock.accept()
146 self.__sockfile = self.__sock.makefile()
147 return self.__negotiate_capabilities()
148
149 def cmd_obj(self, qmp_cmd):
150 """
151 Send a QMP command to the QMP Monitor.
152
153 @param qmp_cmd: QMP command to be sent as a Python dict
154 @return QMP response as a Python dict or None if the connection has
155 been closed
156 """
157 if self._debug:
158 print >>sys.stderr, "QMP:>>> %s" % qmp_cmd
159 try:
160 self.__sock.sendall(json.dumps(qmp_cmd))
161 except socket.error as err:
162 if err[0] == errno.EPIPE:
163 return
164 raise socket.error(err)
165 resp = self.__json_read()
166 if self._debug:
167 print >>sys.stderr, "QMP:<<< %s" % resp
168 return resp
169
170 def cmd(self, name, args=None, id=None):
171 """
172 Build a QMP command and send it to the QMP Monitor.
173
174 @param name: command name (string)
175 @param args: command arguments (dict)
176 @param id: command id (dict, list, string or int)
177 """
178 qmp_cmd = { 'execute': name }
179 if args:
180 qmp_cmd['arguments'] = args
181 if id:
182 qmp_cmd['id'] = id
183 return self.cmd_obj(qmp_cmd)
184
185 def command(self, cmd, **kwds):
186 ret = self.cmd(cmd, kwds)
187 if ret.has_key('error'):
188 raise Exception(ret['error']['desc'])
189 return ret['return']
190
191 def pull_event(self, wait=False):
192 """
193 Get and delete the first available QMP event.
194
195 @param wait (bool): block until an event is available.
196 @param wait (float): If wait is a float, treat it as a timeout value.
197
198 @raise QMPTimeoutError: If a timeout float is provided and the timeout
199 period elapses.
200 @raise QMPConnectError: If wait is True but no events could be retrieved
201 or if some other error occurred.
202
203 @return The first available QMP event, or None.
204 """
205 self.__get_events(wait)
206
207 if self.__events:
208 return self.__events.pop(0)
209 return None
210
211 def get_events(self, wait=False):
212 """
213 Get a list of available QMP events.
214
215 @param wait (bool): block until an event is available.
216 @param wait (float): If wait is a float, treat it as a timeout value.
217
218 @raise QMPTimeoutError: If a timeout float is provided and the timeout
219 period elapses.
220 @raise QMPConnectError: If wait is True but no events could be retrieved
221 or if some other error occurred.
222
223 @return The list of available QMP events.
224 """
225 self.__get_events(wait)
226 return self.__events
227
228 def clear_events(self):
229 """
230 Clear current list of pending events.
231 """
232 self.__events = []
233
234 def close(self):
235 self.__sock.close()
236 self.__sockfile.close()
237
238 timeout = socket.timeout
239
240 def settimeout(self, timeout):
241 self.__sock.settimeout(timeout)
242
243 def get_sock_fd(self):
244 return self.__sock.fileno()
245
246 def is_scm_available(self):
247 return self.__sock.family == socket.AF_UNIX