aboutsummaryrefslogtreecommitdiff
path: root/python/qemu/machine.py
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2020-05-31 21:49:07 +0100
committerPeter Maydell <peter.maydell@linaro.org>2020-05-31 21:49:07 +0100
commitb73f417aaeeedee933aa031d6430ecb9ada71ccb (patch)
treecedf9d186a4729e6353837bf0f1ed8139bd8e774 /python/qemu/machine.py
parent4ec2a1f53e8aaa22924614b64dde97321126943e (diff)
parent1c80c87c8c2489e4318c93c844aa29bc1d014146 (diff)
downloadqemu-b73f417aaeeedee933aa031d6430ecb9ada71ccb.zip
qemu-b73f417aaeeedee933aa031d6430ecb9ada71ccb.tar.gz
qemu-b73f417aaeeedee933aa031d6430ecb9ada71ccb.tar.bz2
Merge remote-tracking branch 'remotes/philmd-gitlab/tags/python-next-20200531' into staging
Python queue: * migration acceptance test fix * introduce pylintrc & flake8 config * various cleanups (Python3, style) * vm-test can set QEMU_LOCAL=1 to use locally built binaries * refactored BootLinuxBase & LinuxKernelTest acceptance classes https://gitlab.com/philmd/qemu/pipelines/151323210 https://travis-ci.org/github/philmd/qemu/builds/693157969 # gpg: Signature made Sun 31 May 2020 17:37:35 BST # gpg: using RSA key FAABE75E12917221DCFD6BB2E3E32C2CDEADC0DE # gpg: Good signature from "Philippe Mathieu-Daudé (F4BUG) <f4bug@amsat.org>" [full] # Primary key fingerprint: FAAB E75E 1291 7221 DCFD 6BB2 E3E3 2C2C DEAD C0DE * remotes/philmd-gitlab/tags/python-next-20200531: (25 commits) tests/acceptance: refactor boot_linux to allow code reuse tests/acceptance: refactor boot_linux_console test to allow code reuse tests/acceptance: allow console interaction with specific VMs tests/acceptance/migration.py: Wait for both sides tests/migration/guestperf: Use Python 3 interpreter tests/vm: allow wait_ssh() to specify command tests/vm: Add ability to select QEMU from current build tests/vm: Pass --debug through for vm-boot-ssh python/qemu/qtest: Check before accessing _qtest python/qemu/qmp: assert sockfile is not None python/qemu/qmp: use True/False for non/blocking modes python/qemu: Adjust traceback typing python/qemu: fix socket.makefile() typing python/qemu: remove Python2 style super() calls python/qemu: delint; add flake8 config python/qemu: delint and add pylintrc python/qemu/machine: remove logging configuration python/qemu/machine: add kill() method python: remove more instances of sys.version_info scripts/qmp: Fix shebang and imports ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'python/qemu/machine.py')
-rw-r--r--python/qemu/machine.py44
1 files changed, 28 insertions, 16 deletions
diff --git a/python/qemu/machine.py b/python/qemu/machine.py
index b9a98e2..041c615 100644
--- a/python/qemu/machine.py
+++ b/python/qemu/machine.py
@@ -24,11 +24,14 @@ import subprocess
import shutil
import socket
import tempfile
+from typing import Optional, Type
+from types import TracebackType
from . import qmp
LOG = logging.getLogger(__name__)
+
class QEMUMachineError(Exception):
"""
Exception called when an error in QEMUMachine happens.
@@ -54,15 +57,16 @@ class MonitorResponseError(qmp.QMPError):
desc = reply["error"]["desc"]
except KeyError:
desc = reply
- super(MonitorResponseError, self).__init__(desc)
+ super().__init__(desc)
self.reply = reply
-class QEMUMachine(object):
+class QEMUMachine:
"""
A QEMU VM
- Use this object as a context manager to ensure the QEMU process terminates::
+ Use this object as a context manager to ensure
+ the QEMU process terminates::
with VM(binary) as vm:
...
@@ -119,15 +123,14 @@ class QEMUMachine(object):
self._console_socket = None
self._remove_files = []
- # just in case logging wasn't configured by the main script:
- logging.basicConfig()
-
def __enter__(self):
return self
- def __exit__(self, exc_type, exc_val, exc_tb):
+ def __exit__(self,
+ exc_type: Optional[Type[BaseException]],
+ exc_val: Optional[BaseException],
+ exc_tb: Optional[TracebackType]) -> None:
self.shutdown()
- return False
def add_monitor_null(self):
"""
@@ -188,8 +191,10 @@ class QEMUMachine(object):
fd_param.append(str(fd))
devnull = open(os.path.devnull, 'rb')
- proc = subprocess.Popen(fd_param, stdin=devnull, stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT, close_fds=False)
+ proc = subprocess.Popen(
+ fd_param, stdin=devnull, stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT, close_fds=False
+ )
output = proc.communicate()[0]
if output:
LOG.debug(output)
@@ -242,7 +247,7 @@ class QEMUMachine(object):
'chardev=mon,mode=control'])
if self._machine is not None:
args.extend(['-machine', self._machine])
- for i in range(self._console_index):
+ for _ in range(self._console_index):
args.extend(['-serial', 'null'])
if self._console_set:
self._console_address = os.path.join(self._sock_dir,
@@ -342,7 +347,7 @@ class QEMUMachine(object):
self._load_io_log()
self._post_shutdown()
- def shutdown(self, has_quit=False):
+ def shutdown(self, has_quit=False, hard=False):
"""
Terminate the VM and clean up
"""
@@ -354,7 +359,9 @@ class QEMUMachine(object):
self._console_socket = None
if self.is_running():
- if self._qmp:
+ if hard:
+ self._popen.kill()
+ elif self._qmp:
try:
if not has_quit:
self._qmp.cmd('quit')
@@ -368,16 +375,20 @@ class QEMUMachine(object):
self._post_shutdown()
exitcode = self.exitcode()
- if exitcode is not None and exitcode < 0:
+ if exitcode is not None and exitcode < 0 and \
+ not (exitcode == -9 and hard):
msg = 'qemu received signal %i: %s'
if self._qemu_full_args:
command = ' '.join(self._qemu_full_args)
else:
command = ''
- LOG.warning(msg, -exitcode, command)
+ LOG.warning(msg, -int(exitcode), command)
self._launched = False
+ def kill(self):
+ self.shutdown(hard=True)
+
def set_qmp_monitor(self, enabled=True):
"""
Set the QMP monitor.
@@ -482,7 +493,8 @@ class QEMUMachine(object):
def events_wait(self, events, timeout=60.0):
"""
- events_wait waits for and returns a named event from QMP with a timeout.
+ events_wait waits for and returns a named event
+ from QMP with a timeout.
events: a sequence of (name, match_criteria) tuples.
The match criteria are optional and may be None.