01f9005feb
- Backport aqmp patches from upstream which can fix iotest issues * Patches added: python-aqmp-add-__del__-method-to-legacy.patch python-aqmp-add-_session_guard.patch python-aqmp-add-SocketAddrT-to-package-r.patch python-aqmp-add-socket-bind-step-to-lega.patch python-aqmp-add-start_server-and-accept-.patch python-aqmp-copy-type-definitions-from-q.patch python-aqmp-drop-_bind_hack.patch python-aqmp-fix-docstring-typo.patch python-aqmp-Fix-negotiation-with-pre-oob.patch python-aqmp-fix-race-condition-in-legacy.patch Python-aqmp-fix-type-definitions-for-myp.patch python-aqmp-handle-asyncio.TimeoutError-.patch python-aqmp-refactor-_do_accept-into-two.patch python-aqmp-remove-_new_session-and-_est.patch python-aqmp-rename-accept-to-start_serve.patch python-aqmp-rename-AQMPError-to-QMPError.patch python-aqmp-split-_client_connected_cb-o.patch python-aqmp-squelch-pylint-warning-for-t.patch python-aqmp-stop-the-server-during-disco.patch python-introduce-qmp-shell-wrap-convenie.patch python-machine-raise-VMLaunchFailure-exc.patch python-move-qmp-shell-under-the-AQMP-pac.patch python-move-qmp-utilities-to-python-qemu.patch python-qmp-switch-qmp-shell-to-AQMP.patch python-support-recording-QMP-session-to-.patch python-upgrade-mypy-to-0.780.patch - Drop the patches which are workaround to fix iotest issues * Patches dropped: Revert-python-iotests-replace-qmp-with-a.patch Revert-python-machine-add-instance-disam.patch Revert-python-machine-add-sock_dir-prope.patch Revert-python-machine-handle-fast-QEMU-t.patch Revert-python-machine-move-more-variable.patch Revert-python-machine-remove-_remove_mon.patch OBS-URL: https://build.opensuse.org/request/show/966963 OBS-URL: https://build.opensuse.org/package/show/Virtualization/qemu?expand=0&rev=708
127 lines
4.8 KiB
Diff
127 lines
4.8 KiB
Diff
From: John Snow <jsnow@redhat.com>
|
|
Date: Mon, 31 Jan 2022 23:11:32 -0500
|
|
Subject: python/machine: raise VMLaunchFailure exception from launch()
|
|
|
|
Git-commit: 50465f94d211beabfbfc80e4f85ec4fad0757570
|
|
|
|
This allows us to pack in some extra information about the failure,
|
|
which guarantees that if the caller did not *intentionally* cause a
|
|
failure (by capturing this Exception), some pretty good clues will be
|
|
printed at the bottom of the traceback information.
|
|
|
|
This will help make failures in the event of a non-negative return code
|
|
more obvious when they go unhandled; the current behavior in
|
|
_post_shutdown() is to print a warning message only in the event of
|
|
signal-based terminations (for negative return codes).
|
|
|
|
(Note: In Python, catching BaseException instead of Exception catches a
|
|
broader array of Exception events, including SystemExit and
|
|
KeyboardInterrupt. We do not want to "wrap" such exceptions as a
|
|
VMLaunchFailure, because that will 'downgrade' the exception from a
|
|
BaseException to a regular Exception. We do, however, want to perform
|
|
cleanup in either case, so catch on the broadest scope and
|
|
wrap-and-re-raise only in the more targeted scope.)
|
|
|
|
Signed-off-by: John Snow <jsnow@redhat.com>
|
|
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
|
|
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
|
|
Message-id: 20220201041134.1237016-3-jsnow@redhat.com
|
|
Signed-off-by: John Snow <jsnow@redhat.com>
|
|
Signed-off-by: Li Zhang <lizhang@suse.de>
|
|
---
|
|
python/qemu/machine/machine.py | 45 ++++++++++++++++++++---
|
|
tests/qemu-iotests/tests/mirror-top-perms | 3 +-
|
|
2 files changed, 40 insertions(+), 8 deletions(-)
|
|
|
|
diff --git a/python/qemu/machine/machine.py b/python/qemu/machine/machine.py
|
|
index 67ab06ca2b6daa531b7c0ad9f7c2..a5972fab4d2b1fddfa2d5a7db882 100644
|
|
--- a/python/qemu/machine/machine.py
|
|
+++ b/python/qemu/machine/machine.py
|
|
@@ -74,6 +74,35 @@ class QEMUMachineAddDeviceError(QEMUMachineError):
|
|
"""
|
|
|
|
|
|
+class VMLaunchFailure(QEMUMachineError):
|
|
+ """
|
|
+ Exception raised when a VM launch was attempted, but failed.
|
|
+ """
|
|
+ def __init__(self, exitcode: Optional[int],
|
|
+ command: str, output: Optional[str]):
|
|
+ super().__init__(exitcode, command, output)
|
|
+ self.exitcode = exitcode
|
|
+ self.command = command
|
|
+ self.output = output
|
|
+
|
|
+ def __str__(self) -> str:
|
|
+ ret = ''
|
|
+ if self.__cause__ is not None:
|
|
+ name = type(self.__cause__).__name__
|
|
+ reason = str(self.__cause__)
|
|
+ if reason:
|
|
+ ret += f"{name}: {reason}"
|
|
+ else:
|
|
+ ret += f"{name}"
|
|
+ ret += '\n'
|
|
+
|
|
+ if self.exitcode is not None:
|
|
+ ret += f"\tExit code: {self.exitcode}\n"
|
|
+ ret += f"\tCommand: {self.command}\n"
|
|
+ ret += f"\tOutput: {self.output}\n"
|
|
+ return ret
|
|
+
|
|
+
|
|
class AbnormalShutdown(QEMUMachineError):
|
|
"""
|
|
Exception raised when a graceful shutdown was requested, but not performed.
|
|
@@ -397,7 +426,7 @@ class QEMUMachine:
|
|
|
|
try:
|
|
self._launch()
|
|
- except:
|
|
+ except BaseException as exc:
|
|
# We may have launched the process but it may
|
|
# have exited before we could connect via QMP.
|
|
# Assume the VM didn't launch or is exiting.
|
|
@@ -408,11 +437,15 @@ class QEMUMachine:
|
|
else:
|
|
self._post_shutdown()
|
|
|
|
- LOG.debug('Error launching VM')
|
|
- if self._qemu_full_args:
|
|
- LOG.debug('Command: %r', ' '.join(self._qemu_full_args))
|
|
- if self._iolog:
|
|
- LOG.debug('Output: %r', self._iolog)
|
|
+ if isinstance(exc, Exception):
|
|
+ raise VMLaunchFailure(
|
|
+ exitcode=self.exitcode(),
|
|
+ command=' '.join(self._qemu_full_args),
|
|
+ output=self._iolog
|
|
+ ) from exc
|
|
+
|
|
+ # Don't wrap 'BaseException'; doing so would downgrade
|
|
+ # that exception. However, we still want to clean up.
|
|
raise
|
|
|
|
def _launch(self) -> None:
|
|
diff --git a/tests/qemu-iotests/tests/mirror-top-perms b/tests/qemu-iotests/tests/mirror-top-perms
|
|
index 0a51a613f39764b2b3ab3fa460ef..b5849978c4158c35e18480186ea2 100755
|
|
--- a/tests/qemu-iotests/tests/mirror-top-perms
|
|
+++ b/tests/qemu-iotests/tests/mirror-top-perms
|
|
@@ -21,7 +21,6 @@
|
|
|
|
import os
|
|
|
|
-from qemu.aqmp import ConnectError
|
|
from qemu.machine import machine
|
|
from qemu.qmp import QMPConnectError
|
|
|
|
@@ -107,7 +106,7 @@ class TestMirrorTopPerms(iotests.QMPTestCase):
|
|
self.vm_b.launch()
|
|
print('ERROR: VM B launched successfully, '
|
|
'this should not have happened')
|
|
- except (QMPConnectError, ConnectError):
|
|
+ except (QMPConnectError, machine.VMLaunchFailure):
|
|
assert 'Is another process using the image' in self.vm_b.get_log()
|
|
|
|
result = self.vm.qmp('block-job-cancel',
|