|
|
43fe83 |
From d1105a7417a983af1cc6fa4ea6a0657fa6413481 Mon Sep 17 00:00:00 2001
|
|
|
43fe83 |
Message-Id: <d1105a7417a983af1cc6fa4ea6a0657fa6413481.1382534060.git.jdenemar@redhat.com>
|
|
|
43fe83 |
From: Peter Krempa <pkrempa@redhat.com>
|
|
|
43fe83 |
Date: Thu, 10 Oct 2013 13:56:31 +0200
|
|
|
43fe83 |
Subject: [PATCH] qemu: monitor: Produce better errors on monitor hangup
|
|
|
43fe83 |
|
|
|
43fe83 |
https://bugzilla.redhat.com/show_bug.cgi?id=1001738
|
|
|
43fe83 |
|
|
|
43fe83 |
Change the monitor error code to add the ability to access the qemu log
|
|
|
43fe83 |
file using a file descriptor so that we can dig in it for a more useful
|
|
|
43fe83 |
error message. The error is now logged on monitor hangups and overwrites
|
|
|
43fe83 |
a possible lesser error. A hangup on the monitor usualy means that qemu
|
|
|
43fe83 |
has crashed and there's a significant chance it produced a useful error
|
|
|
43fe83 |
message.
|
|
|
43fe83 |
|
|
|
43fe83 |
The functionality will be latent until the next patch.
|
|
|
43fe83 |
|
|
|
43fe83 |
(cherry picked from commit 90139a6236eb20a5cd2595af39ea11adae7d54de)
|
|
|
43fe83 |
|
|
|
43fe83 |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
43fe83 |
---
|
|
|
43fe83 |
src/qemu/qemu_monitor.c | 66 ++++++++++++++++++++++++++++++++++++++++++++-----
|
|
|
43fe83 |
1 file changed, 60 insertions(+), 6 deletions(-)
|
|
|
43fe83 |
|
|
|
43fe83 |
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
|
|
|
43fe83 |
index 2eb536c..cf4f954 100644
|
|
|
43fe83 |
--- a/src/qemu/qemu_monitor.c
|
|
|
43fe83 |
+++ b/src/qemu/qemu_monitor.c
|
|
|
43fe83 |
@@ -32,6 +32,8 @@
|
|
|
43fe83 |
#include "qemu_monitor.h"
|
|
|
43fe83 |
#include "qemu_monitor_text.h"
|
|
|
43fe83 |
#include "qemu_monitor_json.h"
|
|
|
43fe83 |
+#include "qemu_domain.h"
|
|
|
43fe83 |
+#include "qemu_process.h"
|
|
|
43fe83 |
#include "virerror.h"
|
|
|
43fe83 |
#include "viralloc.h"
|
|
|
43fe83 |
#include "virlog.h"
|
|
|
43fe83 |
@@ -332,6 +334,35 @@ qemuMonitorOpenPty(const char *monitor)
|
|
|
43fe83 |
}
|
|
|
43fe83 |
|
|
|
43fe83 |
|
|
|
43fe83 |
+/* Get a possible error from qemu's log. This function closes the
|
|
|
43fe83 |
+ * corresponding log fd */
|
|
|
43fe83 |
+static char *
|
|
|
43fe83 |
+qemuMonitorGetErrorFromLog(qemuMonitorPtr mon)
|
|
|
43fe83 |
+{
|
|
|
43fe83 |
+ int len;
|
|
|
43fe83 |
+ char *logbuf = NULL;
|
|
|
43fe83 |
+ int orig_errno = errno;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ if (mon->logfd < 0)
|
|
|
43fe83 |
+ return NULL;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ if (VIR_ALLOC_N_QUIET(logbuf, 4096) < 0)
|
|
|
43fe83 |
+ goto error;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ if ((len = qemuProcessReadLog(mon->logfd, logbuf, 4096 - 1, 0, true)) <= 0)
|
|
|
43fe83 |
+ goto error;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+cleanup:
|
|
|
43fe83 |
+ errno = orig_errno;
|
|
|
43fe83 |
+ VIR_FORCE_CLOSE(mon->logfd);
|
|
|
43fe83 |
+ return logbuf;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+error:
|
|
|
43fe83 |
+ VIR_FREE(logbuf);
|
|
|
43fe83 |
+ goto cleanup;
|
|
|
43fe83 |
+}
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+
|
|
|
43fe83 |
/* This method processes data that has been received
|
|
|
43fe83 |
* from the monitor. Looking for async events and
|
|
|
43fe83 |
* replies/errors.
|
|
|
43fe83 |
@@ -565,6 +596,7 @@ qemuMonitorIO(int watch, int fd, int events, void *opaque) {
|
|
|
43fe83 |
qemuMonitorPtr mon = opaque;
|
|
|
43fe83 |
bool error = false;
|
|
|
43fe83 |
bool eof = false;
|
|
|
43fe83 |
+ bool hangup = false;
|
|
|
43fe83 |
|
|
|
43fe83 |
virObjectRef(mon);
|
|
|
43fe83 |
|
|
|
43fe83 |
@@ -615,12 +647,14 @@ qemuMonitorIO(int watch, int fd, int events, void *opaque) {
|
|
|
43fe83 |
}
|
|
|
43fe83 |
}
|
|
|
43fe83 |
|
|
|
43fe83 |
- if (!error &&
|
|
|
43fe83 |
- events & VIR_EVENT_HANDLE_HANGUP) {
|
|
|
43fe83 |
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
43fe83 |
- _("End of file from monitor"));
|
|
|
43fe83 |
- eof = true;
|
|
|
43fe83 |
- events &= ~VIR_EVENT_HANDLE_HANGUP;
|
|
|
43fe83 |
+ if (events & VIR_EVENT_HANDLE_HANGUP) {
|
|
|
43fe83 |
+ hangup = true;
|
|
|
43fe83 |
+ if (!error) {
|
|
|
43fe83 |
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
43fe83 |
+ _("End of file from monitor"));
|
|
|
43fe83 |
+ eof = true;
|
|
|
43fe83 |
+ events &= ~VIR_EVENT_HANDLE_HANGUP;
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
}
|
|
|
43fe83 |
|
|
|
43fe83 |
if (!error && !eof &&
|
|
|
43fe83 |
@@ -639,6 +673,26 @@ qemuMonitorIO(int watch, int fd, int events, void *opaque) {
|
|
|
43fe83 |
}
|
|
|
43fe83 |
|
|
|
43fe83 |
if (error || eof) {
|
|
|
43fe83 |
+ if (hangup) {
|
|
|
43fe83 |
+ /* Check if an error message from qemu is available and if so, use
|
|
|
43fe83 |
+ * it to overwrite the actual message. It's done only in early
|
|
|
43fe83 |
+ * startup phases where the message from qemu is certainly more
|
|
|
43fe83 |
+ * interesting than a "connection reset by peer" message.
|
|
|
43fe83 |
+ */
|
|
|
43fe83 |
+ char *qemuMessage;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ if ((qemuMessage = qemuMonitorGetErrorFromLog(mon))) {
|
|
|
43fe83 |
+ virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
43fe83 |
+ _("early end of file from monitor: "
|
|
|
43fe83 |
+ "possible problem:\n%s"),
|
|
|
43fe83 |
+ qemuMessage);
|
|
|
43fe83 |
+ virCopyLastError(&mon->lastError);
|
|
|
43fe83 |
+ virResetLastError();
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ VIR_FREE(qemuMessage);
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+
|
|
|
43fe83 |
if (mon->lastError.code != VIR_ERR_OK) {
|
|
|
43fe83 |
/* Already have an error, so clear any new error */
|
|
|
43fe83 |
virResetLastError();
|
|
|
43fe83 |
--
|
|
|
43fe83 |
1.8.4
|
|
|
43fe83 |
|