Jiří Moskovčák has uploaded a new change for review.

Change subject: initial implementation of EvenGuestDistribution
......................................................................

initial implementation of EvenGuestDistribution

Change-Id: I2f2036dfc8a410c787a195d7d56ac3ed4ace81a7
Signed-off-by: Jiri Moskovcak <[email protected]>
---
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/PolicyUnitImpl.java
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/policyunits/EvenDistributionBalancePolicyUnit.java
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/policyunits/EvenGuestDistributionBalancePolicyUnit.java
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/policyunits/EvenGuestDistributionWeightPolicyUnit.java
M 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VDS.java
M 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/config/ConfigValues.java
M 
backend/manager/modules/restapi/interface/definition/src/main/resources/api.xsd
M 
backend/manager/modules/restapi/types/src/main/java/org/ovirt/engine/api/restapi/types/ClusterMapper.java
A packaging/dbscripts/upgrade/03_04_0390_add_even_guest_distribution_policy.sql
9 files changed, 210 insertions(+), 11 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/03/23103/1

diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/PolicyUnitImpl.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/PolicyUnitImpl.java
index 517197b..7033881 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/PolicyUnitImpl.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/PolicyUnitImpl.java
@@ -9,6 +9,8 @@
 import 
org.ovirt.engine.core.bll.scheduling.policyunits.CpuLevelFilterPolicyUnit;
 import 
org.ovirt.engine.core.bll.scheduling.policyunits.EvenDistributionBalancePolicyUnit;
 import 
org.ovirt.engine.core.bll.scheduling.policyunits.EvenDistributionWeightPolicyUnit;
+import 
org.ovirt.engine.core.bll.scheduling.policyunits.EvenGuestDistributionBalancePolicyUnit;
+import 
org.ovirt.engine.core.bll.scheduling.policyunits.EvenGuestDistributionWeightPolicyUnit;
 import 
org.ovirt.engine.core.bll.scheduling.policyunits.HostedEngineHAClusterFilterPolicyUnit;
 import 
org.ovirt.engine.core.bll.scheduling.policyunits.HostedEngineHAClusterWeightPolicyUnit;
 import org.ovirt.engine.core.bll.scheduling.policyunits.MemoryPolicyUnit;
@@ -75,6 +77,14 @@
                 return new EvenDistributionBalancePolicyUnit(policyUnit);
             }
             break;
+        case "OptimalForEvenGuestDistribution":
+                if (policyUnit.getPolicyUnitType() == PolicyUnitType.Weight) {
+                    return new 
EvenGuestDistributionWeightPolicyUnit(policyUnit);
+                }
+                else if (policyUnit.getPolicyUnitType() == 
PolicyUnitType.LoadBalancing) {
+                    return new 
EvenGuestDistributionBalancePolicyUnit(policyUnit);
+                }
+                break;
         default:
             break;
         }
@@ -182,6 +192,17 @@
         policyUnit.setEnabled(enabled);
     }
 
+    protected int tryParseWithDefault(String candidate, int defaultValue) {
+        if (candidate != null) {
+            try {
+                return Integer.parseInt(candidate);
+            } catch (Exception e) {
+                // do nothing
+            }
+        }
+        return defaultValue;
+    }
+
     public final PolicyUnit getPolicyUnit() {
         return policyUnit;
     }
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/policyunits/EvenDistributionBalancePolicyUnit.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/policyunits/EvenDistributionBalancePolicyUnit.java
index 1e42831..c9ee5b8 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/policyunits/EvenDistributionBalancePolicyUnit.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/policyunits/EvenDistributionBalancePolicyUnit.java
@@ -44,12 +44,21 @@
             return null;
         }
         // get vds that over committed for the time defined
+        /* returns list of Hosts with
+         *    cpuUtilization >= highUtilization
+         *    && cpuOverCommitMinutes >= CpuOverCommitDurationMinutes
+         */
         List<VDS> overUtilizedHosts = getOverUtilizedHosts(hosts, parameters);
 
+        // if no hosts is overutilized, then there is nothing to balance...
         if (overUtilizedHosts == null || overUtilizedHosts.size() == 0) {
             return null;
         }
+
+        // returns hosts with utilization lower then the specified threshold
         List<VDS> underUtilizedHosts = getUnderUtilizedHosts(cluster, hosts, 
parameters);
+
+        //if no host has a spare power, then there is nothing we can do to 
balance it..
         if (underUtilizedHosts == null || underUtilizedHosts.size() == 0) {
             return null;
         }
