def cmd(self, cmd, args=None, timeout=CMD_TIMEOUT, debug=True, fd=None): """ Send a QMP monitor command and return the response. Note: an id is automatically assigned to the command and the response is checked for the presence of the same id. @param cmd: Command to send @param args: A dict containing command arguments, or None @param timeout: Time duration to wait for response @param debug: Whether to print the commands being sent and responses @param fd: file object or file descriptor to pass @return: The response received @raise MonitorLockError: Raised if the lock cannot be acquired @raise MonitorSocketError: Raised if a socket error occurs @raise MonitorProtocolError: Raised if no response is received @raise QMPCmdError: Raised if the response is an error message (the exception's args are (cmd, args, data) where data is the error data) """ self._log_command(cmd, debug) if not self._acquire_lock(): raise MonitorLockError("Could not acquire exclusive lock to send " "QMP command '%s'" % cmd) try: # Read any data that might be available self._read_objects() # Send command id = virt_utils.generate_random_string(8) cmdobj = self._build_cmd(cmd, args, id) if fd is not None: if self._passfd is None: self._passfd = virt_passfd_setup.import_passfd() # If command includes a file descriptor, use passfd module self._passfd.sendfd(self._socket, fd, json.dumps(cmdobj) + "\n") else: self._send(json.dumps(cmdobj) + "\n") # Read response r = self._get_response(id, timeout) if r is None: raise MonitorProtocolError("Received no response to QMP " "command '%s', or received a " "response with an incorrect id" % cmd) if "return" in r: ret = r["return"] if ret: self._log_response(cmd, ret, debug) return ret if "error" in r: raise QMPCmdError(cmd, args, r["error"]) finally: self._lock.release()
def cmd(self, command, timeout=20, debug=True, fd=None): """ Send command to the monitor. @param command: Command to send to the monitor @param timeout: Time duration to wait for the (qemu) prompt to return @param debug: Whether to print the commands being sent and responses @return: Output received from the monitor @raise MonitorLockError: Raised if the lock cannot be acquired @raise MonitorSocketError: Raised if a socket error occurs @raise MonitorProtocolError: Raised if the (qemu) prompt cannot be found after sending the command """ if debug: logging.debug("(monitor %s) Sending command '%s'", self.name, command) if not self._acquire_lock(20): raise MonitorLockError("Could not acquire exclusive lock to send " "monitor command '%s'" % command) try: # Read any data that might be available self._recvall() if fd is not None: if self._passfd is None: self._passfd = virt_passfd_setup.import_passfd() # If command includes a file descriptor, use passfd module self._passfd.sendfd(self._socket, fd, "%s\n" % (command)) else: # Send command self._send(command) # Read output s, o = self._read_up_to_qemu_prompt(timeout) # Remove command echo from output o = "\n".join(o.splitlines()[1:]) # Report success/failure if s: if debug and o: logging.debug("(monitor %s) " "Response to '%s'", self.name, command) for l in o.splitlines(): logging.debug("(monitor %s) %s", self.name, l) return o else: msg = ("Could not find (qemu) prompt after command '%s'. " "Output so far: %r" % (command, o)) raise MonitorProtocolError(msg) finally: self._lock.release()
def cmd(self, command, timeout=CMD_TIMEOUT, debug=True, fd=None): """ Send command to the monitor. @param command: Command to send to the monitor @param timeout: Time duration to wait for the (qemu) prompt to return @param debug: Whether to print the commands being sent and responses @return: Output received from the monitor @raise MonitorLockError: Raised if the lock cannot be acquired @raise MonitorSocketError: Raised if a socket error occurs @raise MonitorProtocolError: Raised if the (qemu) prompt cannot be found after sending the command """ if debug: logging.debug("(monitor %s) Sending command '%s'", self.name, command) if not self._acquire_lock(): raise MonitorLockError("Could not acquire exclusive lock to send " "monitor command '%s'" % command) try: # Read any data that might be available self._recvall() if fd is not None: if self._passfd is None: self._passfd = virt_passfd_setup.import_passfd() # If command includes a file descriptor, use passfd module self._passfd.sendfd(self._socket, fd, "%s\n" % (command)) else: # Send command self._send(command) # Read output s, o = self._read_up_to_qemu_prompt(timeout) # Remove command echo from output o = "\n".join(o.splitlines()[1:]) # Report success/failure if s: if debug and o: logging.debug("(monitor %s) " "Response to '%s'", self.name, command) for l in o.splitlines(): logging.debug("(monitor %s) %s", self.name, l) return o else: msg = ("Could not find (qemu) prompt after command '%s'. " "Output so far: %r" % (command, o)) raise MonitorProtocolError(msg) finally: self._lock.release()