mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
Fix peer2peer migration with transient VMs
The qemuMigrationConfirm method shouldn't deal with final VM cleanup, since it can be called from the peer2peer migration, which expects to still use the 'vm' object afterwards. Push the cleanup code out of qemuMigrationConfirm, into its caller, qemuDomainMigrateConfirm3 * src/qemu/qemu_driver.c: Add VM cleanup code to qemuDomainMigrateConfirm3 * src/qemu/qemu_migration.c, src/qemu/qemu_migration.h: Remove job handling cleanup from qemuMigrationConfirm
This commit is contained in:
parent
f88af9dc16
commit
65e1acad80
@ -6284,6 +6284,7 @@ qemuDomainMigrateConfirm3(virDomainPtr domain,
|
|||||||
struct qemud_driver *driver = domain->conn->privateData;
|
struct qemud_driver *driver = domain->conn->privateData;
|
||||||
virDomainObjPtr vm;
|
virDomainObjPtr vm;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
virErrorPtr orig_err;
|
||||||
|
|
||||||
virCheckFlags(VIR_MIGRATE_LIVE |
|
virCheckFlags(VIR_MIGRATE_LIVE |
|
||||||
VIR_MIGRATE_PEER2PEER |
|
VIR_MIGRATE_PEER2PEER |
|
||||||
@ -6304,11 +6305,33 @@ qemuDomainMigrateConfirm3(virDomainPtr domain,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (qemuDomainObjBeginJobWithDriver(driver, vm) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
ret = qemuMigrationConfirm(driver, domain->conn, vm,
|
ret = qemuMigrationConfirm(driver, domain->conn, vm,
|
||||||
cookiein, cookieinlen,
|
cookiein, cookieinlen,
|
||||||
flags, cancelled, false);
|
flags, cancelled);
|
||||||
|
|
||||||
|
orig_err = virSaveLastError();
|
||||||
|
|
||||||
|
if (qemuDomainObjEndJob(vm) == 0) {
|
||||||
|
vm = NULL;
|
||||||
|
} else if (!virDomainObjIsActive(vm) &&
|
||||||
|
(!vm->persistent || (flags & VIR_MIGRATE_UNDEFINE_SOURCE))) {
|
||||||
|
if (flags & VIR_MIGRATE_UNDEFINE_SOURCE)
|
||||||
|
virDomainDeleteConfig(driver->configDir, driver->autostartDir, vm);
|
||||||
|
virDomainRemoveInactive(&driver->domains, vm);
|
||||||
|
vm = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (orig_err) {
|
||||||
|
virSetError(orig_err);
|
||||||
|
virFreeError(orig_err);
|
||||||
|
}
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
if (vm)
|
||||||
|
virDomainObjUnlock(vm);
|
||||||
qemuDriverUnlock(driver);
|
qemuDriverUnlock(driver);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1911,7 +1911,7 @@ finish:
|
|||||||
cookieoutlen = 0;
|
cookieoutlen = 0;
|
||||||
ret = qemuMigrationConfirm(driver, sconn, vm,
|
ret = qemuMigrationConfirm(driver, sconn, vm,
|
||||||
cookiein, cookieinlen,
|
cookiein, cookieinlen,
|
||||||
flags, cancelled, true);
|
flags, cancelled);
|
||||||
/* If Confirm3 returns -1, there's nothing more we can
|
/* If Confirm3 returns -1, there's nothing more we can
|
||||||
* do, but fortunately worst case is that there is a
|
* do, but fortunately worst case is that there is a
|
||||||
* domain left in 'paused' state on source.
|
* domain left in 'paused' state on source.
|
||||||
@ -2067,12 +2067,6 @@ int qemuMigrationPerform(struct qemud_driver *driver,
|
|||||||
event = virDomainEventNewFromObj(vm,
|
event = virDomainEventNewFromObj(vm,
|
||||||
VIR_DOMAIN_EVENT_STOPPED,
|
VIR_DOMAIN_EVENT_STOPPED,
|
||||||
VIR_DOMAIN_EVENT_STOPPED_MIGRATED);
|
VIR_DOMAIN_EVENT_STOPPED_MIGRATED);
|
||||||
if (!vm->persistent || (flags & VIR_MIGRATE_UNDEFINE_SOURCE)) {
|
|
||||||
virDomainDeleteConfig(driver->configDir, driver->autostartDir, vm);
|
|
||||||
if (qemuDomainObjEndJob(vm) > 0)
|
|
||||||
virDomainRemoveInactive(&driver->domains, vm);
|
|
||||||
vm = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
@ -2094,9 +2088,17 @@ endjob:
|
|||||||
VIR_DOMAIN_EVENT_RESUMED,
|
VIR_DOMAIN_EVENT_RESUMED,
|
||||||
VIR_DOMAIN_EVENT_RESUMED_MIGRATED);
|
VIR_DOMAIN_EVENT_RESUMED_MIGRATED);
|
||||||
}
|
}
|
||||||
if (vm &&
|
if (vm) {
|
||||||
qemuDomainObjEndJob(vm) == 0)
|
if (qemuDomainObjEndJob(vm) == 0) {
|
||||||
vm = NULL;
|
vm = NULL;
|
||||||
|
} else if (!virDomainObjIsActive(vm) &&
|
||||||
|
(!vm->persistent || (flags & VIR_MIGRATE_UNDEFINE_SOURCE))) {
|
||||||
|
if (flags & VIR_MIGRATE_UNDEFINE_SOURCE)
|
||||||
|
virDomainDeleteConfig(driver->configDir, driver->autostartDir, vm);
|
||||||
|
virDomainRemoveInactive(&driver->domains, vm);
|
||||||
|
vm = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if (vm)
|
if (vm)
|
||||||
@ -2287,9 +2289,8 @@ int qemuMigrationConfirm(struct qemud_driver *driver,
|
|||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
const char *cookiein,
|
const char *cookiein,
|
||||||
int cookieinlen,
|
int cookieinlen,
|
||||||
unsigned int flags,
|
unsigned int flags ATTRIBUTE_UNUSED,
|
||||||
int retcode,
|
int retcode)
|
||||||
bool skipJob)
|
|
||||||
{
|
{
|
||||||
qemuMigrationCookiePtr mig;
|
qemuMigrationCookiePtr mig;
|
||||||
virDomainEventPtr event = NULL;
|
virDomainEventPtr event = NULL;
|
||||||
@ -2298,14 +2299,10 @@ int qemuMigrationConfirm(struct qemud_driver *driver,
|
|||||||
if (!(mig = qemuMigrationEatCookie(vm, cookiein, cookieinlen, 0)))
|
if (!(mig = qemuMigrationEatCookie(vm, cookiein, cookieinlen, 0)))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (!skipJob &&
|
|
||||||
qemuDomainObjBeginJobWithDriver(driver, vm) < 0)
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
if (!virDomainObjIsActive(vm)) {
|
if (!virDomainObjIsActive(vm)) {
|
||||||
qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
_("guest unexpectedly quit"));
|
_("guest unexpectedly quit"));
|
||||||
goto endjob;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Did the migration go as planned? If yes, kill off the
|
/* Did the migration go as planned? If yes, kill off the
|
||||||
@ -2318,12 +2315,6 @@ int qemuMigrationConfirm(struct qemud_driver *driver,
|
|||||||
event = virDomainEventNewFromObj(vm,
|
event = virDomainEventNewFromObj(vm,
|
||||||
VIR_DOMAIN_EVENT_STOPPED,
|
VIR_DOMAIN_EVENT_STOPPED,
|
||||||
VIR_DOMAIN_EVENT_STOPPED_MIGRATED);
|
VIR_DOMAIN_EVENT_STOPPED_MIGRATED);
|
||||||
if (!vm->persistent || (flags & VIR_MIGRATE_UNDEFINE_SOURCE)) {
|
|
||||||
virDomainDeleteConfig(driver->configDir, driver->autostartDir, vm);
|
|
||||||
if (qemuDomainObjEndJob(vm) > 0)
|
|
||||||
virDomainRemoveInactive(&driver->domains, vm);
|
|
||||||
vm = NULL;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* run 'cont' on the destination, which allows migration on qemu
|
/* run 'cont' on the destination, which allows migration on qemu
|
||||||
@ -2335,7 +2326,7 @@ int qemuMigrationConfirm(struct qemud_driver *driver,
|
|||||||
if (virGetLastError() == NULL)
|
if (virGetLastError() == NULL)
|
||||||
qemuReportError(VIR_ERR_INTERNAL_ERROR,
|
qemuReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
"%s", _("resume operation failed"));
|
"%s", _("resume operation failed"));
|
||||||
goto endjob;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
event = virDomainEventNewFromObj(vm,
|
event = virDomainEventNewFromObj(vm,
|
||||||
@ -2343,22 +2334,14 @@ int qemuMigrationConfirm(struct qemud_driver *driver,
|
|||||||
VIR_DOMAIN_EVENT_RESUMED_MIGRATED);
|
VIR_DOMAIN_EVENT_RESUMED_MIGRATED);
|
||||||
if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0) {
|
if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0) {
|
||||||
VIR_WARN("Failed to save status on vm %s", vm->def->name);
|
VIR_WARN("Failed to save status on vm %s", vm->def->name);
|
||||||
goto endjob;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
qemuMigrationCookieFree(mig);
|
qemuMigrationCookieFree(mig);
|
||||||
rv = 0;
|
rv = 0;
|
||||||
|
|
||||||
endjob:
|
|
||||||
if (vm &&
|
|
||||||
!skipJob &&
|
|
||||||
qemuDomainObjEndJob(vm) == 0)
|
|
||||||
vm = NULL;
|
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if (vm)
|
|
||||||
virDomainObjUnlock(vm);
|
|
||||||
if (event)
|
if (event)
|
||||||
qemuDomainEventQueue(driver, event);
|
qemuDomainEventQueue(driver, event);
|
||||||
return rv;
|
return rv;
|
||||||
|
@ -87,8 +87,7 @@ int qemuMigrationConfirm(struct qemud_driver *driver,
|
|||||||
const char *cookiein,
|
const char *cookiein,
|
||||||
int cookieinlen,
|
int cookieinlen,
|
||||||
unsigned int flags,
|
unsigned int flags,
|
||||||
int retcode,
|
int retcode);
|
||||||
bool skipJob);
|
|
||||||
|
|
||||||
|
|
||||||
int qemuMigrationToFile(struct qemud_driver *driver, virDomainObjPtr vm,
|
int qemuMigrationToFile(struct qemud_driver *driver, virDomainObjPtr vm,
|
||||||
|
Loading…
Reference in New Issue
Block a user