In some cases (spotted with broken connection during tunneled migration)
we were overwriting the original error with worse or even misleading
errors generated when we were cleaning up after failed migration.
---
src/qemu/qemu_migration.c | 20 ++++++++++++++++++++
1 files changed, 20 insertions(+), 0 deletions(-)
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index fc83805..1bee66a 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -1733,6 +1733,7 @@ qemuMigrationRun(struct qemud_driver *driver,
qemuMigrationIOThreadPtr iothread = NULL;
int fd = -1;
unsigned long migrate_speed = resource ? resource : priv->migMaxBandwidth;
+ virErrorPtr orig_err = NULL;
VIR_DEBUG("driver=%p, vm=%p, cookiein=%s, cookieinlen=%d, "
"cookieout=%p, cookieoutlen=%p, flags=%lx, resource=%lu, "
@@ -1874,6 +1875,9 @@ qemuMigrationRun(struct qemud_driver *driver,
ret = 0;
cleanup:
+ if (ret < 0 && !orig_err)
+ orig_err = virSaveLastError();
+
if (spec->fwdType != MIGRATION_FWD_DIRECT) {
/* Close now to ensure the IO thread quits & is joinable */
VIR_FORCE_CLOSE(fd);
@@ -1888,9 +1892,16 @@ cleanup:
qemuMigrationCookieFree(mig);
+ if (orig_err) {
+ virSetError(orig_err);
+ virFreeError(orig_err);
+ }
+
return ret;
cancel:
+ orig_err = virSaveLastError();
+
if (virDomainObjIsActive(vm)) {
if (qemuDomainObjEnterMonitorAsync(driver, vm,
QEMU_ASYNC_JOB_MIGRATION_OUT) == 0) {
@@ -2495,6 +2506,7 @@ qemuMigrationPerformJob(struct qemud_driver *driver,
virDomainEventPtr event = NULL;
int ret = -1;
int resume = 0;
+ virErrorPtr orig_err = NULL;
if (qemuMigrationJobStart(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT) < 0)
goto cleanup;
@@ -2540,6 +2552,9 @@ qemuMigrationPerformJob(struct qemud_driver *driver,
resume = 0;
endjob:
+ if (ret < 0)
+ orig_err = virSaveLastError();
+
if (resume && virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PAUSED) {
/* we got here through some sort of failure; start the domain again */
if (qemuProcessStartCPUs(driver, vm, conn,
@@ -2569,6 +2584,11 @@ endjob:
vm = NULL;
}
+ if (orig_err) {
+ virSetError(orig_err);
+ virFreeError(orig_err);
+ }
+
cleanup:
if (vm)
virDomainObjUnlock(vm);
--
1.7.8.5