From: "Daniel P. Berrange" <berrange(a)redhat.com>
If an LXC VM fails to start, quite a few cleanup paths will
result in the original error message being overwritten. Some
other cleanup paths also forgot to actually terminate the VM.
* src/lxc/lxc_driver.c: Ensure VM is terminated on startup
failure and preserve original error
---
src/lxc/lxc_driver.c | 29 +++++++++++++++++++++--------
1 files changed, 21 insertions(+), 8 deletions(-)
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index 23efe1e..eabc1fb 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -1622,6 +1622,7 @@ static int lxcVmStart(virConnectPtr conn,
char *timestamp;
virCommandPtr cmd = NULL;
lxcDomainObjPrivatePtr priv = vm->privateData;
+ virErrorPtr err = NULL;
if (!lxc_driver->cgroup) {
lxcError(VIR_ERR_INTERNAL_ERROR, "%s",
@@ -1753,8 +1754,7 @@ static int lxcVmStart(virConnectPtr conn,
_("guest failed to start: %s"), out);
}
- lxcVmTerminate(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED);
- goto cleanup;
+ goto error;
}
if ((priv->monitorWatch = virEventAddHandle(
@@ -1762,31 +1762,33 @@ static int lxcVmStart(virConnectPtr conn,
VIR_EVENT_HANDLE_ERROR | VIR_EVENT_HANDLE_HANGUP,
lxcMonitorEvent,
vm, NULL)) < 0) {
- lxcVmTerminate(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED);
- goto cleanup;
+ goto error;
}
if (autoDestroy &&
lxcProcessAutoDestroyAdd(driver, vm, conn) < 0)
- goto cleanup;
+ goto error;
/*
* Again, need to save the live configuration, because the function
* requires vm->def->id != -1 to save tty info surely.
*/
if (virDomainSaveConfig(driver->stateDir, vm->def) < 0)
- goto cleanup;
+ goto error;
if (virDomainObjSetDefTransient(driver->caps, vm, false) < 0)
- goto cleanup;
+ goto error;
/* Write domain status to disk. */
if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0)
- goto cleanup;
+ goto error;
rc = 0;
cleanup:
+ if (rc != 0 && !err)
+ err = virSaveLastError();
+ VIR_WARN("Cleanup %s" , err && err->message ? err->message :
NULL);
virCommandFree(cmd);
if (VIR_CLOSE(logfd) < 0) {
virReportSystemError(errno, "%s", _("could not close
logfile"));
@@ -1805,7 +1807,18 @@ cleanup:
VIR_FORCE_CLOSE(handshakefds[0]);
VIR_FORCE_CLOSE(handshakefds[1]);
VIR_FREE(logfile);
+
+ if (err) {
+ virSetError(err);
+ virResetError(err);
+ }
+
return rc;
+
+error:
+ err = virSaveLastError();
+ lxcVmTerminate(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED);
+ goto cleanup;
}
/**
--
1.7.6.4