|
|
7a3408 |
From 9ac80cb260482543d02c9d8fd79162c05d684a74 Mon Sep 17 00:00:00 2001
|
|
|
7a3408 |
Message-Id: <9ac80cb260482543d02c9d8fd79162c05d684a74@dist-git>
|
|
|
7a3408 |
From: Jiri Denemark <jdenemar@redhat.com>
|
|
|
7a3408 |
Date: Thu, 2 Jul 2015 21:46:56 +0200
|
|
|
7a3408 |
Subject: [PATCH] qemu: Use error from Finish instead of "unexpectedly failed"
|
|
|
7a3408 |
|
|
|
7a3408 |
When QEMU exits on destination during migration, the source reports
|
|
|
7a3408 |
either success (if the failure happened at the very end) or unhelpful
|
|
|
7a3408 |
"unexpectedly failed" error message. However, the Finish API called on
|
|
|
7a3408 |
the destination may report a real error so let's use it instead of the
|
|
|
7a3408 |
generic one.
|
|
|
7a3408 |
|
|
|
7a3408 |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
7a3408 |
(cherry picked from commit 2e7cea24355328102c40dd127329ddf47d55a3e2)
|
|
|
7a3408 |
|
|
|
7a3408 |
https://bugzilla.redhat.com/show_bug.cgi?id=1090093
|
|
|
7a3408 |
|
|
|
7a3408 |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
7a3408 |
---
|
|
|
7a3408 |
src/libvirt-domain.c | 30 ++++++++++++++++++++++++++++--
|
|
|
7a3408 |
src/qemu/qemu_migration.c | 39 +++++++++++++++++++++++++++++++++++++--
|
|
|
7a3408 |
2 files changed, 65 insertions(+), 4 deletions(-)
|
|
|
7a3408 |
|
|
|
7a3408 |
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
|
|
|
7a3408 |
index 909c264..837933f 100644
|
|
|
7a3408 |
--- a/src/libvirt-domain.c
|
|
|
7a3408 |
+++ b/src/libvirt-domain.c
|
|
|
7a3408 |
@@ -3175,8 +3175,34 @@ virDomainMigrateVersion3Full(virDomainPtr domain,
|
|
|
7a3408 |
(dconn, dname, cookiein, cookieinlen, &cookieout, &cookieoutlen,
|
|
|
7a3408 |
NULL, uri, destflags, cancelled);
|
|
|
7a3408 |
}
|
|
|
7a3408 |
- if (cancelled && ddomain)
|
|
|
7a3408 |
- VIR_ERROR(_("finish step ignored that migration was cancelled"));
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+ if (cancelled) {
|
|
|
7a3408 |
+ if (ddomain) {
|
|
|
7a3408 |
+ VIR_ERROR(_("finish step ignored that migration was cancelled"));
|
|
|
7a3408 |
+ } else {
|
|
|
7a3408 |
+ /* If Finish reported a useful error, use it instead of the
|
|
|
7a3408 |
+ * original "migration unexpectedly failed" error.
|
|
|
7a3408 |
+ *
|
|
|
7a3408 |
+ * This is ugly but we can't do better with the APIs we have. We
|
|
|
7a3408 |
+ * only replace the error if Finish was called with cancelled == 1
|
|
|
7a3408 |
+ * and reported a real error (old libvirt would report an error
|
|
|
7a3408 |
+ * from RPC instead of MIGRATE_FINISH_OK), which only happens when
|
|
|
7a3408 |
+ * the domain died on destination. To further reduce a possibility
|
|
|
7a3408 |
+ * of false positives we also check that Perform returned
|
|
|
7a3408 |
+ * VIR_ERR_OPERATION_FAILED.
|
|
|
7a3408 |
+ */
|
|
|
7a3408 |
+ if (orig_err &&
|
|
|
7a3408 |
+ orig_err->domain == VIR_FROM_QEMU &&
|
|
|
7a3408 |
+ orig_err->code == VIR_ERR_OPERATION_FAILED) {
|
|
|
7a3408 |
+ virErrorPtr err = virGetLastError();
|
|
|
7a3408 |
+ if (err->domain == VIR_FROM_QEMU &&
|
|
|
7a3408 |
+ err->code != VIR_ERR_MIGRATE_FINISH_OK) {
|
|
|
7a3408 |
+ virFreeError(orig_err);
|
|
|
7a3408 |
+ orig_err = NULL;
|
|
|
7a3408 |
+ }
|
|
|
7a3408 |
+ }
|
|
|
7a3408 |
+ }
|
|
|
7a3408 |
+ }
|
|
|
7a3408 |
|
|
|
7a3408 |
/* If ddomain is NULL, then we were unable to start
|
|
|
7a3408 |
* the guest on the target, and must restart on the
|
|
|
7a3408 |
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
|
|
|
7a3408 |
index a9cbada..d789110 100644
|
|
|
7a3408 |
--- a/src/qemu/qemu_migration.c
|
|
|
7a3408 |
+++ b/src/qemu/qemu_migration.c
|
|
|
7a3408 |
@@ -4982,8 +4982,34 @@ doPeer2PeerMigrate3(virQEMUDriverPtr driver,
|
|
|
7a3408 |
dconnuri, uri, destflags, cancelled);
|
|
|
7a3408 |
qemuDomainObjExitRemote(vm);
|
|
|
7a3408 |
}
|
|
|
7a3408 |
- if (cancelled && ddomain)
|
|
|
7a3408 |
- VIR_ERROR(_("finish step ignored that migration was cancelled"));
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+ if (cancelled) {
|
|
|
7a3408 |
+ if (ddomain) {
|
|
|
7a3408 |
+ VIR_ERROR(_("finish step ignored that migration was cancelled"));
|
|
|
7a3408 |
+ } else {
|
|
|
7a3408 |
+ /* If Finish reported a useful error, use it instead of the
|
|
|
7a3408 |
+ * original "migration unexpectedly failed" error.
|
|
|
7a3408 |
+ *
|
|
|
7a3408 |
+ * This is ugly but we can't do better with the APIs we have. We
|
|
|
7a3408 |
+ * only replace the error if Finish was called with cancelled == 1
|
|
|
7a3408 |
+ * and reported a real error (old libvirt would report an error
|
|
|
7a3408 |
+ * from RPC instead of MIGRATE_FINISH_OK), which only happens when
|
|
|
7a3408 |
+ * the domain died on destination. To further reduce a possibility
|
|
|
7a3408 |
+ * of false positives we also check that Perform returned
|
|
|
7a3408 |
+ * VIR_ERR_OPERATION_FAILED.
|
|
|
7a3408 |
+ */
|
|
|
7a3408 |
+ if (orig_err &&
|
|
|
7a3408 |
+ orig_err->domain == VIR_FROM_QEMU &&
|
|
|
7a3408 |
+ orig_err->code == VIR_ERR_OPERATION_FAILED) {
|
|
|
7a3408 |
+ virErrorPtr err = virGetLastError();
|
|
|
7a3408 |
+ if (err->domain == VIR_FROM_QEMU &&
|
|
|
7a3408 |
+ err->code != VIR_ERR_MIGRATE_FINISH_OK) {
|
|
|
7a3408 |
+ virFreeError(orig_err);
|
|
|
7a3408 |
+ orig_err = NULL;
|
|
|
7a3408 |
+ }
|
|
|
7a3408 |
+ }
|
|
|
7a3408 |
+ }
|
|
|
7a3408 |
+ }
|
|
|
7a3408 |
|
|
|
7a3408 |
/* If ddomain is NULL, then we were unable to start
|
|
|
7a3408 |
* the guest on the target, and must restart on the
|
|
|
7a3408 |
@@ -5719,6 +5745,15 @@ qemuMigrationFinish(virQEMUDriverPtr driver,
|
|
|
7a3408 |
/* Guest is successfully running, so cancel previous auto destroy */
|
|
|
7a3408 |
qemuProcessAutoDestroyRemove(driver, vm);
|
|
|
7a3408 |
} else if (!(flags & VIR_MIGRATE_OFFLINE)) {
|
|
|
7a3408 |
+ qemuDomainJobInfo info;
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+ /* Check for a possible error on the monitor in case Finish was called
|
|
|
7a3408 |
+ * earlier than monitor EOF handler got a chance to process the error
|
|
|
7a3408 |
+ */
|
|
|
7a3408 |
+ qemuMigrationFetchJobStatus(driver, vm,
|
|
|
7a3408 |
+ QEMU_ASYNC_JOB_MIGRATION_IN,
|
|
|
7a3408 |
+ &info;;
|
|
|
7a3408 |
+
|
|
|
7a3408 |
qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED,
|
|
|
7a3408 |
VIR_QEMU_PROCESS_STOP_MIGRATED);
|
|
|
7a3408 |
virDomainAuditStop(vm, "failed");
|
|
|
7a3408 |
--
|
|
|
7a3408 |
2.4.5
|
|
|
7a3408 |
|