vm.setLastHostId(srcHostId);
try {
if (vm == null || vm.getHostId() == null || vm.getHostId() != srcHostId || !changeState(vm, Event.MigrationRequested, dstHostId, work, Step.Migrating)) {
s_logger.info("Migration cancelled because state has changed: " + vm);
throw new ConcurrentOperationException("Migration cancelled because state has changed: " + vm);
}
} catch (NoTransitionException e1) {
s_logger.info("Migration cancelled because " + e1.getMessage());
throw new ConcurrentOperationException("Migration cancelled because " + e1.getMessage());
}
boolean migrated = false;
try {
boolean isWindows = _guestOsCategoryDao.findById(_guestOsDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows");
MigrateCommand mc = new MigrateCommand(vm.getInstanceName(), dest.getHost().getPrivateIpAddress(), isWindows);
mc.setHostGuid(dest.getHost().getGuid());
try {
MigrateAnswer ma = (MigrateAnswer) _agentMgr.send(vm.getLastHostId(), mc);
if (!ma.getResult()) {
s_logger.error("Unable to migrate due to " + ma.getDetails());
return null;
}
} catch (OperationTimedoutException e) {
if (e.isActive()) {
s_logger.warn("Active migration command so scheduling a restart for " + vm);
_haMgr.scheduleRestart(vm, true);
}
throw new AgentUnavailableException("Operation timed out on migrating " + vm, dstHostId);
}
try {
long newServiceOfferingId = vm.getServiceOfferingId();
vm.setServiceOfferingId(oldSvcOfferingId); // release capacity for the old service offering only
if (!changeState(vm, VirtualMachine.Event.OperationSucceeded, dstHostId, work, Step.Started)) {
throw new ConcurrentOperationException("Unable to change the state for " + vm);
}
vm.setServiceOfferingId(newServiceOfferingId);
} catch (NoTransitionException e1) {
throw new ConcurrentOperationException("Unable to change state due to " + e1.getMessage());
}
try {
if (!checkVmOnHost(vm, dstHostId)) {
s_logger.error("Unable to complete migration for " + vm);