3737import javax .naming .ConfigurationException ;
3838
3939import com .cloud .gpu .dao .VgpuProfileDao ;
40+ import com .cloud .resource .ResourceState ;
4041import org .apache .cloudstack .affinity .AffinityGroupDomainMapVO ;
4142import org .apache .cloudstack .affinity .AffinityGroupProcessor ;
4243import org .apache .cloudstack .affinity .AffinityGroupService ;
@@ -383,22 +384,12 @@ public DeployDestination planDeployment(VirtualMachineProfile vmProfile, Deploym
383384 planner = getDeploymentPlannerByName (plannerName );
384385 }
385386
386- Host lastHost = null ;
387-
388- String considerLastHostStr = (String )vmProfile .getParameter (VirtualMachineProfile .Param .ConsiderLastHost );
389- boolean considerLastHost = vm .getLastHostId () != null && haVmTag == null &&
390- (considerLastHostStr == null || Boolean .TRUE .toString ().equalsIgnoreCase (considerLastHostStr ));
391- if (considerLastHost ) {
392- HostVO host = _hostDao .findById (vm .getLastHostId ());
393- logger .debug ("This VM has last host_id specified, trying to choose the same host: " + host );
394- lastHost = host ;
395-
396- DeployDestination deployDestination = deployInVmLastHost (vmProfile , plan , avoids , planner , vm , dc , offering , cpuRequested , ramRequested , volumesRequireEncryption );
397- if (deployDestination != null ) {
398- return deployDestination ;
399- }
387+ DeployDestination deployDestinationForVmLasthost = deployInVmLastHost (vmProfile , plan , avoids , planner , vm , dc , offering , cpuRequested , ramRequested , volumesRequireEncryption );
388+ if (deployDestinationForVmLasthost != null ) {
389+ return deployDestinationForVmLasthost ;
400390 }
401391
392+ HostVO lastHost = _hostDao .findById (vm .getLastHostId ());
402393 avoidOtherClustersForDeploymentIfMigrationDisabled (vm , lastHost , avoids );
403394
404395 DeployDestination dest = null ;
@@ -480,56 +471,65 @@ private void avoidDifferentArchResources(VirtualMachineProfile vmProfile, DataCe
480471 private DeployDestination deployInVmLastHost (VirtualMachineProfile vmProfile , DeploymentPlan plan , ExcludeList avoids ,
481472 DeploymentPlanner planner , VirtualMachine vm , DataCenter dc , ServiceOffering offering , int cpuRequested , long ramRequested ,
482473 boolean volumesRequireEncryption ) throws InsufficientServerCapacityException {
483- HostVO host = _hostDao .findById (vm .getLastHostId ());
484- if (canUseLastHost (host , avoids , plan , vm , offering , volumesRequireEncryption )) {
485- _hostDao .loadHostTags (host );
486- _hostDao .loadDetails (host );
487- if (host .getStatus () != Status .Up ) {
474+ String considerLastHostStr = (String )vmProfile .getParameter (VirtualMachineProfile .Param .ConsiderLastHost );
475+ String haVmTag = (String )vmProfile .getParameter (VirtualMachineProfile .Param .HaTag );
476+ boolean considerLastHost = vm .getLastHostId () != null && haVmTag == null &&
477+ !(Boolean .FALSE .toString ().equalsIgnoreCase (considerLastHostStr ));
478+ if (!considerLastHost ) {
479+ return null ;
480+ }
481+
482+ logger .debug ("This VM has last host_id: {}" , vm .getLastHostId ());
483+ HostVO lastHost = _hostDao .findById (vm .getLastHostId ());
484+ if (canUseLastHost (lastHost , avoids , plan , vm , offering , volumesRequireEncryption )) {
485+ _hostDao .loadHostTags (lastHost );
486+ _hostDao .loadDetails (lastHost );
487+ if (lastHost .getStatus () != Status .Up ) {
488488 logger .debug ("Cannot deploy VM [{}] to the last host [{}] because this host is not in UP state or is not enabled. Host current status [{}] and resource status [{}]." ,
489- vm , host , host .getState ().name (), host .getResourceState ());
489+ vm , lastHost , lastHost .getState ().name (), lastHost .getResourceState ());
490490 return null ;
491491 }
492- if (checkVmProfileAndHost (vmProfile , host )) {
493- long cluster_id = host .getClusterId ();
492+ if (checkVmProfileAndHost (vmProfile , lastHost )) {
493+ long cluster_id = lastHost .getClusterId ();
494494 ClusterDetailsVO cluster_detail_cpu = _clusterDetailsDao .findDetail (cluster_id , "cpuOvercommitRatio" );
495495 ClusterDetailsVO cluster_detail_ram = _clusterDetailsDao .findDetail (cluster_id , "memoryOvercommitRatio" );
496496 float cpuOvercommitRatio = Float .parseFloat (cluster_detail_cpu .getValue ());
497497 float memoryOvercommitRatio = Float .parseFloat (cluster_detail_ram .getValue ());
498498
499499 boolean hostHasCpuCapability , hostHasCapacity = false ;
500- hostHasCpuCapability = _capacityMgr .checkIfHostHasCpuCapability (host , offering .getCpu (), offering .getSpeed ());
500+ hostHasCpuCapability = _capacityMgr .checkIfHostHasCpuCapability (lastHost , offering .getCpu (), offering .getSpeed ());
501501
502502 if (hostHasCpuCapability ) {
503503 // first check from reserved capacity
504- hostHasCapacity = _capacityMgr .checkIfHostHasCapacity (host , cpuRequested , ramRequested , true , cpuOvercommitRatio , memoryOvercommitRatio , true );
504+ hostHasCapacity = _capacityMgr .checkIfHostHasCapacity (lastHost , cpuRequested , ramRequested , true , cpuOvercommitRatio , memoryOvercommitRatio , true );
505505
506506 // if not reserved, check the free capacity
507507 if (!hostHasCapacity )
508- hostHasCapacity = _capacityMgr .checkIfHostHasCapacity (host , cpuRequested , ramRequested , false , cpuOvercommitRatio , memoryOvercommitRatio , true );
508+ hostHasCapacity = _capacityMgr .checkIfHostHasCapacity (lastHost , cpuRequested , ramRequested , false , cpuOvercommitRatio , memoryOvercommitRatio , true );
509509 }
510510
511511 boolean displayStorage = getDisplayStorageFromVmProfile (vmProfile );
512512 if (!hostHasCapacity || !hostHasCpuCapability ) {
513- logger .debug ("Cannot deploy VM [{}] to the last host [{}] because this host does not have enough capacity to deploy this VM." , vm , host );
513+ logger .debug ("Cannot deploy VM [{}] to the last host [{}] because this host does not have enough capacity to deploy this VM." , vm , lastHost );
514514 return null ;
515515 }
516- Pod pod = _podDao .findById (host .getPodId ());
517- Cluster cluster = _clusterDao .findById (host .getClusterId ());
516+ Pod pod = _podDao .findById (lastHost .getPodId ());
517+ Cluster cluster = _clusterDao .findById (lastHost .getClusterId ());
518518
519519 logger .debug ("Last host [{}] of VM [{}] is UP and has enough capacity. Checking for suitable pools for this host under zone [{}], pod [{}] and cluster [{}]." ,
520- host , vm , dc , pod , cluster );
520+ lastHost , vm , dc , pod , cluster );
521521
522- if (DEPLOYMENT_PLANNING_SKIP_HYPERVISORS . contains ( vm .getHypervisorType ()) ) {
523- DeployDestination dest = new DeployDestination (dc , pod , cluster , host , new HashMap <>(), displayStorage );
522+ if (vm .getHypervisorType () == HypervisorType . BareMetal ) {
523+ DeployDestination dest = new DeployDestination (dc , pod , cluster , lastHost , new HashMap <>(), displayStorage );
524524 logger .debug ("Returning Deployment Destination: {}." , dest );
525525 return dest ;
526526 }
527527
528528 // search for storage under the zone, pod, cluster
529529 // of
530530 // the last host.
531- DataCenterDeployment lastPlan = new DataCenterDeployment (host .getDataCenterId (),
532- host .getPodId (), host .getClusterId (), host .getId (), plan .getPoolId (), null );
531+ DataCenterDeployment lastPlan = new DataCenterDeployment (lastHost .getDataCenterId (),
532+ lastHost .getPodId (), lastHost .getClusterId (), lastHost .getId (), plan .getPoolId (), null );
533533 Pair <Map <Volume , List <StoragePool >>, List <Volume >> result = findSuitablePoolsForVolumes (
534534 vmProfile , lastPlan , avoids , HostAllocator .RETURN_UPTO_ALL );
535535 Map <Volume , List <StoragePool >> suitableVolumeStoragePools = result .first ();
@@ -538,11 +538,11 @@ private DeployDestination deployInVmLastHost(VirtualMachineProfile vmProfile, De
538538 // choose the potential pool for this VM for this
539539 // host
540540 if (suitableVolumeStoragePools .isEmpty ()) {
541- logger .debug ("Cannot find suitable storage pools in host [{}] to deploy VM [{}]" , host , vm );
541+ logger .debug ("Cannot find suitable storage pools in host [{}] to deploy VM [{}]" , lastHost , vm );
542542 return null ;
543543 }
544544 List <Host > suitableHosts = new ArrayList <>();
545- suitableHosts .add (host );
545+ suitableHosts .add (lastHost );
546546 Pair <Host , Map <Volume , StoragePool >> potentialResources = findPotentialDeploymentResources (
547547 suitableHosts , suitableVolumeStoragePools , avoids ,
548548 getPlannerUsage (planner , vmProfile , plan , avoids ), readyAndReusedVolumes , plan .getPreferredHosts (), vm );
@@ -555,7 +555,7 @@ private DeployDestination deployInVmLastHost(VirtualMachineProfile vmProfile, De
555555 for (Volume vol : readyAndReusedVolumes ) {
556556 storageVolMap .remove (vol );
557557 }
558- DeployDestination dest = new DeployDestination (dc , pod , cluster , host , storageVolMap , displayStorage );
558+ DeployDestination dest = new DeployDestination (dc , pod , cluster , lastHost , storageVolMap , displayStorage );
559559 logger .debug ("Returning Deployment Destination: {}" , dest );
560560 return dest ;
561561 }
@@ -567,7 +567,7 @@ private DeployDestination deployInVmLastHost(VirtualMachineProfile vmProfile, De
567567
568568 private boolean canUseLastHost (HostVO host , ExcludeList avoids , DeploymentPlan plan , VirtualMachine vm , ServiceOffering offering , boolean volumesRequireEncryption ) {
569569 if (host == null ) {
570- logger .warn ("Could not find last host of VM [{}] with id [{}]. Skipping this and trying other available hosts. " , vm , vm .getLastHostId ());
570+ logger .warn ("Could not find last host of VM [{}] with id [{}]. Skipping it " , vm , vm .getLastHostId ());
571571 return false ;
572572 }
573573
@@ -581,6 +581,12 @@ private boolean canUseLastHost(HostVO host, ExcludeList avoids, DeploymentPlan p
581581 return false ;
582582 }
583583
584+ logger .debug ("VM's last host is {}, trying to choose the same host if it is not in maintenance, error or degraded state" , host );
585+ if (host .isInMaintenanceStates () || Arrays .asList (ResourceState .Error , ResourceState .Degraded ).contains (host .getResourceState ())) {
586+ logger .debug ("Unable to deploy VM {} in the last host, last host {} is in {} state" , vm .getName (), host .getName (), host .getResourceState ());
587+ return false ;
588+ }
589+
584590 if (_capacityMgr .checkIfHostReachMaxGuestLimit (host )) {
585591 logger .debug ("Cannot deploy VM [{}] in the last host [{}] because this host already has the max number of running VMs (users and system VMs). Skipping this and trying other available hosts." ,
586592 vm , host );
@@ -1477,7 +1483,7 @@ private Pair<Boolean, Boolean> findVMStorageRequirements(VirtualMachineProfile v
14771483
14781484 protected Pair <Host , Map <Volume , StoragePool >> findPotentialDeploymentResources (List <Host > suitableHosts , Map <Volume , List <StoragePool >> suitableVolumeStoragePools ,
14791485 ExcludeList avoid , PlannerResourceUsage resourceUsageRequired , List <Volume > readyAndReusedVolumes , List <Long > preferredHosts , VirtualMachine vm ) {
1480- logger .debug ("Trying to find a potenial host and associated storage pools from the suitable host/pool lists for this VM" );
1486+ logger .debug ("Trying to find a potential host and associated storage pools from the suitable host/pool lists for this VM" );
14811487
14821488 boolean hostCanAccessPool = false ;
14831489 boolean haveEnoughSpace = false ;
0 commit comments