CLOUDSTACK-10305: Rare race condition in KVM migration (#2466)

There is a race condition in the monitoring of the migration process on KVM. If the monitor wakes up in the tight window after the migration succeeds, but before the migration thread terminates, the monitor will get a LibvirtException “Domain not found: no domain with matching uuid” when checking on the migration status. This in turn causes CloudStack to sync the VM state to stop, in which it issues a defensive StopCommand to ensure it is correctly synced.

Fix: Prevent LibvirtException: "Domain not found" caused by the call to dm.getInfo()
This commit is contained in:
Nicolas Vazquez 2018-02-26 11:31:51 -03:00 committed by Rohit Yadav
parent cae3292560
commit 703054964a

View File

@ -172,13 +172,21 @@ public final class LibvirtMigrateCommandWrapper extends CommandWrapper<MigrateCo
// pause vm if we meet the vm.migrate.pauseafter threshold and not already paused // pause vm if we meet the vm.migrate.pauseafter threshold and not already paused
final int migratePauseAfter = libvirtComputingResource.getMigratePauseAfter(); final int migratePauseAfter = libvirtComputingResource.getMigratePauseAfter();
if (migratePauseAfter > 0 && sleeptime > migratePauseAfter && dm.getInfo().state == DomainState.VIR_DOMAIN_RUNNING ) { if (migratePauseAfter > 0 && sleeptime > migratePauseAfter) {
s_logger.info("Pausing VM " + vmName + " due to property vm.migrate.pauseafter setting to " + migratePauseAfter+ "ms to complete migration"); DomainState state = null;
try { try {
dm.suspend(); state = dm.getInfo().state;
} catch (final LibvirtException e) { } catch (final LibvirtException e) {
// pause could be racy if it attempts to pause right when vm is finished, simply warn s_logger.info("Couldn't get VM domain state after " + sleeptime + "ms: " + e.getMessage());
s_logger.info("Failed to pause vm " + vmName + " : " + e.getMessage()); }
if (state != null && state == DomainState.VIR_DOMAIN_RUNNING) {
try {
s_logger.info("Pausing VM " + vmName + " due to property vm.migrate.pauseafter setting to " + migratePauseAfter + "ms to complete migration");
dm.suspend();
} catch (final LibvirtException e) {
// pause could be racy if it attempts to pause right when vm is finished, simply warn
s_logger.info("Failed to pause vm " + vmName + " : " + e.getMessage());
}
} }
} }
} }