2929import org .apache .log4j .Logger ;
3030
3131import com .cloud .configuration .Config ;
32+ import com .cloud .deploy .DeploymentPlanner .PlannerResourceUsage ;
33+ import com .cloud .deploy .dao .PlannerHostReservationDao ;
3234import com .cloud .exception .InsufficientServerCapacityException ;
3335import com .cloud .host .HostVO ;
3436import com .cloud .resource .ResourceManager ;
3941import com .cloud .utils .DateUtil ;
4042import com .cloud .utils .NumbersUtil ;
4143import com .cloud .vm .UserVmVO ;
44+ import com .cloud .vm .VMInstanceVO ;
4245import com .cloud .vm .VirtualMachine ;
4346import com .cloud .vm .VirtualMachineProfile ;
4447
@@ -98,12 +101,12 @@ public List<Long> orderClusters(VirtualMachineProfile<? extends VirtualMachine>
98101 Set <Long > hostRunningStrictImplicitVmsOfOtherAccounts = new HashSet <Long >();
99102 Set <Long > allOtherHosts = new HashSet <Long >();
100103 for (Long host : allHosts ) {
101- List <UserVmVO > userVms = getVmsOnHost (host );
102- if (userVms == null || userVms .isEmpty ()) {
104+ List <VMInstanceVO > vms = getVmsOnHost (host );
105+ if (vms == null || vms .isEmpty ()) {
103106 emptyHosts .add (host );
104- } else if (checkHostSuitabilityForImplicitDedication (account .getAccountId (), userVms )) {
107+ } else if (checkHostSuitabilityForImplicitDedication (account .getAccountId (), vms )) {
105108 hostRunningVmsOfAccount .add (host );
106- } else if (checkIfAllVmsCreatedInStrictMode (account .getAccountId (), userVms )) {
109+ } else if (checkIfAllVmsCreatedInStrictMode (account .getAccountId (), vms )) {
107110 hostRunningStrictImplicitVmsOfOtherAccounts .add (host );
108111 } else {
109112 allOtherHosts .add (host );
@@ -139,12 +142,12 @@ public List<Long> orderClusters(VirtualMachineProfile<? extends VirtualMachine>
139142 return clusterList ;
140143 }
141144
142- private List <UserVmVO > getVmsOnHost (long hostId ) {
143- List <UserVmVO > vms = _vmDao .listUpByHostId (hostId );
144- List <UserVmVO > vmsByLastHostId = _vmDao .listByLastHostId (hostId );
145+ private List <VMInstanceVO > getVmsOnHost (long hostId ) {
146+ List <VMInstanceVO > vms = _vmInstanceDao .listUpByHostId (hostId );
147+ List <VMInstanceVO > vmsByLastHostId = _vmInstanceDao .listByLastHostId (hostId );
145148 if (vmsByLastHostId .size () > 0 ) {
146149 // check if any VMs are within skip.counting.hours, if yes we have to consider the host.
147- for (UserVmVO stoppedVM : vmsByLastHostId ) {
150+ for (VMInstanceVO stoppedVM : vmsByLastHostId ) {
148151 long secondsSinceLastUpdate = (DateUtil .currentGMTTime ().getTime () - stoppedVM .getUpdateTime ()
149152 .getTime ()) / 1000 ;
150153 if (secondsSinceLastUpdate < capacityReleaseInterval ) {
@@ -156,9 +159,12 @@ private List<UserVmVO> getVmsOnHost(long hostId) {
156159 return vms ;
157160 }
158161
159- private boolean checkHostSuitabilityForImplicitDedication (Long accountId , List <UserVmVO > allVmsOnHost ) {
162+ private boolean checkHostSuitabilityForImplicitDedication (Long accountId , List <VMInstanceVO > allVmsOnHost ) {
160163 boolean suitable = true ;
161- for (UserVmVO vm : allVmsOnHost ) {
164+ if (allVmsOnHost .isEmpty ())
165+ return false ;
166+
167+ for (VMInstanceVO vm : allVmsOnHost ) {
162168 if (vm .getAccountId () != accountId ) {
163169 s_logger .info ("Host " + vm .getHostId () + " found to be unsuitable for implicit dedication as it is " +
164170 "running instances of another account" );
@@ -170,15 +176,17 @@ private boolean checkHostSuitabilityForImplicitDedication(Long accountId, List<U
170176 "is running instances of this account which haven't been created using implicit dedication." );
171177 suitable = false ;
172178 break ;
173- }
179+ }
174180 }
175181 }
176182 return suitable ;
177183 }
178184
179- private boolean checkIfAllVmsCreatedInStrictMode (Long accountId , List <UserVmVO > allVmsOnHost ) {
185+ private boolean checkIfAllVmsCreatedInStrictMode (Long accountId , List <VMInstanceVO > allVmsOnHost ) {
180186 boolean createdByImplicitStrict = true ;
181- for (UserVmVO vm : allVmsOnHost ) {
187+ if (allVmsOnHost .isEmpty ())
188+ return false ;
189+ for (VMInstanceVO vm : allVmsOnHost ) {
182190 if (!isImplicitPlannerUsedByOffering (vm .getServiceOfferingId ())) {
183191 s_logger .info ("Host " + vm .getHostId () + " found to be running a vm created by a planner other" +
184192 " than implicit." );
@@ -243,7 +251,84 @@ private List<Long> getUpdatedClusterList(List<Long> clusterList, Set<Long> hosts
243251 }
244252
245253 @ Override
246- public PlannerResourceUsage getResourceUsage () {
247- return PlannerResourceUsage .Dedicated ;
254+ public PlannerResourceUsage getResourceUsage (VirtualMachineProfile <? extends VirtualMachine > vmProfile ,
255+ DeploymentPlan plan , ExcludeList avoid ) throws InsufficientServerCapacityException {
256+ // Check if strict or preferred mode should be used.
257+ boolean preferred = isServiceOfferingUsingPlannerInPreferredMode (vmProfile .getServiceOfferingId ());
258+
259+ // If service offering in strict mode return resource usage as Dedicated
260+ if (!preferred ) {
261+ return PlannerResourceUsage .Dedicated ;
262+ }
263+ else {
264+ // service offering is in implicit mode.
265+ // find is it possible to deploy in dedicated mode,
266+ // if its possible return dedicated else return shared.
267+ List <Long > clusterList = super .orderClusters (vmProfile , plan , avoid );
268+ Set <Long > hostsToAvoid = avoid .getHostsToAvoid ();
269+ Account account = vmProfile .getOwner ();
270+
271+ // Get the list of all the hosts in the given clusters
272+ List <Long > allHosts = new ArrayList <Long >();
273+ for (Long cluster : clusterList ) {
274+ List <HostVO > hostsInCluster = resourceMgr .listAllHostsInCluster (cluster );
275+ for (HostVO hostVO : hostsInCluster ) {
276+
277+ allHosts .add (hostVO .getId ());
278+ }
279+ }
280+
281+ // Go over all the hosts in the cluster and get a list of
282+ // 1. All empty hosts, not running any vms.
283+ // 2. Hosts running vms for this account and created by a service
284+ // offering which uses an
285+ // implicit dedication planner.
286+ // 3. Hosts running vms created by implicit planner and in strict
287+ // mode of other accounts.
288+ // 4. Hosts running vms from other account or from this account but
289+ // created by a service offering which uses
290+ // any planner besides implicit.
291+ Set <Long > emptyHosts = new HashSet <Long >();
292+ Set <Long > hostRunningVmsOfAccount = new HashSet <Long >();
293+ Set <Long > hostRunningStrictImplicitVmsOfOtherAccounts = new HashSet <Long >();
294+ Set <Long > allOtherHosts = new HashSet <Long >();
295+ for (Long host : allHosts ) {
296+ List <VMInstanceVO > vms = getVmsOnHost (host );
297+ // emptyHost should contain only Hosts which are not having any VM's (user/system) on it.
298+ if (vms == null || vms .isEmpty ()) {
299+ emptyHosts .add (host );
300+ } else if (checkHostSuitabilityForImplicitDedication (account .getAccountId (), vms )) {
301+ hostRunningVmsOfAccount .add (host );
302+ } else if (checkIfAllVmsCreatedInStrictMode (account .getAccountId (), vms )) {
303+ hostRunningStrictImplicitVmsOfOtherAccounts .add (host );
304+ } else {
305+ allOtherHosts .add (host );
306+ }
307+ }
308+
309+ // Hosts running vms of other accounts created by ab implicit
310+ // planner in strict mode should always be avoided.
311+ avoid .addHostList (hostRunningStrictImplicitVmsOfOtherAccounts );
312+
313+ if (!hostRunningVmsOfAccount .isEmpty ()
314+ && (hostsToAvoid == null || !hostsToAvoid .containsAll (hostRunningVmsOfAccount ))) {
315+ // Check if any of hosts that are running implicit dedicated vms are available (not in avoid list).
316+ // If so, we'll try and use these hosts. We can deploy in Dedicated mode
317+ return PlannerResourceUsage .Dedicated ;
318+ } else if (!emptyHosts .isEmpty () && (hostsToAvoid == null || !hostsToAvoid .containsAll (emptyHosts ))) {
319+ // If there aren't implicit resources try on empty hosts, As empty hosts are available we can deploy in Dedicated mode.
320+ // Empty hosts can contain hosts which are not having user vms but system vms are running.
321+ // But the host where system vms are running is marked as shared and still be part of empty Hosts.
322+ // The scenario will fail where actual Empty hosts and uservms not running host.
323+ return PlannerResourceUsage .Dedicated ;
324+ } else if (!preferred ) {
325+ return PlannerResourceUsage .Dedicated ;
326+ } else {
327+ if (!allOtherHosts .isEmpty () && (hostsToAvoid == null || !hostsToAvoid .containsAll (allOtherHosts ))) {
328+ return PlannerResourceUsage .Shared ;
329+ }
330+ }
331+ return PlannerResourceUsage .Shared ;
332+ }
248333 }
249- }
334+ }
0 commit comments