private String getMigrationNetworkIp() { if (!FeatureSupported.migrationNetwork(getVm().getVdsGroupCompatibilityVersion())) { return null; } Network migrationNetwork = null; // Find migrationNetworkCluster List<Network> allNetworksInCluster = getNetworkDao().getAllForCluster(getVm().getVdsGroupId()); for (Network tempNetwork : allNetworksInCluster) { if (tempNetwork.getCluster().isMigration()) { migrationNetwork = tempNetwork; break; } } if (migrationNetwork != null) { // assure migration network is active on source host if (getMigrationNetworkAddress(getVds().getId(), migrationNetwork.getName()) == null) { return null; } // find migration IP address on destination host return getMigrationNetworkAddress(getDestinationVds().getId(), migrationNetwork.getName()); } return null; }
private boolean isTunnelMigrationUsed() { if (!FeatureSupported.tunnelMigration(getVm().getVdsGroupCompatibilityVersion())) { return false; } // if vm has no override for tunnel migration (its null), // use cluster's setting return getVm().getTunnelMigration() != null ? getVm().getTunnelMigration() : getVdsGroup().isTunnelMigration(); }
/** * Actually process the VM device update in DB. * * @param vm */ private void processVmDevices(Map vm) { if (vm == null || vm.get(VdsProperties.vm_guid) == null) { log.error("Received NULL VM or VM id when processing VM devices, abort."); return; } Guid vmId = new Guid((String) vm.get(VdsProperties.vm_guid)); Set<Guid> processedDevices = new HashSet<Guid>(); List<VmDevice> devices = getDbFacade().getVmDeviceDao().getVmDeviceByVmId(vmId); Map<VmDeviceId, VmDevice> deviceMap = Entities.businessEntitiesById(devices); for (Object o : (Object[]) vm.get(VdsProperties.Devices)) { Map device = (Map<String, Object>) o; if (device.get(VdsProperties.Address) == null) { logDeviceInformation(vmId, device); continue; } Guid deviceId = getDeviceId(device); VmDevice vmDevice = deviceMap.get(new VmDeviceId(deviceId, vmId)); String logicalName = null; if (deviceId != null && FeatureSupported.reportedDisksLogicalNames( getVdsManager().getGroupCompatibilityVersion()) && VmDeviceType.DISK.getName().equals(device.get(VdsProperties.Device))) { try { logicalName = getDeviceLogicalName((Map<?, ?>) vm.get(VdsProperties.GuestDiskMapping), deviceId); } catch (Exception e) { log.error( "error while getting device name when processing, vm '{}', device info '{}' with exception, skipping '{}'", vmId, device, e.getMessage()); log.error("Exception", e); } } if (deviceId == null || vmDevice == null) { deviceId = addNewVmDevice(vmId, device, logicalName); } else { vmDevice.setIsPlugged(Boolean.TRUE); vmDevice.setAddress(((Map<String, String>) device.get(VdsProperties.Address)).toString()); vmDevice.setAlias(StringUtils.defaultString((String) device.get(VdsProperties.Alias))); vmDevice.setLogicalName(logicalName); addVmDeviceToList(vmDevice); } processedDevices.add(deviceId); } handleRemovedDevices(vmId, processedDevices, devices); }
/** * Checking that the interfaces are all configured, interfaces with no network are allowed only if * network linking is supported. * * @return true if all VM network interfaces are attached to existing cluster networks, or to no * network (when network linking is supported). */ protected ValidationResult validateInterfacesConfigured(VM vm) { for (VmNetworkInterface nic : vm.getInterfaces()) { if (nic.getVnicProfileId() == null) { return FeatureSupported.networkLinking(vm.getVdsGroupCompatibilityVersion()) ? ValidationResult.VALID : new ValidationResult( VdcBllMessages.ACTION_TYPE_FAILED_INTERFACE_NETWORK_NOT_CONFIGURED); } } return ValidationResult.VALID; }
@Override protected boolean canDoAction() { if (getVm() == null) { return failCanDoAction(EngineMessage.ACTION_TYPE_FAILED_VM_NOT_FOUND); } if (getVm().getStatus() != VMStatus.Up) { return failVmStatusIllegal(); } if (!FeatureSupported.vmSlaPolicy(getVm().getVdsGroupCompatibilityVersion())) { return failCanDoAction(EngineMessage.VM_SLA_POLICY_NOT_SUPPORTED); } return true; }
private Boolean getMigrateCompressed() { if (FeatureSupported.migrationCompression(getVm().getVdsGroupCompatibilityVersion())) { if (getVm().getMigrateCompressed() != null) { return getVm().getMigrateCompressed(); } if (getVdsGroup().getMigrateCompressed() != null) { return getVdsGroup().getMigrateCompressed(); } return Config.getValue(ConfigValues.DefaultMigrationCompression); } return null; }
private Boolean getAutoConverge() { if (FeatureSupported.autoConvergence(getVm().getVdsGroupCompatibilityVersion())) { if (getVm().getAutoConverge() != null) { return getVm().getAutoConverge(); } if (getVdsGroup().getAutoConverge() != null) { return getVdsGroup().getAutoConverge(); } return Config.getValue(ConfigValues.DefaultAutoConvergence); } return null; }
protected void getDowntime() { if (FeatureSupported.migrateDowntime(getVm().getVdsGroupCompatibilityVersion())) { try { VDSReturnValue retVal = runVdsCommand( VDSCommandType.MigrateStatus, new MigrateStatusVDSCommandParameters(getDestinationVdsId(), getVmId())); if (retVal != null) { actualDowntime = (Integer) retVal.getReturnValue(); } } catch (EngineException e) { migrationErrorCode = e.getErrorCode(); } } }
/** * @param clusterNetworksNames cluster logical networks names * @param interfaceNetworkNames VM interface network names * @return true if all VM network interfaces are attached to existing cluster networks */ protected ValidationResult validateInterfacesAttachedToClusterNetworks( VM vm, final Set<String> clusterNetworkNames, final Set<String> interfaceNetworkNames) { Set<String> result = new HashSet<String>(interfaceNetworkNames); result.removeAll(clusterNetworkNames); if (FeatureSupported.networkLinking(vm.getVdsGroupCompatibilityVersion())) { result.remove(null); } // If after removing the cluster network names we still have objects, then we have interface on // networks that // aren't attached to the cluster return result.isEmpty() ? ValidationResult.VALID : new ValidationResult( VdcBllMessages.ACTION_TYPE_FAILED_NETWORK_NOT_IN_CLUSTER, String.format("$networks %1$s", StringUtils.join(result, ","))); }
protected boolean validate() { VM vm = parentCommand.getVm(); if (vm == null) { parentCommand.addCanDoActionMessage(EngineMessage.ACTION_TYPE_FAILED_VM_NOT_FOUND); return false; } else { targetCluster = DbFacade.getInstance().getVdsGroupDao().get(targetClusterId); if (targetCluster == null) { parentCommand.addCanDoActionMessage(EngineMessage.VM_CLUSTER_IS_NOT_VALID); return false; } // Check that the target cluster is in the same data center. if (!targetCluster.getStoragePoolId().equals(vm.getStoragePoolId())) { parentCommand.addCanDoActionMessage( EngineMessage.VM_CANNOT_MOVE_TO_CLUSTER_IN_OTHER_STORAGE_POOL); return false; } List<VmNic> interfaces = DbFacade.getInstance().getVmNicDao().getAllForVm(vm.getId()); Version clusterCompatibilityVersion = targetCluster.getCompatibilityVersion(); if (!validateDestinationClusterContainsNetworks(interfaces) || !validateNics(interfaces, clusterCompatibilityVersion)) { return false; } // Check if VM static parameters are compatible for new cluster. boolean isCpuSocketsValid = AddVmCommand.checkCpuSockets( vm.getStaticData().getNumOfSockets(), vm.getStaticData().getCpuPerSocket(), vm.getStaticData().getThreadsPerCpu(), clusterCompatibilityVersion.getValue(), parentCommand.getReturnValue().getCanDoActionMessages()); if (!isCpuSocketsValid) { return false; } // Check that the USB policy is legal if (!VmHandler.isUsbPolicyLegal( vm.getUsbPolicy(), vm.getOs(), targetCluster, parentCommand.getReturnValue().getCanDoActionMessages())) { return false; } // Check if the display type is supported if (!VmHandler.isGraphicsAndDisplaySupported( vm.getOs(), VmDeviceUtils.getGraphicsTypesOfEntity(vm.getId()), vm.getDefaultDisplayType(), parentCommand.getReturnValue().getCanDoActionMessages(), clusterCompatibilityVersion)) { return false; } if (VmDeviceUtils.hasVirtioScsiController(vm.getId())) { // Verify cluster compatibility if (!FeatureSupported.virtIoScsi(targetCluster.getCompatibilityVersion())) { return parentCommand.failCanDoAction( EngineMessage.VIRTIO_SCSI_INTERFACE_IS_NOT_AVAILABLE_FOR_CLUSTER_LEVEL); } // Verify OS compatibility if (!VmHandler.isOsTypeSupportedForVirtioScsi( vm.getOs(), targetCluster.getCompatibilityVersion(), parentCommand.getReturnValue().getCanDoActionMessages())) { return false; } } // A existing VM cannot be changed into a cluster without a defined architecture if (targetCluster.getArchitecture() == ArchitectureType.undefined) { return parentCommand.failCanDoAction( EngineMessage.ACTION_TYPE_FAILED_CLUSTER_UNDEFINED_ARCHITECTURE); } else if (targetCluster.getArchitecture() != vm.getClusterArch()) { return parentCommand.failCanDoAction( EngineMessage.ACTION_TYPE_FAILED_VM_CLUSTER_DIFFERENT_ARCHITECTURES); } } return true; }
private Map<String, Object> generateNetworks() { Map<String, Object> networks = new HashMap<String, Object>(); NetworkQoSDao qosDao = getDbFacade().getQosDao(); for (Network network : getParameters().getNetworks()) { Map<String, Object> opts = new HashMap<String, Object>(); VdsNetworkInterface iface = findNetworkInterface( network.getName(), getParameters().getInterfaces(), getParameters().getBonds()); String ifaceNameWithoutVlan = NetworkUtils.stripVlan(iface); Boolean bonded = findInterfaceByName(ifaceNameWithoutVlan).getBonded(); String type = (bonded != null && bonded) ? "bonding" : "nic"; opts.put(type, ifaceNameWithoutVlan); if (NetworkUtils.isVlan(network)) { opts.put("vlan", network.getVlanId().toString()); } if (iface.getBootProtocol() != null) { addBootProtocol(opts, iface); } if (network.getMtu() == 0) { opts.put("mtu", NetworkUtils.getDefaultMtu().toString()); } else { opts.put("mtu", String.valueOf(network.getMtu())); } opts.put("bridged", Boolean.toString(network.isVmNetwork())); if (network.isVmNetwork()) { opts.put(VdsProperties.STP, network.getStp() ? "yes" : "no"); } VDS host = getDbFacade().getVdsDao().get(getParameters().getVdsId()); Version version = host.getVdsGroupCompatibilityVersion(); if (qosConfiguredOnInterface(iface, network) && FeatureSupported.hostNetworkQos(version)) { NetworkQosMapper qosMapper = new NetworkQosMapper( opts, VdsProperties.HOST_QOS_INBOUND, VdsProperties.HOST_QOS_OUTBOUND); qosMapper.serialize( iface.isQosOverridden() ? iface.getQos() : qosDao.get(network.getQosId())); } Set<Version> supportedClusterVersionsSet = host.getSupportedClusterVersionsSet(); if (supportedClusterVersionsSet == null || supportedClusterVersionsSet.isEmpty()) { log.warnFormat( "Host {0} ({1}) doesn't contain Supported Cluster Versions, therefore 'defaultRoute'" + " will not be sent via the SetupNetworks", host.getName(), host.getId()); } else if (FeatureSupported.defaultRoute(Collections.max(supportedClusterVersionsSet)) && NetworkUtils.isManagementNetwork(network) && (iface.getBootProtocol() == NetworkBootProtocol.DHCP || (iface.getBootProtocol() == NetworkBootProtocol.STATIC_IP && StringUtils.isNotEmpty(iface.getGateway())))) { opts.put(DEFAULT_ROUTE, Boolean.TRUE); } if (iface.hasCustomProperties()) { opts.put(VdsProperties.NETWORK_CUSTOM_PROPERTIES, iface.getCustomProperties()); } networks.put(network.getName(), opts); } for (String net : getParameters().getRemovedNetworks()) { networks.put(net, REMOVE_OBJ); } return networks; }
protected void buildVmProperties() { createInfo.put(VdsProperties.vm_guid, vm.getId().toString()); createInfo.put(VdsProperties.vm_name, vm.getName()); createInfo.put(VdsProperties.mem_size_mb, vm.getVmMemSizeMb()); createInfo.put(VdsProperties.mem_guaranteed_size_mb, vm.getMinAllocatedMem()); createInfo.put(VdsProperties.smartcardEnabled, Boolean.toString(vm.isSmartcardEnabled())); createInfo.put(VdsProperties.num_of_cpus, String.valueOf(vm.getNumOfCpus())); if (Config.<Boolean>getValue(ConfigValues.SendSMPOnRunVm)) { createInfo.put(VdsProperties.cores_per_socket, (Integer.toString(vm.getCpuPerSocket()))); if (FeatureSupported.supportedInConfig( ConfigValues.HotPlugCpuSupported, vm.getVdsGroupCompatibilityVersion(), vm.getClusterArch())) { createInfo.put( VdsProperties.max_number_of_cpus, String.valueOf( Config.<Integer>getValue( ConfigValues.MaxNumOfVmCpus, vm.getVdsGroupCompatibilityVersion().getValue()))); } } final String compatibilityVersion = vm.getVdsGroupCompatibilityVersion().toString(); addCpuPinning(compatibilityVersion); createInfo.put(VdsProperties.emulatedMachine, getVdsGroup().getEmulatedMachine()); // send cipher suite and spice secure channels parameters only if ssl // enabled. if (Config.<Boolean>getValue(ConfigValues.SSLEnabled)) { createInfo.put( VdsProperties.spiceSslCipherSuite, Config.<String>getValue(ConfigValues.CipherSuite)); createInfo.put( VdsProperties.SpiceSecureChannels, Config.<String>getValue(ConfigValues.SpiceSecureChannels, compatibilityVersion)); } createInfo.put(VdsProperties.kvmEnable, vm.getKvmEnable().toString().toLowerCase()); createInfo.put(VdsProperties.acpiEnable, vm.getAcpiEnable().toString().toLowerCase()); createInfo.put( VdsProperties.Custom, VmPropertiesUtils.getInstance() .getVMProperties(vm.getVdsGroupCompatibilityVersion(), vm.getStaticData())); createInfo.put(VdsProperties.vm_type, "kvm"); // "qemu", "kvm" if (vm.isRunAndPause()) { createInfo.put(VdsProperties.launch_paused_param, "true"); } if (vm.isUseHostCpuFlags()) { createInfo.put(VdsProperties.cpuType, "hostPassthrough"); } else if (vm.getVdsGroupCpuFlagsData() != null) { createInfo.put(VdsProperties.cpuType, vm.getVdsGroupCpuFlagsData()); } createInfo.put(VdsProperties.niceLevel, String.valueOf(vm.getNiceLevel())); if (vm.getCpuShares() > 0) { createInfo.put(VdsProperties.cpuShares, String.valueOf(vm.getCpuShares())); } if (!StringUtils.isEmpty(vm.getHibernationVolHandle())) { createInfo.put(VdsProperties.hiberVolHandle, vm.getHibernationVolHandle()); } String keyboardLayout = vm.getDynamicData().getVncKeyboardLayout(); if (keyboardLayout == null) { keyboardLayout = vm.getDefaultVncKeyboardLayout(); if (keyboardLayout == null) { keyboardLayout = Config.<String>getValue(ConfigValues.VncKeyboardLayout); } } createInfo.put(VdsProperties.KeyboardLayout, keyboardLayout); if (osRepository.isLinux(vm.getVmOsId())) { createInfo.put(VdsProperties.PitReinjection, "false"); } if (vm.getDisplayType() == DisplayType.vnc) { createInfo.put(VdsProperties.TabletEnable, "true"); } createInfo.put( VdsProperties.transparent_huge_pages, vm.isTransparentHugePages() ? "true" : "false"); }
@Override protected boolean canDoAction() { final VM vm = getVm(); if (vm == null) { return failCanDoAction(EngineMessage.ACTION_TYPE_FAILED_VM_NOT_FOUND); } if (!canRunActionOnNonManagedVm()) { return false; } VmValidator vmValidator = new VmValidator(vm); if (!validate(vmValidator.isVmPluggedDiskNotUsingScsiReservation())) { return false; } if (!FeatureSupported.isMigrationSupported( getVdsGroup().getArchitecture(), getVdsGroup().getCompatibilityVersion())) { return failCanDoAction(EngineMessage.MIGRATION_IS_NOT_SUPPORTED); } // If VM is pinned to host, no migration can occur if (vm.getMigrationSupport() == MigrationSupport.PINNED_TO_HOST) { return failCanDoAction(EngineMessage.ACTION_TYPE_FAILED_VM_IS_PINNED_TO_HOST); } if (vm.getMigrationSupport() == MigrationSupport.IMPLICITLY_NON_MIGRATABLE && !getParameters().isForceMigrationForNonMigratableVm()) { return failCanDoAction( EngineMessage .ACTION_TYPE_FAILED_VM_IS_NON_MIGRTABLE_AND_IS_NOT_FORCED_BY_USER_TO_MIGRATE); } switch (vm.getStatus()) { case MigratingFrom: return failCanDoAction(EngineMessage.ACTION_TYPE_FAILED_MIGRATION_IN_PROGRESS); case NotResponding: return failVmStatusIllegal(); case Paused: if (vm.getVmPauseStatus() == VmPauseStatus.EIO) { return failCanDoAction(EngineMessage.MIGRATE_PAUSED_EIO_VM_IS_NOT_SUPPORTED); } break; default: } if (!vm.isQualifyToMigrate()) { return failCanDoAction(EngineMessage.ACTION_TYPE_FAILED_VM_IS_NOT_RUNNING); } if (!validate( vmValidator.vmNotHavingPluggedDiskSnapshots( EngineMessage.ACTION_TYPE_FAILED_VM_HAS_PLUGGED_DISK_SNAPSHOT)) || !validate(vmValidator.vmNotHavingPassthroughVnics())) { return false; } if (getParameters().getTargetVdsGroupId() != null) { ChangeVmClusterValidator changeVmClusterValidator = new ChangeVmClusterValidator(this, getParameters().getTargetVdsGroupId()); if (!changeVmClusterValidator.validate()) { return false; } } return validate(new SnapshotsValidator().vmNotDuringSnapshot(vm.getId())) // This check was added to prevent migration of VM while its disks are being migrated // TODO: replace it with a better solution && validate( new DiskImagesValidator(ImagesHandler.getPluggedActiveImagesForVm(vm.getId())) .diskImagesNotLocked()) && schedulingManager.canSchedule( getVdsGroup(), getVm(), getVdsBlackList(), getParameters().getInitialHosts(), getDestinationHostList(), getReturnValue().getCanDoActionMessages()); }
@Override protected boolean canDoAction() { final VM vm = getVm(); if (vm == null) { return failCanDoAction(VdcBllMessages.ACTION_TYPE_FAILED_VM_NOT_FOUND); } if (!canRunActionOnNonManagedVm()) { return false; } if (!FeatureSupported.isMigrationSupported( getVdsGroup().getArchitecture(), getVdsGroup().getcompatibility_version())) { return failCanDoAction(VdcBllMessages.MIGRATION_IS_NOT_SUPPORTED); } // If VM is pinned to host, no migration can occur if (vm.getMigrationSupport() == MigrationSupport.PINNED_TO_HOST) { return failCanDoAction(VdcBllMessages.ACTION_TYPE_FAILED_VM_IS_PINNED_TO_HOST); } if (vm.getMigrationSupport() == MigrationSupport.IMPLICITLY_NON_MIGRATABLE && !getParameters().isForceMigrationForNonMigratableVm()) { return failCanDoAction( VdcBllMessages .ACTION_TYPE_FAILED_VM_IS_NON_MIGRTABLE_AND_IS_NOT_FORCED_BY_USER_TO_MIGRATE); } switch (vm.getStatus()) { case MigratingFrom: return failCanDoAction(VdcBllMessages.ACTION_TYPE_FAILED_MIGRATION_IN_PROGRESS); case NotResponding: return failCanDoAction( VdcBllMessages.ACTION_TYPE_FAILED_VM_STATUS_ILLEGAL, LocalizedVmStatus.from(VMStatus.NotResponding)); case Paused: if (vm.getVmPauseStatus() == VmPauseStatus.EIO) { return failCanDoAction(VdcBllMessages.MIGRATE_PAUSED_EIO_VM_IS_NOT_SUPPORTED); } break; default: } if (!vm.isQualifyToMigrate()) { return failCanDoAction(VdcBllMessages.ACTION_TYPE_FAILED_VM_IS_NOT_RUNNING); } VmValidator vmValidator = new VmValidator(vm); if (!validate( vmValidator.vmNotHavingPluggedDiskSnapshots( VdcBllMessages.ACTION_TYPE_FAILED_VM_HAS_PLUGGED_DISK_SNAPSHOT))) { return false; } if (getDestinationVds() != null && getDestinationVds().getStatus() != VDSStatus.Up) { addCanDoActionMessage(VdcBllMessages.VAR__HOST_STATUS__UP); return failCanDoAction(VdcBllMessages.ACTION_TYPE_FAILED_VDS_STATUS_ILLEGAL); } return validate(new SnapshotsValidator().vmNotDuringSnapshot(vm.getId())) // This check was added to prevent migration of VM while its disks are being migrated // TODO: replace it with a better solution && validate( new DiskImagesValidator(ImagesHandler.getPluggedActiveImagesForVm(vm.getId())) .diskImagesNotLocked()) && SchedulingManager.getInstance() .canSchedule( getVdsGroup(), getVm(), getVdsBlackList(), getParameters().getInitialHosts(), getDestinationVdsId(), getReturnValue().getCanDoActionMessages()); }
@Override protected boolean canDoAction() { if (getVdsGroup() == null) { return failCanDoAction(EngineMessage.VDS_CLUSTER_IS_NOT_VALID); } // A Pool cannot be added in a cluster without a defined architecture if (getVdsGroup().getArchitecture() == ArchitectureType.undefined) { return failCanDoAction(EngineMessage.ACTION_TYPE_FAILED_CLUSTER_UNDEFINED_ARCHITECTURE); } VmPool pool = getVmPoolDao().getByName(getParameters().getVmPool().getName()); if (pool != null && (getActionType() == VdcActionType.AddVmPoolWithVms || !pool.getVmPoolId().equals(getParameters().getVmPoolId()))) { return failCanDoAction(EngineMessage.ACTION_TYPE_FAILED_NAME_ALREADY_USED); } setStoragePoolId(getVdsGroup().getStoragePoolId()); if (!validate(new StoragePoolValidator(getStoragePool()).isUp())) { return false; } // check if the selected template is compatible with Cluster architecture. if (!getVmTemplate().getId().equals(VmTemplateHandler.BLANK_VM_TEMPLATE_ID) && getVdsGroup().getArchitecture() != getVmTemplate().getClusterArch()) { return failCanDoAction(EngineMessage.ACTION_TYPE_FAILED_TEMPLATE_IS_INCOMPATIBLE); } if (!verifyAddVM()) { return false; } if (getVmTemplate().getDiskTemplateMap().values().size() != diskInfoDestinationMap.size()) { log.error( "Can not found any default active domain for one of the disks of template with id '{}'", getVmTemplate().getId()); addCanDoActionMessage(EngineMessage.ACTION_TYPE_FAILED_MISSED_STORAGES_FOR_SOME_DISKS); return false; } List<Guid> storageIds = new ArrayList<>(); for (DiskImage diskImage : diskInfoDestinationMap.values()) { Guid storageId = diskImage.getStorageIds().get(0); if (!storageIds.contains(storageId) && !areTemplateImagesInStorageReady(storageId)) { return false; } storageIds.add(storageId); } if (getActionType() == VdcActionType.AddVmPoolWithVms && getParameters().getVmsCount() < 1) { return failCanDoAction(EngineMessage.VM_POOL_CANNOT_CREATE_WITH_NO_VMS); } if (getParameters().getVmStaticData().isStateless()) { return failCanDoAction(EngineMessage.ACTION_TYPE_FAILED_VM_FROM_POOL_CANNOT_BE_STATELESS); } if (getParameters().getVmPool().getPrestartedVms() > getParameters().getVmPool().getAssignedVmsCount() + getParameters().getVmsCount()) { return failCanDoAction( EngineMessage.ACTION_TYPE_FAILED_PRESTARTED_VMS_CANNOT_EXCEED_VMS_COUNT); } if (Boolean.TRUE.equals(getParameters().isVirtioScsiEnabled()) && !FeatureSupported.virtIoScsi(getVdsGroup().getCompatibilityVersion())) { return failCanDoAction( EngineMessage.VIRTIO_SCSI_INTERFACE_IS_NOT_AVAILABLE_FOR_CLUSTER_LEVEL); } if (!setAndValidateDiskProfiles()) { return false; } if (!setAndValidateCpuProfile()) { return false; } return checkDestDomains(); }