|
|
43fe83 |
From 4ac6f237fe6ec1c681aab55b4745a14da51e1fd3 Mon Sep 17 00:00:00 2001
|
|
|
43fe83 |
Message-Id: <4ac6f237fe6ec1c681aab55b4745a14da51e1fd3.1382534060.git.jdenemar@redhat.com>
|
|
|
43fe83 |
From: Peter Krempa <pkrempa@redhat.com>
|
|
|
43fe83 |
Date: Thu, 10 Oct 2013 13:56:32 +0200
|
|
|
43fe83 |
Subject: [PATCH] qemu: Wire up better early error reporting
|
|
|
43fe83 |
|
|
|
43fe83 |
https://bugzilla.redhat.com/show_bug.cgi?id=1001738
|
|
|
43fe83 |
|
|
|
43fe83 |
The previous patches added infrastructure to report better errors from
|
|
|
43fe83 |
monitor in some cases. This patch finalizes this "feature" by enabling
|
|
|
43fe83 |
this enhanced error reporting on early phases of VM startup. In these
|
|
|
43fe83 |
phases the possibility of qemu producing a useful error message is
|
|
|
43fe83 |
really high compared to running it during the whole life cycle. After
|
|
|
43fe83 |
the start up is complete, the feature is disabled to provide the usual
|
|
|
43fe83 |
error messages so that users are not confused by possibly irrelevant
|
|
|
43fe83 |
messages that may be in the domain log.
|
|
|
43fe83 |
|
|
|
43fe83 |
The original motivation to do this enhancement is to capture errors when
|
|
|
43fe83 |
using VFIO device passthrough, where qemu reports errors after the
|
|
|
43fe83 |
monitor is initialized and the existing error catching code couldn't
|
|
|
43fe83 |
catch this producing a unhelpful message:
|
|
|
43fe83 |
|
|
|
43fe83 |
# virsh start test
|
|
|
43fe83 |
error: Failed to start domain test
|
|
|
43fe83 |
error: Unable to read from monitor: Connection reset by peer
|
|
|
43fe83 |
|
|
|
43fe83 |
With this change, the message is changed to:
|
|
|
43fe83 |
|
|
|
43fe83 |
# virsh start test
|
|
|
43fe83 |
error: Failed to start domain test
|
|
|
43fe83 |
error: internal error: early end of file from monitor: possible problem:
|
|
|
43fe83 |
qemu-system-x86_64: -device vfio-pci,host=00:1a.0,id=hostdev0,bus=pci.0,addr=0x5: vfio: error, group 8 is not viable, please ensure all devices within the iommu_group are bound to their vfio bus driver.
|
|
|
43fe83 |
qemu-system-x86_64: -device vfio-pci,host=00:1a.0,id=hostdev0,bus=pci.0,addr=0x5: vfio: failed to get group 8
|
|
|
43fe83 |
qemu-system-x86_64: -device vfio-pci,host=00:1a.0,id=hostdev0,bus=pci.0,addr=0x5: Device 'vfio-pci' could not be initialized
|
|
|
43fe83 |
|
|
|
43fe83 |
(cherry picked from commit ef29de14c37d14abc546e90555a0093797facfdd)
|
|
|
43fe83 |
|
|
|
43fe83 |
Conflicts:
|
|
|
43fe83 |
src/qemu/qemu_process.c
|
|
|
43fe83 |
|
|
|
43fe83 |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
43fe83 |
---
|
|
|
43fe83 |
src/qemu/qemu_process.c | 29 +++++++++++++++++++----------
|
|
|
43fe83 |
1 file changed, 19 insertions(+), 10 deletions(-)
|
|
|
43fe83 |
|
|
|
43fe83 |
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
|
|
|
43fe83 |
index 063cd78..c991d04 100644
|
|
|
43fe83 |
--- a/src/qemu/qemu_process.c
|
|
|
43fe83 |
+++ b/src/qemu/qemu_process.c
|
|
|
43fe83 |
@@ -1368,7 +1368,7 @@ static qemuMonitorCallbacks monitorCallbacks = {
|
|
|
43fe83 |
};
|
|
|
43fe83 |
|
|
|
43fe83 |
static int
|
|
|
43fe83 |
-qemuConnectMonitor(virQEMUDriverPtr driver, virDomainObjPtr vm)
|
|
|
43fe83 |
+qemuConnectMonitor(virQEMUDriverPtr driver, virDomainObjPtr vm, int logfd)
|
|
|
43fe83 |
{
|
|
|
43fe83 |
qemuDomainObjPrivatePtr priv = vm->privateData;
|
|
|
43fe83 |
int ret = -1;
|
|
|
43fe83 |
@@ -1393,6 +1393,9 @@ qemuConnectMonitor(virQEMUDriverPtr driver, virDomainObjPtr vm)
|
|
|
43fe83 |
priv->monJSON,
|
|
|
43fe83 |
&monitorCallbacks);
|
|
|
43fe83 |
|
|
|
43fe83 |
+ if (mon)
|
|
|
43fe83 |
+ ignore_value(qemuMonitorSetDomainLog(mon, logfd));
|
|
|
43fe83 |
+
|
|
|
43fe83 |
virObjectLock(vm);
|
|
|
43fe83 |
priv->monStart = 0;
|
|
|
43fe83 |
|
|
|
43fe83 |
@@ -1767,10 +1770,11 @@ qemuProcessWaitForMonitor(virQEMUDriverPtr driver,
|
|
|
43fe83 |
virHashTablePtr paths = NULL;
|
|
|
43fe83 |
qemuDomainObjPrivatePtr priv;
|
|
|
43fe83 |
|
|
|
43fe83 |
- if (!virQEMUCapsUsedQMP(qemuCaps) && pos != -1) {
|
|
|
43fe83 |
- if ((logfd = qemuDomainOpenLog(driver, vm, pos)) < 0)
|
|
|
43fe83 |
- return -1;
|
|
|
43fe83 |
+ if (pos != -1 &&
|
|
|
43fe83 |
+ (logfd = qemuDomainOpenLog(driver, vm, pos)) < 0)
|
|
|
43fe83 |
+ return -1;
|
|
|
43fe83 |
|
|
|
43fe83 |
+ if (logfd != -1 && !virQEMUCapsUsedQMP(qemuCaps)) {
|
|
|
43fe83 |
if (VIR_ALLOC_N(buf, buf_size) < 0)
|
|
|
43fe83 |
goto closelog;
|
|
|
43fe83 |
|
|
|
43fe83 |
@@ -1781,9 +1785,8 @@ qemuProcessWaitForMonitor(virQEMUDriverPtr driver,
|
|
|
43fe83 |
}
|
|
|
43fe83 |
|
|
|
43fe83 |
VIR_DEBUG("Connect monitor to %p '%s'", vm, vm->def->name);
|
|
|
43fe83 |
- if (qemuConnectMonitor(driver, vm) < 0) {
|
|
|
43fe83 |
+ if (qemuConnectMonitor(driver, vm, logfd) < 0)
|
|
|
43fe83 |
goto cleanup;
|
|
|
43fe83 |
- }
|
|
|
43fe83 |
|
|
|
43fe83 |
/* Try to get the pty path mappings again via the monitor. This is much more
|
|
|
43fe83 |
* reliable if it's available.
|
|
|
43fe83 |
@@ -1810,14 +1813,15 @@ cleanup:
|
|
|
43fe83 |
/* VM is dead, any other error raised in the interim is probably
|
|
|
43fe83 |
* not as important as the qemu cmdline output */
|
|
|
43fe83 |
if (virQEMUCapsUsedQMP(qemuCaps)) {
|
|
|
43fe83 |
- if ((logfd = qemuDomainOpenLog(driver, vm, pos)) < 0)
|
|
|
43fe83 |
- return -1;
|
|
|
43fe83 |
-
|
|
|
43fe83 |
if (VIR_ALLOC_N(buf, buf_size) < 0)
|
|
|
43fe83 |
goto closelog;
|
|
|
43fe83 |
}
|
|
|
43fe83 |
|
|
|
43fe83 |
len = strlen(buf);
|
|
|
43fe83 |
+ /* best effor seek - we need to reset to the original position, so that
|
|
|
43fe83 |
+ * a possible read of the fd in the monitor code doesn't influence this
|
|
|
43fe83 |
+ * error delivery option */
|
|
|
43fe83 |
+ lseek(logfd, pos, SEEK_SET);
|
|
|
43fe83 |
qemuProcessReadLog(logfd, buf + len, buf_size - len - 1, 0, true);
|
|
|
43fe83 |
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
43fe83 |
_("process exited while connecting to monitor: %s"),
|
|
|
43fe83 |
@@ -3052,7 +3056,7 @@ qemuProcessReconnect(void *opaque)
|
|
|
43fe83 |
virObjectRef(obj);
|
|
|
43fe83 |
|
|
|
43fe83 |
/* XXX check PID liveliness & EXE path */
|
|
|
43fe83 |
- if (qemuConnectMonitor(driver, obj) < 0)
|
|
|
43fe83 |
+ if (qemuConnectMonitor(driver, obj, -1) < 0)
|
|
|
43fe83 |
goto error;
|
|
|
43fe83 |
|
|
|
43fe83 |
/* Failure to connect to agent shouldn't be fatal */
|
|
|
43fe83 |
@@ -4020,6 +4024,9 @@ int qemuProcessStart(virConnectPtr conn,
|
|
|
43fe83 |
goto cleanup;
|
|
|
43fe83 |
}
|
|
|
43fe83 |
|
|
|
43fe83 |
+ /* unset reporting errors from qemu log */
|
|
|
43fe83 |
+ qemuMonitorSetDomainLog(priv->mon, -1);
|
|
|
43fe83 |
+
|
|
|
43fe83 |
virCommandFree(cmd);
|
|
|
43fe83 |
VIR_FORCE_CLOSE(logfile);
|
|
|
43fe83 |
virObjectUnref(cfg);
|
|
|
43fe83 |
@@ -4035,6 +4042,8 @@ cleanup:
|
|
|
43fe83 |
virBitmapFree(nodemask);
|
|
|
43fe83 |
virCommandFree(cmd);
|
|
|
43fe83 |
VIR_FORCE_CLOSE(logfile);
|
|
|
43fe83 |
+ if (priv->mon)
|
|
|
43fe83 |
+ qemuMonitorSetDomainLog(priv->mon, -1);
|
|
|
43fe83 |
qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED, stop_flags);
|
|
|
43fe83 |
virObjectUnref(cfg);
|
|
|
43fe83 |
virObjectUnref(caps);
|
|
|
43fe83 |
--
|
|
|
43fe83 |
1.8.4
|
|
|
43fe83 |
|