@@ -188,16 +197,5 @@
         private static int calculateCpuUsage(VM o1) {
             return o1.getUsageCpuPercent() * o1.getNumOfCpus();
         }
-    }
-
-    protected int tryParseWithDefault(String candidate, int defaultValue) {
-        if (candidate != null) {
-            try {
-                return Integer.parseInt(candidate);
-            } catch (Exception e) {
-                // do nothing
-            }
-        }
-        return defaultValue;
     }
 }
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/policyunits/EvenGuestDistributionBalancePolicyUnit.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/policyunits/EvenGuestDistributionBalancePolicyUnit.java
new file mode 100644
index 0000000..9affcab
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/policyunits/EvenGuestDistributionBalancePolicyUnit.java
@@ -0,0 +1,96 @@
+package org.ovirt.engine.core.bll.scheduling.policyunits;
+
+import org.ovirt.engine.core.common.businessentities.VDS;
+import org.ovirt.engine.core.common.businessentities.VDSGroup;
+import org.ovirt.engine.core.common.config.Config;
+import org.ovirt.engine.core.common.config.ConfigValues;
+import org.ovirt.engine.core.common.scheduling.PolicyUnit;
+import org.ovirt.engine.core.utils.linq.LinqUtils;
+import org.ovirt.engine.core.utils.linq.Predicate;
+
+import java.util.List;
+import java.util.Map;
+
+public class EvenGuestDistributionBalancePolicyUnit extends 
EvenDistributionBalancePolicyUnit {
+
+
+    public EvenGuestDistributionBalancePolicyUnit (PolicyUnit policyUnit) {
+        super(policyUnit);
+    }
+
+    private int getSPMGraceDefaultValue() {
+        return Config.<Integer> 
getValue(ConfigValues.SPMVMGraceForEvenGuestDistribute);
+    }
+
+    private int getMigrationThresholdDefault() {
+        return Config.<Integer> 
getValue(ConfigValues.MigrationThresholdForEvenGuestDistribute);
+    }
+
+    private int getHighVMCountDefaultValue() {
+        return Config.<Integer> 
getValue(ConfigValues.HighVMCountForEvenGuestDistribute);
+    }
+
+    /* returns the number of running VMS on given VDS
+       if the VDS is SPM the return value is the number of running VMS + 
SPMVMCountGrace
+     */
+    private int getOccupiedVMSLots(VDS vds, Map<String, String> parameters) {
+        int occupiedSlots = vds.getVmActive();
+        final int SPMVMCountGrace = 
tryParseWithDefault(parameters.get("SPMVMCountGrace"),
+                getSPMGraceDefaultValue());
+        if (vds.isSpm())
+            occupiedSlots += SPMVMCountGrace;
+
+        return occupiedSlots;
+    }
+
+    private VDS getWorstVDS(List<VDS> relevantHosts, Map<String, String> 
parameters) {
+        VDS worstVDS = relevantHosts.get(0);
+        for (VDS vds: relevantHosts) {
+            if (getOccupiedVMSLots(vds, parameters) > 
getOccupiedVMSLots(worstVDS, parameters))
+                worstVDS = vds;
+        }
+
+        return worstVDS;
+    }
+
+    @Override
+    protected List<VDS> getOverUtilizedHosts(List<VDS> relevantHosts,
+            final Map<String, String> parameters) {
+
+        final int highVmCountUtilization = 
tryParseWithDefault(parameters.get("HighVMCount"),
+                getHighVMCountDefaultValue());
+
+        final VDS worstVDS = getWorstVDS(relevantHosts, parameters);
+        if (getOccupiedVMSLots(worstVDS, parameters) < highVmCountUtilization) 
{
+            log.debugFormat("No host is overutilized, the worst is {1} with 
{2} occupied VM slots", worstVDS.getName(), getOccupiedVMSLots(worstVDS, 
parameters));
+            return null;
+        }
+
+        return LinqUtils.filter(relevantHosts, new Predicate<VDS>() {
+            @Override
+            public boolean eval(VDS p) {
+                return getOccupiedVMSLots(p, parameters) >= 
getOccupiedVMSLots(worstVDS, parameters);
+            }
+        });
+    }
+
+    @Override
+    protected List<VDS> getUnderUtilizedHosts(VDSGroup cluster,
+            List<VDS> relevantHosts,
+            final Map<String, String> parameters) {
+
+        final int migrationThreshold = 
tryParseWithDefault(parameters.get("MigrationThreshold"),
+                getMigrationThresholdDefault());
+
+        final VDS worstVDS = getWorstVDS(relevantHosts, parameters);
+
+        return LinqUtils.filter(relevantHosts, new Predicate<VDS>() {
+            @Override
+            public boolean eval(VDS p) {
+                int distance = getOccupiedVMSLots(worstVDS, parameters) - 
getOccupiedVMSLots(p, parameters);
+                return distance < migrationThreshold;
+            }
+        });
+    }
+
+}
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/policyunits/EvenGuestDistributionWeightPolicyUnit.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/policyunits/EvenGuestDistributionWeightPolicyUnit.java
new file mode 100644
index 0000000..692c921
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/policyunits/EvenGuestDistributionWeightPolicyUnit.java
@@ -0,0 +1,50 @@
+package org.ovirt.engine.core.bll.scheduling.policyunits;
+
+import org.ovirt.engine.core.bll.scheduling.PolicyUnitImpl;
+import org.ovirt.engine.core.common.businessentities.VDS;
+import org.ovirt.engine.core.common.businessentities.VDSGroup;
+import org.ovirt.engine.core.common.businessentities.VM;
+import org.ovirt.engine.core.common.config.Config;
+import org.ovirt.engine.core.common.config.ConfigValues;
+import org.ovirt.engine.core.common.scheduling.PolicyUnit;
+import org.ovirt.engine.core.common.utils.Pair;
+import org.ovirt.engine.core.compat.Guid;
+import org.ovirt.engine.core.dal.dbbroker.DbFacade;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+public class EvenGuestDistributionWeightPolicyUnit extends PolicyUnitImpl {
+    public EvenGuestDistributionWeightPolicyUnit (PolicyUnit policyUnit) {
+        super(policyUnit);
+    }
+
+    private int getSPMGraceDefaultValue() {
+        return Config.<Integer> 
getValue(ConfigValues.SPMVMGraceForEvenGuestDistribute);
+    }
+
+    private int getOccupiedVMSLots(VDS vds, Map<String, String> parameters) {
+        int occupiedSlots = vds.getVmActive();
+        final int SPMVMCountGrace = 
tryParseWithDefault(parameters.get("SPMVMCountGrace"),
+                getSPMGraceDefaultValue());
+        if (vds.isSpm())
+            occupiedSlots += SPMVMCountGrace;
+
+        return occupiedSlots;
+    }
+
+    private int calcEvenGuestDistributionScore(VDS vds) {
+        return Math.max(0, vds.getVmCount());
+    }
+
+    @Override
+    public List<Pair<Guid, Integer>> score(List<VDS> hosts, VM vm, Map<String, 
String> parameters) {
+        VDSGroup vdsGroup = 
DbFacade.getInstance().getVdsGroupDao().get(hosts.get(0).getVdsGroupId());
+        List<Pair<Guid, Integer>> scores = new ArrayList<Pair<Guid, 
Integer>>();
+        for (VDS vds : hosts) {
+            scores.add(new Pair<Guid, Integer>(vds.getId(), 
calcEvenGuestDistributionScore(vds)));
+        }
+        return scores;
+    }
+}
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VDS.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VDS.java
index 6c64c74..1ad5de4 100644
--- 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VDS.java
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VDS.java
@@ -1185,6 +1185,10 @@
         _spm_status = value;
     }
 
