From 6fb618488723ceee1f422006b2517154733cd0dc Mon Sep 17 00:00:00 2001 Message-Id: <6fb618488723ceee1f422006b2517154733cd0dc.1381871412.git.jdenemar@redhat.com> From: "Daniel P. Berrange" Date: Mon, 14 Oct 2013 16:45:22 +0100 Subject: [PATCH] Improve error reporting with LXC controller For https://bugzilla.redhat.com/show_bug.cgi?id=927072 The LXC code would read the log file if an LXC guest failed to startup. There were a number of failure cases where the guest will not start and libvirtd never gets as far as looking at the log file. Fix this by replacing some earlier generic errors with messages from the log. Signed-off-by: Daniel P. Berrange (cherry picked from commit 1815e2d0812a9cd1c85363e93db5c00e302d1c96) Signed-off-by: Jiri Denemark --- src/lxc/lxc_process.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c index 724ffa9..ccf86af 100644 --- a/src/lxc/lxc_process.c +++ b/src/lxc/lxc_process.c @@ -980,6 +980,7 @@ int virLXCProcessStart(virConnectPtr conn, virErrorPtr err = NULL; virLXCDriverConfigPtr cfg = virLXCDriverGetConfig(driver); virCgroupPtr selfcgroup; + int status; if (virCgroupNewSelf(&selfcgroup) < 0) return -1; @@ -1182,9 +1183,18 @@ int virLXCProcessStart(virConnectPtr conn, VIR_WARN("Unable to seek to end of logfile: %s", virStrerror(errno, ebuf, sizeof(ebuf))); - if (virCommandRun(cmd, NULL) < 0) + if (virCommandRun(cmd, &status) < 0) goto cleanup; + if (status != 0) { + if (virLXCProcessReadLogOutput(vm, logfile, pos, ebuf, sizeof(ebuf)) <= 0) + snprintf(ebuf, sizeof(ebuf), "unexpected exit status %d", status); + virReportError(VIR_ERR_INTERNAL_ERROR, + _("guest failed to start: %s"), ebuf); + goto cleanup; + } + + if (VIR_CLOSE(handshakefds[1]) < 0) { virReportSystemError(errno, "%s", _("could not close handshake fd")); goto cleanup; @@ -1193,16 +1203,23 @@ int virLXCProcessStart(virConnectPtr conn, /* Connect to the controller as a client *first* because * this will block until the child has written their * pid file out to disk & created their cgroup */ - if (!(priv->monitor = virLXCProcessConnectMonitor(driver, vm))) + if (!(priv->monitor = virLXCProcessConnectMonitor(driver, vm))) { + /* Intentionally overwrite the real monitor error message, + * since a better one is almost always found in the logs + */ + if (virLXCProcessReadLogOutput(vm, logfile, pos, ebuf, sizeof(ebuf)) > 0) { + virResetLastError(); + virReportError(VIR_ERR_INTERNAL_ERROR, + _("guest failed to start: %s"), ebuf); + } goto cleanup; + } /* And get its pid */ if ((r = virPidFileRead(cfg->stateDir, vm->def->name, &vm->pid)) < 0) { - char out[1024]; - - if (virLXCProcessReadLogOutput(vm, logfile, pos, out, 1024) > 0) + if (virLXCProcessReadLogOutput(vm, logfile, pos, ebuf, sizeof(ebuf)) > 0) virReportError(VIR_ERR_INTERNAL_ERROR, - _("guest failed to start: %s"), out); + _("guest failed to start: %s"), ebuf); else virReportSystemError(-r, _("Failed to read pid file %s/%s.pid"), -- 1.8.3.2