throw new InvalidParameterValueException("Unsupported Hypervisor Type for VM migration, we support " +
"XenServer/VMware/KVM/Ovm only");
}
long srcHostId = vm.getHostId();
Host srcHost = _hostDao.findById(srcHostId);
if (srcHost == null) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Unable to find the host with id: " + srcHostId + " of this VM:" + vm);
}
InvalidParameterValueException ex = new InvalidParameterValueException(
"Unable to find the host (with specified id) of VM with specified id");
ex.addProxyObject(String.valueOf(srcHostId), "hostId");
ex.addProxyObject(vm.getUuid(), "vmId");
throw ex;
}
// Check if the vm can be migrated with storage.
boolean canMigrateWithStorage = false;
if (vm.getType() == VirtualMachine.Type.User) {
HypervisorCapabilitiesVO capabilities = _hypervisorCapabilitiesDao.findByHypervisorTypeAndVersion(
srcHost.getHypervisorType(), srcHost.getHypervisorVersion());
if (capabilities != null) {
canMigrateWithStorage = capabilities.isStorageMotionSupported();
}
}
// Check if the vm is using any disks on local storage.
VirtualMachineProfile<VMInstanceVO> vmProfile = new VirtualMachineProfileImpl<VMInstanceVO>(vm);
List<VolumeVO> volumes = _volumeDao.findCreatedByInstance(vmProfile.getId());
boolean usesLocal = false;
for (VolumeVO volume : volumes) {
DiskOfferingVO diskOffering = _diskOfferingDao.findById(volume.getDiskOfferingId());
DiskProfile diskProfile = new DiskProfile(volume, diskOffering, vmProfile.getHypervisorType());
if (diskProfile.useLocalStorage()) {
usesLocal = true;
break;
}
}
if (!canMigrateWithStorage && usesLocal) {
throw new InvalidParameterValueException("Unsupported operation, VM uses Local storage, cannot migrate");
}
Type hostType = srcHost.getType();
Pair<List<HostVO>, Integer> allHostsPair = null;
List<HostVO> allHosts = null;
Map<Host, Boolean> requiresStorageMotion = new HashMap<Host, Boolean>();
DataCenterDeployment plan = null;
if (canMigrateWithStorage) {
allHostsPair = searchForServers(startIndex, pageSize, null, hostType, null, srcHost.getDataCenterId(), null,
null, null, null, null, null, srcHost.getHypervisorType(), srcHost.getHypervisorVersion());
allHosts = allHostsPair.first();
allHosts.remove(srcHost);
// Check if the host has storage pools for all the volumes of the vm to be migrated.
for (Iterator<HostVO> iterator = allHosts.iterator(); iterator.hasNext();) {
Host host = iterator.next();
Map<Volume, List<StoragePool>> volumePools = findSuitablePoolsForVolumes(vmProfile, host);
if (volumePools.isEmpty()) {
iterator.remove();
} else {
boolean migrationRequired = true;
if (srcHost.getHypervisorType() == HypervisorType.VMware || srcHost.getHypervisorType() == HypervisorType.KVM) {
// Check if each volume required migrating to other pool or not.
migrationRequired = checkIfMigrationRequired(volumePools);
}
if ((!host.getClusterId().equals(srcHost.getClusterId()) || usesLocal) && migrationRequired) {
requiresStorageMotion.put(host, true);
}
}
}