+    public boolean isSpm() {
+        return _spm_status == VdsSpmStatus.SPM;
+    }
+
     public NonOperationalReason getNonOperationalReason() {
         return this.mVdsDynamic.getNonOperationalReason();
     }
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/config/ConfigValues.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/config/ConfigValues.java
index 6113ddd..b5eee3b 100644
--- 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/config/ConfigValues.java
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/config/ConfigValues.java
@@ -427,6 +427,18 @@
     @DefaultValueAttribute("120")
     MaxVdsMemOverCommitForServers,
     @Reloadable
+    @TypeConverterAttribute(Integer.class)
+    @DefaultValueAttribute("10")
+    HighVMCountForEvenGuestDistribute,
+    @Reloadable
+    @TypeConverterAttribute(Integer.class)
+    @DefaultValueAttribute("5")
+    SPMVMGraceForEvenGuestDistribute,
+    @Reloadable
+    @TypeConverterAttribute(Integer.class)
+    @DefaultValueAttribute("5")
+    MigrationThresholdForEvenGuestDistribute,
+    @Reloadable
     @TypeConverterAttribute(Boolean.class)
     @DefaultValueAttribute("true")
     AutoInstallCertificateOnApprove,
diff --git 
a/backend/manager/modules/restapi/interface/definition/src/main/resources/api.xsd
 
