|
|
c1c534 |
From 0b0135f00c4e17cb902ec6885648b5a4e667d56b Mon Sep 17 00:00:00 2001
|
|
|
c1c534 |
Message-Id: <0b0135f00c4e17cb902ec6885648b5a4e667d56b@dist-git>
|
|
|
c1c534 |
From: Jiri Denemark <jdenemar@redhat.com>
|
|
|
c1c534 |
Date: Wed, 22 Nov 2017 13:12:00 +0100
|
|
|
c1c534 |
Subject: [PATCH] qemu: Use the end of QEMU log for reporting errors
|
|
|
c1c534 |
|
|
|
c1c534 |
When QEMU dies, we read its output stored in a log file and use it for
|
|
|
c1c534 |
reporting a hopefully useful error. However, virReportError will trim
|
|
|
c1c534 |
the message to (VIR_ERROR_MAX_LENGTH - 1) characters, which means the
|
|
|
c1c534 |
end of the log (which likely contains the error message we want to
|
|
|
c1c534 |
report) may get lost. We should trim the beginning of the log instead.
|
|
|
c1c534 |
|
|
|
c1c534 |
https://bugzilla.redhat.com/show_bug.cgi?id=1335534
|
|
|
c1c534 |
|
|
|
c1c534 |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
c1c534 |
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
|
|
|
c1c534 |
(cherry picked from commit 96f7a045e93ad08eb4130be97dd6d8a8c963a952)
|
|
|
c1c534 |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
c1c534 |
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
|
|
|
c1c534 |
---
|
|
|
c1c534 |
src/qemu/qemu_process.c | 34 ++++++++++++++++++++++++++++++----
|
|
|
c1c534 |
1 file changed, 30 insertions(+), 4 deletions(-)
|
|
|
c1c534 |
|
|
|
c1c534 |
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
|
|
|
c1c534 |
index c5fa8cb4b2..f7808227a8 100644
|
|
|
c1c534 |
--- a/src/qemu/qemu_process.c
|
|
|
c1c534 |
+++ b/src/qemu/qemu_process.c
|
|
|
c1c534 |
@@ -1827,17 +1827,24 @@ qemuConnectMonitor(virQEMUDriverPtr driver, virDomainObjPtr vm, int asyncJob,
|
|
|
c1c534 |
* qemuProcessReadLog: Read log file of a qemu VM
|
|
|
c1c534 |
* @logCtxt: the domain log context
|
|
|
c1c534 |
* @msg: pointer to buffer to store the read messages in
|
|
|
c1c534 |
+ * @max: maximum length of the message returned in @msg
|
|
|
c1c534 |
*
|
|
|
c1c534 |
* Reads log of a qemu VM. Skips messages not produced by qemu or irrelevant
|
|
|
c1c534 |
- * messages. Returns returns 0 on success or -1 on error
|
|
|
c1c534 |
+ * messages. If @max is not zero, @msg will contain at most @max characters
|
|
|
c1c534 |
+ * from the end of the log and @msg will start after a new line if possible.
|
|
|
c1c534 |
+ *
|
|
|
c1c534 |
+ * Returns 0 on success or -1 on error
|
|
|
c1c534 |
*/
|
|
|
c1c534 |
static int
|
|
|
c1c534 |
-qemuProcessReadLog(qemuDomainLogContextPtr logCtxt, char **msg)
|
|
|
c1c534 |
+qemuProcessReadLog(qemuDomainLogContextPtr logCtxt,
|
|
|
c1c534 |
+ char **msg,
|
|
|
c1c534 |
+ size_t max)
|
|
|
c1c534 |
{
|
|
|
c1c534 |
char *buf;
|
|
|
c1c534 |
ssize_t got;
|
|
|
c1c534 |
char *eol;
|
|
|
c1c534 |
char *filter_next;
|
|
|
c1c534 |
+ size_t skip;
|
|
|
c1c534 |
|
|
|
c1c534 |
if ((got = qemuDomainLogContextRead(logCtxt, &buf)) < 0)
|
|
|
c1c534 |
return -1;
|
|
|
c1c534 |
@@ -1848,7 +1855,7 @@ qemuProcessReadLog(qemuDomainLogContextPtr logCtxt, char **msg)
|
|
|
c1c534 |
*eol = '\0';
|
|
|
c1c534 |
if (virLogProbablyLogMessage(filter_next) ||
|
|
|
c1c534 |
strstr(filter_next, "char device redirected to")) {
|
|
|
c1c534 |
- size_t skip = (eol + 1) - filter_next;
|
|
|
c1c534 |
+ skip = (eol + 1) - filter_next;
|
|
|
c1c534 |
memmove(filter_next, eol + 1, buf + got - eol);
|
|
|
c1c534 |
got -= skip;
|
|
|
c1c534 |
} else {
|
|
|
c1c534 |
@@ -1863,6 +1870,19 @@ qemuProcessReadLog(qemuDomainLogContextPtr logCtxt, char **msg)
|
|
|
c1c534 |
buf[got - 1] = '\0';
|
|
|
c1c534 |
got--;
|
|
|
c1c534 |
}
|
|
|
c1c534 |
+
|
|
|
c1c534 |
+ if (max > 0 && got > max) {
|
|
|
c1c534 |
+ skip = got - max;
|
|
|
c1c534 |
+
|
|
|
c1c534 |
+ if (buf[skip - 1] != '\n' &&
|
|
|
c1c534 |
+ (eol = strchr(buf + skip, '\n')) &&
|
|
|
c1c534 |
+ !virStringIsEmpty(eol + 1))
|
|
|
c1c534 |
+ skip = eol + 1 - buf;
|
|
|
c1c534 |
+
|
|
|
c1c534 |
+ memmove(buf, buf + skip, got - skip + 1);
|
|
|
c1c534 |
+ got -= skip;
|
|
|
c1c534 |
+ }
|
|
|
c1c534 |
+
|
|
|
c1c534 |
ignore_value(VIR_REALLOC_N_QUIET(buf, got + 1));
|
|
|
c1c534 |
*msg = buf;
|
|
|
c1c534 |
return 0;
|
|
|
c1c534 |
@@ -1874,8 +1894,14 @@ qemuProcessReportLogError(qemuDomainLogContextPtr logCtxt,
|
|
|
c1c534 |
const char *msgprefix)
|
|
|
c1c534 |
{
|
|
|
c1c534 |
char *logmsg = NULL;
|
|
|
c1c534 |
+ size_t max;
|
|
|
c1c534 |
|
|
|
c1c534 |
- if (qemuProcessReadLog(logCtxt, &logmsg) < 0)
|
|
|
c1c534 |
+ max = VIR_ERROR_MAX_LENGTH - 1;
|
|
|
c1c534 |
+ max -= strlen(msgprefix);
|
|
|
c1c534 |
+ /* The length of the formatting string minus two '%s' */
|
|
|
c1c534 |
+ max -= strlen(_("%s: %s")) - 4;
|
|
|
c1c534 |
+
|
|
|
c1c534 |
+ if (qemuProcessReadLog(logCtxt, &logmsg, max) < 0)
|
|
|
c1c534 |
return -1;
|
|
|
c1c534 |
|
|
|
c1c534 |
virResetLastError();
|
|
|
c1c534 |
--
|
|
|
c1c534 |
2.15.0
|
|
|
c1c534 |
|