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