b/backend/manager/modules/restapi/interface/definition/src/main/resources/api.xsd
index 012dd94..eef4a4b 100644
--- 
a/backend/manager/modules/restapi/interface/definition/src/main/resources/api.xsd
+++ 
b/backend/manager/modules/restapi/interface/definition/src/main/resources/api.xsd
@@ -1240,6 +1240,14 @@
           </xs:appinfo>
         </xs:annotation>
     </xs:attribute>
+      <xs:attribute name="vmscount" type="xs:int">
+          <xs:annotation>
+              <xs:appinfo>
+                  <jaxb:property generateIsSetMethod="false"/>
+              </xs:appinfo>
+          </xs:annotation>
+      </xs:attribute>
+
   </xs:complexType>
 
   <xs:complexType name="SchedulingPolicy">
diff --git 
a/backend/manager/modules/restapi/types/src/main/java/org/ovirt/engine/api/restapi/types/ClusterMapper.java
 
b/backend/manager/modules/restapi/types/src/main/java/org/ovirt/engine/api/restapi/types/ClusterMapper.java
index 7b25265..036915f 100644
--- 
a/backend/manager/modules/restapi/types/src/main/java/org/ovirt/engine/api/restapi/types/ClusterMapper.java
+++ 
b/backend/manager/modules/restapi/types/src/main/java/org/ovirt/engine/api/restapi/types/ClusterMapper.java
@@ -28,6 +28,7 @@
     private static final String CPU_OVER_COMMIT_DURATION_MINUTES = 
"CpuOverCommitDurationMinutes";
     private static final String HIGH_UTILIZATION = "HighUtilization";
     private static final String LOW_UTILIZATION = "LowUtilization";
+    private static final String HIGH_VM_COUNT = "HighVmCount";
     static final org.ovirt.engine.core.compat.Version min_thp_version = new 
org.ovirt.engine.core.compat.Version(3, 0);
 
     @Mapping(from = Cluster.class, to = VDSGroup.class)
@@ -188,6 +189,9 @@
             if (thresholds.getHigh() != null) {
                 entity.getClusterPolicyProperties().put(HIGH_UTILIZATION, 
thresholds.getHigh().toString());
             }
+            if (thresholds.getHigh() != null) {
+                entity.getClusterPolicyProperties().put(HIGH_VM_COUNT, 
thresholds.getVmscount().toString());
+            }
             if (thresholds.getDuration() != null) {
                 int round = Math.round(thresholds.getDuration() / 60.0f);
                 
entity.getClusterPolicyProperties().put(CPU_OVER_COMMIT_DURATION_MINUTES, 
Integer.toString(round));
diff --git 
a/packaging/dbscripts/upgrade/03_04_0390_add_even_guest_distribution_policy.sql 
b/packaging/dbscripts/upgrade/03_04_0390_add_even_guest_distribution_policy.sql
new file mode 100644
index 0000000..fb782e5
--- /dev/null
+++ 
b/packaging/dbscripts/upgrade/03_04_0390_add_even_guest_distribution_policy.sql
@@ -0,0 +1,6 @@
+INSERT INTO policy_units (id, name, is_internal, type, enabled, 
custom_properties_regex, description) VALUES 
('d58c8e32-44e1-418f-9222-52cd887bf9e0', 'OptimalForEvenGuestDistribution', 
true, 2, true,
+'{"HighVmCount" : "^([5-9][0-9])$"}', 'Even VM count distribution policy');
+INSERT INTO cluster_policies (id, name, description, is_locked, is_default, 
custom_properties) VALUES ('8d5d7bec-68de-4a67-b53e-0ac54686d579', 
'VM_Evenly_Distributed', '', true, false, '{"HighVMCount" : "10"}');
+
+-- add the policy units to the VM_Evenly_Distributed cluster policy
+INSERT INTO cluster_policy_units (cluster_policy_id, policy_unit_id, 
filter_sequence, factor) VALUES ('8d5d7bec-68de-4a67-b53e-0ac54686d579', 
'd58c8e32-44e1-418f-9222-52cd887bf9e0', 0, 1);


-- 
To view, visit http://gerrit.ovirt.org/23103
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I2f2036dfc8a410c787a195d7d56ac3ed4ace81a7
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: master
Gerrit-Owner: Jiří Moskovčák <[email protected]>
_______________________________________________
Engine-patches mailing list
[email protected]
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to