提交 90139a62 编写于 作者: P Peter Krempa

qemu: monitor: Produce better errors on monitor hangup

Change the monitor error code to add the ability to access the qemu log
file using a file descriptor so that we can dig in it for a more useful
error message. The error is now logged on monitor hangups and overwrites
a possible lesser error. A hangup on the monitor usualy means that qemu
has crashed and there's a significant chance it produced a useful error
message.

The functionality will be latent until the next patch.
上级 8519e9ec
......@@ -32,6 +32,8 @@
#include "qemu_monitor.h"
#include "qemu_monitor_text.h"
#include "qemu_monitor_json.h"
#include "qemu_domain.h"
#include "qemu_process.h"
#include "virerror.h"
#include "viralloc.h"
#include "virlog.h"
......@@ -331,6 +333,35 @@ qemuMonitorOpenPty(const char *monitor)
}
/* Get a possible error from qemu's log. This function closes the
* corresponding log fd */
static char *
qemuMonitorGetErrorFromLog(qemuMonitorPtr mon)
{
int len;
char *logbuf = NULL;
int orig_errno = errno;
if (mon->logfd < 0)
return NULL;
if (VIR_ALLOC_N_QUIET(logbuf, 4096) < 0)
goto error;
if ((len = qemuProcessReadLog(mon->logfd, logbuf, 4096 - 1, 0, true)) <= 0)
goto error;
cleanup:
errno = orig_errno;
VIR_FORCE_CLOSE(mon->logfd);
return logbuf;
error:
VIR_FREE(logbuf);
goto cleanup;
}
/* This method processes data that has been received
* from the monitor. Looking for async events and
* replies/errors.
......@@ -564,6 +595,7 @@ qemuMonitorIO(int watch, int fd, int events, void *opaque) {
qemuMonitorPtr mon = opaque;
bool error = false;
bool eof = false;
bool hangup = false;
virObjectRef(mon);
......@@ -614,12 +646,14 @@ qemuMonitorIO(int watch, int fd, int events, void *opaque) {
}
}
if (!error &&
events & VIR_EVENT_HANDLE_HANGUP) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("End of file from monitor"));
eof = true;
events &= ~VIR_EVENT_HANDLE_HANGUP;
if (events & VIR_EVENT_HANDLE_HANGUP) {
hangup = true;
if (!error) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("End of file from monitor"));
eof = true;
events &= ~VIR_EVENT_HANDLE_HANGUP;
}
}
if (!error && !eof &&
......@@ -638,6 +672,26 @@ qemuMonitorIO(int watch, int fd, int events, void *opaque) {
}
if (error || eof) {
if (hangup) {
/* Check if an error message from qemu is available and if so, use
* it to overwrite the actual message. It's done only in early
* startup phases where the message from qemu is certainly more
* interesting than a "connection reset by peer" message.
*/
char *qemuMessage;
if ((qemuMessage = qemuMonitorGetErrorFromLog(mon))) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("early end of file from monitor: "
"possible problem:\n%s"),
qemuMessage);
virCopyLastError(&mon->lastError);
virResetLastError();
}
VIR_FREE(qemuMessage);
}
if (mon->lastError.code != VIR_ERR_OK) {
/* Already have an error, so clear any new error */
virResetLastError();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册