@@ -604,6 +604,66 @@ class QMPMonitor(Monitor):
return self._greeting
+ def send(self, data, timeout=20):
+ """
+ Send data to the QMP monitor and return its response.
+
+ @param data: Data to send
+ @param timeout: Time duration to wait for response
+ @return: QMP success or error response as a dictionary
+ @raise MonitorLockError: Raised if the lock cannot be acquired
+ @raise MonitorSendError: Raised if the command cannot be sent
+ @raise MonitorProtocolError: Raised if no response is received
+ """
+ # XXX: This method is similar to _get_command_output(), we should
+ # refactor it
+ if not self._acquire_lock(20):
+ raise MonitorLockError("Could not acquire exclusive lock to send "
+ "QMP command '%s'" % cmd)
+ try:
+ self._read_objects()
+ self._socket.sendall(data)
+ end_time = time.time() + timeout
+ while time.time() < end_time:
+ for obj in self._read_objects():
+ if isinstance(obj, dict):
+ if "return" in obj or "error" in obj:
+ return obj
+ time.sleep(0.1)
+ else:
+ raise MonitorProtocolError("Received no response (data: %s)"
+ % str(data))
+ except socket.error:
+ raise MonitorSendError("Could not send data '%s'" % str(data))
+ finally:
+ self._lock.release()
+
+
+ def cmd_obj(self, cmd_obj, timeout=20):
+ """
+ Take a Python object, transforms it in JSON and send the resulting
+ string to the QMP monitor. Return the monitor's response.
+
+ @param cmd_obj: Python object to transform in JSON
+ @param timeout: Time duration to wait for response
+ @return: QMP success or error response as a dictionary
+ @note: raise same exceptions as send()
+ """
+ return self.send(json.dumps(cmd_obj) + "\n", timeout)
+
+ def cmd_qmp(self, command, arguments=None, id=None, timeout=20):
+ """
+ Build a QMP command from the passed arguments, return the monitor's
+ response.
+
+ @param command: QMP command name
+ @param arguments: Arguments in the form of a Python dictionary
+ @param id: QMP command id
+ @return: QMP success or error response as a dictionary
+ @note: raise same exceptions as send_cmd()
+ """
+ return self.cmd_obj(self._build_cmd(command, arguments, id), timeout)
+
# Command wrappers
# Note: all of the following functions raise exceptions in a similar manner
# to cmd() and _get_command_output().