Even when failing to start CPUs, the finish method was returning
a success result. Fix this so that the QEMU process is killed
off when finish fails under v3 protocol. Also rename the
killOnFinish boolean to 'v3proto' to make it clearer that this
is a tunable based on the migration protocol version
* src/qemu/qemu_driver.c: Update for API change
* src/qemu/qemu_migration.c, src/qemu/qemu_migration.h: Kill
VM in qemuMigrationFinish if failing to start CPUs
---
src/qemu/qemu_driver.c | 8 ++++----
src/qemu/qemu_migration.c | 37 ++++++++++++++++++++++++++++++++-----
src/qemu/qemu_migration.h | 5 +++--
3 files changed, 39 insertions(+), 11 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 978a63a..43425e6 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -5971,7 +5971,7 @@ qemudDomainMigratePerform (virDomainPtr dom,
ret = qemuMigrationPerform(driver, dom->conn, vm,
NULL, dconnuri, uri, cookie, cookielen,
NULL, NULL, /* No output cookies in v2 */
- flags, dname, resource, true);
+ flags, dname, resource, false);
cleanup:
qemuDriverUnlock(driver);
@@ -6020,7 +6020,7 @@ qemudDomainMigrateFinish2 (virConnectPtr dconn,
*/
dom = qemuMigrationFinish(driver, dconn, vm,
NULL, 0, NULL, NULL, /* No cookies */
- flags, retcode);
+ flags, retcode, false);
cleanup:
if (orig_err) {
@@ -6222,7 +6222,7 @@ qemuDomainMigratePerform3(virDomainPtr dom,
ret = qemuMigrationPerform(driver, dom->conn, vm, xmlin,
dconnuri, uri, cookiein, cookieinlen,
cookieout, cookieoutlen,
- flags, dname, resource, false);
+ flags, dname, resource, true);
cleanup:
qemuDriverUnlock(driver);
@@ -6271,7 +6271,7 @@ qemuDomainMigrateFinish3(virConnectPtr dconn,
*newdom = qemuMigrationFinish(driver, dconn, vm,
cookiein, cookieinlen,
cookieout, cookieoutlen,
- flags, cancelled);
+ flags, cancelled, true);
ret = 0;
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index fa1a75b..4388214 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -2047,7 +2047,7 @@ int qemuMigrationPerform(struct qemud_driver *driver,
unsigned long flags,
const char *dname,
unsigned long resource,
- bool killOnFinish)
+ bool v3proto)
{
virDomainEventPtr event = NULL;
int ret = -1;
@@ -2092,8 +2092,13 @@ int qemuMigrationPerform(struct qemud_driver *driver,
goto endjob;
}
- /* Clean up the source domain. */
- if (killOnFinish) {
+ /*
+ * In v3 protocol, the source VM is not killed off until the
+ * confirm step.
+ */
+ if (v3proto) {
+ resume = 0;
+ } else {
qemuProcessStop(driver, vm, 1, VIR_DOMAIN_SHUTOFF_MIGRATED);
qemuAuditDomainStop(vm, "migrated");
resume = 0;
@@ -2193,7 +2198,8 @@ qemuMigrationFinish(struct qemud_driver *driver,
char **cookieout,
int *cookieoutlen,
unsigned long flags,
- int retcode)
+ int retcode,
+ bool v3proto)
{
virDomainPtr dom = NULL;
virDomainEventPtr event = NULL;
@@ -2257,7 +2263,6 @@ qemuMigrationFinish(struct qemud_driver *driver,
event = NULL;
}
- dom = virGetDomain (dconn, vm->def->name, vm->def->uuid);
if (!(flags & VIR_MIGRATE_PAUSED)) {
/* run 'cont' on the destination, which allows migration on qemu
@@ -2266,6 +2271,26 @@ qemuMigrationFinish(struct qemud_driver *driver,
*/
if (qemuProcessStartCPUs(driver, vm, dconn,
VIR_DOMAIN_RUNNING_MIGRATED) < 0) {
+ /*
+ * In v3 protocol, the source VM is still available to
+ * restart during confirm() step, so we kill it off
+ * now.
+ * In v2 protocol, the source is dead, so we leave
+ * target in paused state, in case admin can fix
+ * things up
+ */
+ if (v3proto) {
+ qemuProcessStop(driver, vm, 1, VIR_DOMAIN_SHUTOFF_FAILED);
+ qemuAuditDomainStop(vm, "failed");
+ event = virDomainEventNewFromObj(vm,
+ VIR_DOMAIN_EVENT_STOPPED,
+ VIR_DOMAIN_EVENT_STOPPED_FAILED);
+ if (!vm->persistent) {
+ if (qemuDomainObjEndJob(vm) > 0)
+ virDomainRemoveInactive(&driver->domains, vm);
+ vm = NULL;
+ }
+ }
if (virGetLastError() == NULL)
qemuReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("resume operation
failed"));
@@ -2273,6 +2298,8 @@ qemuMigrationFinish(struct qemud_driver *driver,
}
}
+ dom = virGetDomain (dconn, vm->def->name, vm->def->uuid);
+
event = virDomainEventNewFromObj(vm,
VIR_DOMAIN_EVENT_RESUMED,
VIR_DOMAIN_EVENT_RESUMED_MIGRATED);
diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h
index 08e3acc..d3a3743 100644
--- a/src/qemu/qemu_migration.h
+++ b/src/qemu/qemu_migration.h
@@ -72,7 +72,7 @@ int qemuMigrationPerform(struct qemud_driver *driver,
unsigned long flags,
const char *dname,
unsigned long resource,
- bool killOnFinish);
+ bool v3proto);
virDomainPtr qemuMigrationFinish(struct qemud_driver *driver,
virConnectPtr dconn,
@@ -82,7 +82,8 @@ virDomainPtr qemuMigrationFinish(struct qemud_driver *driver,
char **cookieout,
int *cookieoutlen,
unsigned long flags,
- int retcode);
+ int retcode,
+ bool v3proto);
int qemuMigrationConfirm(struct qemud_driver *driver,
virConnectPtr conn,
--
1.7.4.4