Gilad Chaplik has uploaded a new change for review. Change subject: core: Introduce sla package ......................................................................
core: Introduce sla package Move all host selection code into a separate package within bll. Remove all bll dependencies from those files Change-Id: Icac8f7bc8a696455134bb90ffc17afd420e18dd3 Signed-off-by: Gilad Chaplik <[email protected]> --- M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/InitBackendServicesOnStartupBean.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MemoryVdsComparer.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MigrateVmCommand.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/NonWaitingDelayer.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RunVmCommand.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RunVmCommandBase.java D backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VdsComparer.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmPoolCommandBase.java R backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/EvenlyDistributeComparer.java A backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/MigrationHandler.java R backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/NoneComparer.java R backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/PowerSaveComparer.java R backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/RunVmDelayer.java A backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/SlaValidator.java A backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/VdsComparer.java R backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/VdsCpuVdsLoadBalancingAlgorithm.java R backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/VdsFreeMemoryChecker.java R backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/VdsLoadBalancer.java R backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/VdsLoadBalancingAlgorithm.java R backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/VdsSelector.java R backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/VmCountVdsLoadBalancingAlgorithm.java A backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/a.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/validator/RunVmValidator.java M backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/RunVmCommandTest.java 24 files changed, 235 insertions(+), 183 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/80/14580/1 diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/InitBackendServicesOnStartupBean.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/InitBackendServicesOnStartupBean.java index da748a5..2691f48 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/InitBackendServicesOnStartupBean.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/InitBackendServicesOnStartupBean.java @@ -1,16 +1,23 @@ package org.ovirt.engine.core.bll; +import java.util.List; + import javax.annotation.PostConstruct; import javax.ejb.DependsOn; import javax.ejb.Singleton; import javax.ejb.Startup; import org.ovirt.engine.core.bll.gluster.GlusterJobsManager; +import org.ovirt.engine.core.bll.job.ExecutionHandler; import org.ovirt.engine.core.bll.network.MacPoolManager; +import org.ovirt.engine.core.bll.sla.MigrationHandler; +import org.ovirt.engine.core.bll.sla.VdsLoadBalancer; import org.ovirt.engine.core.bll.storage.StoragePoolStatusHandler; -import org.ovirt.engine.core.common.config.Config; -import org.ovirt.engine.core.common.config.ConfigValues; +import org.ovirt.engine.core.common.action.MigrateVmToServerParameters; +import org.ovirt.engine.core.common.action.VdcActionType; +import org.ovirt.engine.core.common.utils.Pair; +import org.ovirt.engine.core.compat.Guid; import org.ovirt.engine.core.utils.exceptions.InitializationException; import org.ovirt.engine.core.utils.log.Log; import org.ovirt.engine.core.utils.log.LogFactory; @@ -41,9 +48,19 @@ AsyncTaskManager.getInstance().InitAsyncTaskManager(); OvfDataUpdater.getInstance().initOvfDataUpdater(); - if (Config.<Boolean> GetValue(ConfigValues.EnableVdsLoadBalancing)) { - VdsLoadBalancer.EnableLoadBalancer(); - } + VdsLoadBalancer.getInstance().setMigrationHandler(new MigrationHandler() { + + @Override + public void migrateVMs(List<Pair<Guid, Guid>> list) { + for (Pair<Guid, Guid> pair : list) { + MigrateVmToServerParameters parameters = + new MigrateVmToServerParameters(false, pair.getFirst(), pair.getSecond()); + Backend.getInstance().runInternalAction(VdcActionType.MigrateVmToServer, + parameters, + ExecutionHandler.createInternalJobContext()); + } + } + }); ThreadPoolUtil.execute(new Runnable() { @Override diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MemoryVdsComparer.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MemoryVdsComparer.java index 2d60f75..88aeb42 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MemoryVdsComparer.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MemoryVdsComparer.java @@ -1,5 +1,6 @@ package org.ovirt.engine.core.bll; +import org.ovirt.engine.core.bll.sla.VdsComparer; import org.ovirt.engine.core.common.businessentities.*; /** diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MigrateVmCommand.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MigrateVmCommand.java index 5e9b8d5..9c0f9d4 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MigrateVmCommand.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MigrateVmCommand.java @@ -3,6 +3,8 @@ import java.util.List; import org.ovirt.engine.core.bll.job.ExecutionHandler; +import org.ovirt.engine.core.bll.sla.VdsFreeMemoryChecker; +import org.ovirt.engine.core.bll.sla.VdsSelector; import org.ovirt.engine.core.bll.snapshots.SnapshotsValidator; import org.ovirt.engine.core.bll.validator.DiskImagesValidator; import org.ovirt.engine.core.common.AuditLogType; @@ -81,6 +83,7 @@ protected void initVdss() { setVdsIdRef(new Guid(getVm().getRunOnVds().toString())); setVdsDestinationId(getVdsSelector().getVdsToRunOn(true)); + VmHandler.UpdateVmGuestAgentVersion(getVm()); // make _destinationVds null in order to refresh it from db in case it // changed. _destinationVds = null; diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/NonWaitingDelayer.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/NonWaitingDelayer.java index 8e600fc..5e1e0b3 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/NonWaitingDelayer.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/NonWaitingDelayer.java @@ -1,5 +1,6 @@ package org.ovirt.engine.core.bll; +import org.ovirt.engine.core.bll.sla.RunVmDelayer; import org.ovirt.engine.core.compat.Guid; /** diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RunVmCommand.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RunVmCommand.java index 03d6c5e..a8f3e05 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RunVmCommand.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RunVmCommand.java @@ -19,6 +19,8 @@ import org.ovirt.engine.core.bll.quota.QuotaConsumptionParameter; import org.ovirt.engine.core.bll.quota.QuotaVdsDependent; import org.ovirt.engine.core.bll.quota.QuotaVdsGroupConsumptionParameter; +import org.ovirt.engine.core.bll.sla.VdsFreeMemoryChecker; +import org.ovirt.engine.core.bll.sla.VdsSelector; import org.ovirt.engine.core.bll.utils.PermissionSubject; import org.ovirt.engine.core.bll.utils.VmDeviceUtils; import org.ovirt.engine.core.bll.validator.RunVmValidator; @@ -560,6 +562,7 @@ protected boolean getVdsToRunOn() { // use destination vds or default vds or none setVdsId(getVdsSelector().getVdsToRunOn(false)); + VmHandler.UpdateVmGuestAgentVersion(getVm()); setVds(null); setVdsName(null); if (getVdsId().equals(Guid.Empty)) { diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RunVmCommandBase.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RunVmCommandBase.java index 5ed7bc3..e339d0a 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RunVmCommandBase.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RunVmCommandBase.java @@ -14,6 +14,8 @@ import org.ovirt.engine.core.bll.job.ExecutionContext.ExecutionMethod; import org.ovirt.engine.core.bll.job.ExecutionHandler; import org.ovirt.engine.core.bll.job.JobRepositoryFactory; +import org.ovirt.engine.core.bll.sla.RunVmDelayer; +import org.ovirt.engine.core.bll.sla.VdsSelector; import org.ovirt.engine.core.bll.snapshots.SnapshotsValidator; import org.ovirt.engine.core.bll.storage.StorageHelperDirector; import org.ovirt.engine.core.common.action.VmOperationParameterBase; @@ -22,7 +24,6 @@ import org.ovirt.engine.core.common.businessentities.LunDisk; import org.ovirt.engine.core.common.businessentities.StorageServerConnections; import org.ovirt.engine.core.common.businessentities.VDS; -import org.ovirt.engine.core.common.businessentities.VM; import org.ovirt.engine.core.common.businessentities.VMStatus; import org.ovirt.engine.core.common.config.Config; import org.ovirt.engine.core.common.config.ConfigValues; @@ -48,7 +49,7 @@ public abstract class RunVmCommandBase<T extends VmOperationParameterBase> extends VmCommand<T> implements IVdsAsyncCommand, RunVmDelayer { - private static Log log = LogFactory.getLog(RunVmCommandBase.class); + public static Log log = LogFactory.getLog(RunVmCommandBase.class); protected static final HashMap<Guid, Integer> _vds_pending_vm_count = new HashMap<Guid, Integer>(); private VdsSelector privateVdsSelector; protected boolean _isRerun = false; @@ -82,61 +83,6 @@ */ private List<Guid> getRunVdssList() { return getVdsSelector().getRunVdssList(); - } - - /** - * Check if the given host has enough CPU to run the VM, without exceeding the high utilization threshold. - * - * @param vds - * The host to check. - * @param vm - * The VM to check. - * @return Does this host has enough CPU (without exceeding the threshold) to run the VM. - */ - public static boolean hasCpuToRunVM(VDS vds, VM vm) { - if (vds.getUsageCpuPercent() == null || vm.getUsageCpuPercent() == null) { - return false; - } - - // The predicted CPU is actually the CPU that the VM will take considering how many cores it has and now many - // cores the host has. This is why we take both parameters into consideration. - int predictedVmCpu = (vm.getUsageCpuPercent() * vm.getNumOfCpus()) / VdsSelector.getEffectiveCpuCores(vds); - boolean result = vds.getUsageCpuPercent() + predictedVmCpu <= vds.getHighUtilization(); - if (log.isDebugEnabled()) { - log.debugFormat("Host {0} has {1}% CPU load; VM {2} is predicted to have {3}% CPU load; " + - "High threshold is {4}%. Host is {5}suitable in terms of CPU.", - vds.getName(), - vds.getUsageCpuPercent(), - vm.getName(), - predictedVmCpu, - vds.getHighUtilization(), - (result ? "" : "not ")); - } - - return result; - } - - public static boolean hasMemoryToRunVM(VDS curVds, VM vm) { - boolean retVal = false; - if (curVds.getMemCommited() != null && curVds.getPhysicalMemMb() != null && curVds.getReservedMem() != null) { - double vdsCurrentMem = - curVds.getMemCommited() + curVds.getPendingVmemSize() + curVds.getGuestOverhead() + curVds - .getReservedMem() + vm.getMinAllocatedMem(); - double vdsMemLimit = curVds.getMaxVdsMemoryOverCommit() * curVds.getPhysicalMemMb() / 100.0; - if (log.isDebugEnabled()) { - log.debugFormat("hasMemoryToRunVM: host {0} pending vmem size is : {1} MB", - curVds.getName(), - curVds.getPendingVmemSize()); - log.debugFormat("Host Mem Conmmitted: {0}, Host Reserved Mem: {1}, Host Guest Overhead {2}, VM Min Allocated Mem {3}", - curVds.getMemCommited(), - curVds.getReservedMem(), - curVds.getGuestOverhead(), - vm.getMinAllocatedMem()); - log.debugFormat("{0} <= ??? {1}", vdsCurrentMem, vdsMemLimit); - } - retVal = (vdsCurrentMem <= vdsMemLimit); - } - return retVal; } @Override diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VdsComparer.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VdsComparer.java deleted file mode 100644 index 7cae7e5..0000000 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VdsComparer.java +++ /dev/null @@ -1,69 +0,0 @@ -package org.ovirt.engine.core.bll; - -import org.ovirt.engine.core.compat.*; -import org.ovirt.engine.core.common.businessentities.*; - -/** - * Base class for comparing between vdss - */ -public abstract class VdsComparer { - /** - * Factory method, creates necessary comparer - * - * @return - */ - public static VdsComparer CreateComparer(VdsSelectionAlgorithm selectionAlgorithm) { - switch (selectionAlgorithm) { - case EvenlyDistribute: - return new EvenlyDistributeComparer(); - case PowerSave: - return new PowerSaveComparer(); - case None: - return new NoneComparer(); - default: - throw new NotImplementedException("Uknown type of selection algorithm: " + selectionAlgorithm); - } - // try - // { - // //return AppDomain.CurrentDomain.CreateInstanceAndUnwrap("VdcBLL", - // GetComparerTypeName(selectionAlgorithm)) as VdsComparer; - // java.lang.Class type = - // java.lang.Class.forName(GetComparerTypeName(selectionAlgorithm)); - // //type.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, - // null, - // // CallingConventions.HasThis, null, null); - // java.lang.reflect.Constructor info = type.getConstructors()[0]; - // Object TempAsCast = info.newInstance(null); - // return (VdsComparer)((TempAsCast instanceof VdsComparer) ? TempAsCast - // : null); - // //return new BestDistributionComparer(); - // } - // catch (Exception ex) - // { - // throw new ApplicationException("JTODO unhandled exception", ex); - // } - } - - // private static String GetComparerTypeName(VdsSelectionAlgorithm - // selectionAlgorithm) - // { - // return String.format("%1$s.%2$s%3$s", - // "VdcBLL",selectionAlgorithm.toString(), "Comparer"); - // } - /** - * Base abstract function for finish best Vds treatment - * - * @param x - */ - public abstract void BestVdsProcedure(VDS x); - - /** - * Base abstract function to compare between two VDSs - * - * @param x - * @param y - * @param vm - * @return - */ - public abstract boolean IsBetter(VDS x, VDS y, VM vm); -} diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmPoolCommandBase.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmPoolCommandBase.java index 045e4b0..e4e5293 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmPoolCommandBase.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmPoolCommandBase.java @@ -5,6 +5,8 @@ import java.util.LinkedList; import java.util.List; +import org.ovirt.engine.core.bll.sla.VdsFreeMemoryChecker; +import org.ovirt.engine.core.bll.sla.VdsSelector; import org.ovirt.engine.core.bll.snapshots.SnapshotsValidator; import org.ovirt.engine.core.bll.storage.StoragePoolValidator; import org.ovirt.engine.core.bll.utils.PermissionSubject; diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/EvenlyDistributeComparer.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/EvenlyDistributeComparer.java similarity index 96% rename from backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/EvenlyDistributeComparer.java rename to backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/EvenlyDistributeComparer.java index 48c9ed5..87f3e23 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/EvenlyDistributeComparer.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/EvenlyDistributeComparer.java @@ -1,4 +1,4 @@ -package org.ovirt.engine.core.bll; +package org.ovirt.engine.core.bll.sla; import org.ovirt.engine.core.common.businessentities.*; import org.ovirt.engine.core.common.config.Config; diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/MigrationHandler.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/MigrationHandler.java new file mode 100644 index 0000000..836ec82 --- /dev/null +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/MigrationHandler.java @@ -0,0 +1,14 @@ +package org.ovirt.engine.core.bll.sla; + +import java.util.List; + +import org.ovirt.engine.core.common.utils.Pair; +import org.ovirt.engine.core.compat.Guid; + +public abstract class MigrationHandler { + /** + * this method holds a list of pairs VM id and Host id. each VM should be migrated to the specified Host + * @param list + */ + public abstract void migrateVMs(List<Pair<Guid, Guid>> list); +} diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/NoneComparer.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/NoneComparer.java similarity index 61% rename from backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/NoneComparer.java rename to backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/NoneComparer.java index aeb94a6..dd2bab7 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/NoneComparer.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/NoneComparer.java @@ -1,4 +1,5 @@ -package org.ovirt.engine.core.bll; +package org.ovirt.engine.core.bll.sla; + public class NoneComparer extends EvenlyDistributeComparer { } diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/PowerSaveComparer.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/PowerSaveComparer.java similarity index 94% rename from backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/PowerSaveComparer.java rename to backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/PowerSaveComparer.java index 643cf49..4dee9a6 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/PowerSaveComparer.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/PowerSaveComparer.java @@ -1,4 +1,4 @@ -package org.ovirt.engine.core.bll; +package org.ovirt.engine.core.bll.sla; import org.ovirt.engine.core.common.businessentities.*; diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RunVmDelayer.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/RunVmDelayer.java similarity index 77% rename from backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RunVmDelayer.java rename to backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/RunVmDelayer.java index 884749b..1122385 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RunVmDelayer.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/RunVmDelayer.java @@ -1,9 +1,9 @@ -package org.ovirt.engine.core.bll; +package org.ovirt.engine.core.bll.sla; import org.ovirt.engine.core.compat.Guid; /** - * Some commands e.g RunVm may run as a bulk AKA {@link MultipleActionsRunner} and performs logic to <br> + * Some commands e.g RunVm may run as a bulk and performs logic to <br> * count and reserve memory and CPU to assure there are both enough resources to complete them<br> * (i.e run a VM on a selected host) and that we don't exceed those for the subsequent executions.<br> * Moreover bulk operations may cause a pick in VDSM resources utilization and the engine can regulate <br> diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/SlaValidator.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/SlaValidator.java new file mode 100644 index 0000000..b38029f --- /dev/null +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/SlaValidator.java @@ -0,0 +1,70 @@ +package org.ovirt.engine.core.bll.sla; + +import org.ovirt.engine.core.common.businessentities.VDS; +import org.ovirt.engine.core.common.businessentities.VM; +import org.ovirt.engine.core.utils.log.Log; +import org.ovirt.engine.core.utils.log.LogFactory; + +public class SlaValidator { + public static Log log = LogFactory.getLog(SlaValidator.class); + + private static final SlaValidator instance = new SlaValidator(); + + public static SlaValidator getInstance() { + return instance; + } + + public boolean hasMemoryToRunVM(VDS curVds, VM vm) { + boolean retVal = false; + if (curVds.getMemCommited() != null && curVds.getPhysicalMemMb() != null && curVds.getReservedMem() != null) { + double vdsCurrentMem = + curVds.getMemCommited() + curVds.getPendingVmemSize() + curVds.getGuestOverhead() + curVds + .getReservedMem() + vm.getMinAllocatedMem(); + double vdsMemLimit = curVds.getMaxVdsMemoryOverCommit() * curVds.getPhysicalMemMb() / 100.0; + if (log.isDebugEnabled()) { + log.debugFormat("hasMemoryToRunVM: host {0} pending vmem size is : {1} MB", + curVds.getName(), + curVds.getPendingVmemSize()); + log.debugFormat("Host Mem Conmmitted: {0}, Host Reserved Mem: {1}, Host Guest Overhead {2}, VM Min Allocated Mem {3}", + curVds.getMemCommited(), + curVds.getReservedMem(), + curVds.getGuestOverhead(), + vm.getMinAllocatedMem()); + log.debugFormat("{0} <= ??? {1}", vdsCurrentMem, vdsMemLimit); + } + retVal = (vdsCurrentMem <= vdsMemLimit); + } + return retVal; + } + + /** + * Check if the given host has enough CPU to run the VM, without exceeding the high utilization threshold. + * + * @param vds + * The host to check. + * @param vm + * The VM to check. + * @return Does this host has enough CPU (without exceeding the threshold) to run the VM. + */ + public boolean hasCpuToRunVM(VDS vds, VM vm) { + if (vds.getUsageCpuPercent() == null || vm.getUsageCpuPercent() == null) { + return false; + } + // The predicted CPU is actually the CPU that the VM will take considering how many cores it has and now many + // cores the host has. This is why we take both parameters into consideration. + int predictedVmCpu = (vm.getUsageCpuPercent() * vm.getNumOfCpus()) / VdsSelector.getEffectiveCpuCores(vds); + boolean result = vds.getUsageCpuPercent() + predictedVmCpu <= vds.getHighUtilization(); + if (log.isDebugEnabled()) { + log.debugFormat("Host {0} has {1}% CPU load; VM {2} is predicted to have {3}% CPU load; " + + "High threshold is {4}%. Host is {5}suitable in terms of CPU.", + vds.getName(), + vds.getUsageCpuPercent(), + vm.getName(), + predictedVmCpu, + vds.getHighUtilization(), + (result ? "" : "not ")); + } + return result; + } + +} diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/VdsComparer.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/VdsComparer.java new file mode 100644 index 0000000..bc87ddd --- /dev/null +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/VdsComparer.java @@ -0,0 +1,43 @@ +package org.ovirt.engine.core.bll.sla; + +import org.ovirt.engine.core.common.businessentities.VDS; +import org.ovirt.engine.core.common.businessentities.VM; +import org.ovirt.engine.core.common.businessentities.VdsSelectionAlgorithm; + +/** + * Base class for comparing between Hosts + */ +public abstract class VdsComparer { + /** + * Factory method, creates necessary comparer + * + * @return + */ + public static VdsComparer CreateComparer(VdsSelectionAlgorithm selectionAlgorithm) { + switch (selectionAlgorithm) { + case EvenlyDistribute: + return new EvenlyDistributeComparer(); + case PowerSave: + return new PowerSaveComparer(); + default: + return new NoneComparer(); + } + } + + /** + * Base abstract function for finish best Vds treatment + * + * @param x + */ + public abstract void BestVdsProcedure(VDS x); + + /** + * Base abstract function to compare between two VDSs + * + * @param x + * @param y + * @param vm + * @return + */ + public abstract boolean IsBetter(VDS x, VDS y, VM vm); +} diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VdsCpuVdsLoadBalancingAlgorithm.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/VdsCpuVdsLoadBalancingAlgorithm.java similarity index 99% rename from backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VdsCpuVdsLoadBalancingAlgorithm.java rename to backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/VdsCpuVdsLoadBalancingAlgorithm.java index c7db4bf..32b5c28 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VdsCpuVdsLoadBalancingAlgorithm.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/VdsCpuVdsLoadBalancingAlgorithm.java @@ -1,4 +1,4 @@ -package org.ovirt.engine.core.bll; +package org.ovirt.engine.core.bll.sla; import java.util.Collections; import java.util.Comparator; diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VdsFreeMemoryChecker.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/VdsFreeMemoryChecker.java similarity index 87% rename from backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VdsFreeMemoryChecker.java rename to backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/VdsFreeMemoryChecker.java index 57ceca6..73d6ddf 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VdsFreeMemoryChecker.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/VdsFreeMemoryChecker.java @@ -1,4 +1,4 @@ -package org.ovirt.engine.core.bll; +package org.ovirt.engine.core.bll.sla; import org.apache.commons.logging.Log; import org.ovirt.engine.core.common.businessentities.VDS; @@ -18,7 +18,7 @@ public boolean evaluate(VDS vds, VM vm) { // first check if this host has enough memory run the VM. - if (!RunVmCommandBase.hasMemoryToRunVM(vds, vm)) { + if (!SlaValidator.getInstance().hasMemoryToRunVM(vds, vm)) { if (vds.getPendingVmemSize() == 0) { // there are no pending VMs to run - we hit the hard limit of memory, no special treatment @@ -35,7 +35,7 @@ vds = DbFacade.getInstance().getVdsDao().get(vds.getId()); // check free memory on the updated host - return RunVmCommandBase.hasMemoryToRunVM(vds, vm); + return SlaValidator.getInstance().hasMemoryToRunVM(vds, vm); } return true; } diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VdsLoadBalancer.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/VdsLoadBalancer.java similarity index 73% rename from backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VdsLoadBalancer.java rename to backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/VdsLoadBalancer.java index b503908..4df6903 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VdsLoadBalancer.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/VdsLoadBalancer.java @@ -1,4 +1,4 @@ -package org.ovirt.engine.core.bll; +package org.ovirt.engine.core.bll.sla; import java.util.List; import java.util.concurrent.TimeUnit; @@ -7,9 +7,9 @@ import org.ovirt.engine.core.common.businessentities.VdsSelectionAlgorithm; import org.ovirt.engine.core.common.config.Config; import org.ovirt.engine.core.common.config.ConfigValues; +import org.ovirt.engine.core.dal.dbbroker.DbFacade; import org.ovirt.engine.core.utils.log.Log; import org.ovirt.engine.core.utils.log.LogFactory; -import org.ovirt.engine.core.dal.dbbroker.DbFacade; import org.ovirt.engine.core.utils.timer.OnTimerMethodAnnotation; import org.ovirt.engine.core.utils.timer.SchedulerUtilQuartzImpl; @@ -19,8 +19,22 @@ */ public final class VdsLoadBalancer { private static Log log = LogFactory.getLog(VdsLoadBalancer.class); + private static VdsLoadBalancer instance = null; + private MigrationHandler migrationHandler = null; - private static VdsLoadBalancer instance = new VdsLoadBalancer(); + public static VdsLoadBalancer getInstance() { + if (instance == null) { + synchronized (VdsLoadBalancer.class) { + if (instance == null) { + instance = new VdsLoadBalancer(); + if (Config.<Boolean> GetValue(ConfigValues.EnableVdsLoadBalancing)) { + EnableLoadBalancer(); + } + } + } + } + return instance; + } private VdsLoadBalancer() { } @@ -40,7 +54,7 @@ group.gethigh_utilization(), group.getlow_utilization(), group.getcpu_over_commit_duration_minutes(), Config.<Integer> GetValue(ConfigValues.UtilizationThresholdInPercent)); - loadBalancingAlgorithm.LoadBalance(); + migrationHandler.migrateVMs(loadBalancingAlgorithm.LoadBalance()); } else { log.debugFormat("VdsLoadBalancer: Cluster {0} skipped because no selection algorithm selected.", group.getname()); @@ -55,4 +69,11 @@ Config.<Integer> GetValue(ConfigValues.VdsLoadBalancingeIntervalInMinutes), TimeUnit.MINUTES); log.info("Finished scheduling to enable vds load balancer"); } + + public void setMigrationHandler(MigrationHandler migrationHandler) { + if (this.migrationHandler != null) { + throw new RuntimeException("Load balance migration handler should be set only once"); + } + this.migrationHandler = migrationHandler; + } } diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VdsLoadBalancingAlgorithm.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/VdsLoadBalancingAlgorithm.java similarity index 89% rename from backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VdsLoadBalancingAlgorithm.java rename to backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/VdsLoadBalancingAlgorithm.java index e149da8..645ecfb 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VdsLoadBalancingAlgorithm.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/VdsLoadBalancingAlgorithm.java @@ -1,5 +1,6 @@ -package org.ovirt.engine.core.bll; +package org.ovirt.engine.core.bll.sla; +import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashSet; @@ -7,13 +8,11 @@ import java.util.Map; import java.util.Set; -import org.ovirt.engine.core.bll.job.ExecutionHandler; -import org.ovirt.engine.core.common.action.MigrateVmToServerParameters; -import org.ovirt.engine.core.common.action.VdcActionType; import org.ovirt.engine.core.common.businessentities.MigrationSupport; 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.utils.Pair; import org.ovirt.engine.core.compat.Guid; import org.ovirt.engine.core.dal.dbbroker.DbFacade; import org.ovirt.engine.core.utils.linq.Function; @@ -107,7 +106,8 @@ return new VdsCpuVdsLoadBalancingAlgorithm(group); } - public void LoadBalance() { + public List<Pair<Guid, Guid>> LoadBalance() { + List<Pair<Guid, Guid>> migrationList = new ArrayList<Pair<Guid, Guid>>(); setAllRelevantVdss(DbFacade.getInstance().getVdsDao().getAllForVdsGroupWithoutMigrating(getVdsGroup().getId())); log.infoFormat("VdsLoadBalancer: number of relevant vdss (no migration, no pending): {0}.", getAllRelevantVdss().size()); @@ -116,12 +116,13 @@ InitUnderUtilizedList(); if (getOverUtilizedServers().size() != 0 && (getReadyToMigrationServers().size() != 0 || getUnderUtilizedServers().size() != 0)) { - ProceedOverUtilizedServers(); + migrationList.addAll(ProceedOverUtilizedServers()); } if (getUnderUtilizedServers().size() > 0 && (getReadyToMigrationServers().size() > 0 || getUnderUtilizedServers().size() > 1)) { - ProceedUnderUtilizedServers(); + migrationList.addAll(ProceedUnderUtilizedServers()); } + return migrationList; } protected abstract void InitOverUtilizedList(); @@ -130,7 +131,7 @@ protected abstract void InitUnderUtilizedList(); - private void ProceedOverUtilizedServers() { + private List<Pair<Guid, Guid>> ProceedOverUtilizedServers() { List<Guid> overUtilizedServersIds = LinqUtils.foreach(getOverUtilizedServers().values(), new Function<VDS, Guid>() { @Override @@ -138,6 +139,7 @@ return vds.getId(); } }); + List<Pair<Guid, Guid>> vmVdsMigrationList = new ArrayList<Pair<Guid, Guid>>(); for (Guid vdsId : overUtilizedServersIds) { VDS vds = getOverUtilizedServers().get(vdsId); log.infoFormat("VdsLoadBalancer: Server {0} decided as overutilized", vds.getName()); @@ -178,11 +180,7 @@ /** * Migrate vm from OverUtilezed server */ - MigrateVmToServerParameters parameters = - new MigrateVmToServerParameters(false, vm.getId(), destinationVdsId); - Backend.getInstance().runInternalAction(VdcActionType.MigrateVmToServer, - parameters, - ExecutionHandler.createInternalJobContext()); + vmVdsMigrationList.add(new Pair<Guid, Guid>(vm.getId(), destinationVdsId)); /** * Remove server from list */ @@ -195,9 +193,10 @@ log.info("VdsLoadBalancer: No vms found to migrate on this server"); } } + return vmVdsMigrationList; } - private void ProceedUnderUtilizedServers() { + private List<Pair<Guid, Guid>> ProceedUnderUtilizedServers() { List<Guid> underUtilizedServersIds = LinqUtils.foreach(getUnderUtilizedServers().values(), new Function<VDS, Guid>() { @Override @@ -206,6 +205,7 @@ } }); Set<Guid> processed = new HashSet<Guid>(); + List<Pair<Guid, Guid>> vmVdsMigrationList = new ArrayList<Pair<Guid, Guid>>(); for (Guid vdsId : underUtilizedServersIds) { if (!processed.contains(vdsId)) { VDS vds = getUnderUtilizedServers().get(vdsId); @@ -251,11 +251,7 @@ vds.getName()); } else { Guid destinationVdsId = destinationVds.getId(); - MigrateVmToServerParameters parameters = - new MigrateVmToServerParameters(false, vm.getId(), destinationVdsId); - Backend.getInstance().runInternalAction(VdcActionType.MigrateVmToServer, - parameters, - ExecutionHandler.createInternalJobContext()); + vmVdsMigrationList.add(new Pair<Guid, Guid>(vm.getId(), destinationVdsId)); currentList.remove(destinationVdsId); log.infoFormat( "VdsLoadBalancer: Desktop {0} migrated from underutilized server {1} to server {2}", @@ -273,6 +269,7 @@ // passed vm on it } } + return vmVdsMigrationList; } private java.util.List<VM> getMigrableVmsRunningOnVds(Guid vdsId) { @@ -293,8 +290,8 @@ @Override public boolean eval(VDS p) { return (p.getVdsGroupId().equals(vm.getVdsGroupId()) - && RunVmCommandBase.hasMemoryToRunVM(p, vm) - && RunVmCommandBase.hasCpuToRunVM(p, vm)); + && SlaValidator.getInstance().hasMemoryToRunVM(p, vm) + && SlaValidator.getInstance().hasCpuToRunVM(p, vm)); } }); } diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VdsSelector.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/VdsSelector.java similarity index 95% rename from backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VdsSelector.java rename to backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/VdsSelector.java index a9b3183..6f9bd03 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VdsSelector.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/VdsSelector.java @@ -1,4 +1,4 @@ -package org.ovirt.engine.core.bll; +package org.ovirt.engine.core.bll.sla; import java.util.ArrayList; import java.util.Arrays; @@ -135,7 +135,6 @@ VDS target_vds = DbFacade.getInstance().getVdsDao().get(getDestinationVdsId()); log.infoFormat("Checking for a specific VDS only - id:{0}, name:{1}, host_name(ip):{2}", getDestinationVdsId(), target_vds.getName(), target_vds.getHostName()); - VmHandler.UpdateVmGuestAgentVersion(getVm()); result = getVdsToRunOn(Arrays.asList(target_vds), isMigrate); } return result; @@ -183,17 +182,15 @@ for (VDS curVds : vdss) { noVDSs = false; - ValidationResult result = validateHostIsReadyToRun(curVds, sb, isMigrate); - if (result.isValid()) { + VdcBllMessages result = validateHostIsReadyToRun(curVds, sb, isMigrate); + if (result == null) { return true; } else { - if (messageToReturn.getValue() < result.getMessage().getValue()) { - messageToReturn = result.getMessage(); - /** - * save version of current vds for later use - */ - vdsVersion = curVds.getVersion(); - } + messageToReturn = result; + /** + * save version of current vds for later use + */ + vdsVersion = curVds.getVersion(); } } @@ -208,7 +205,6 @@ * action message */ if (messageToReturn == VdcBllMessages.ACTION_TYPE_FAILED_VDS_VM_VERSION && vdsVersion != null) { - VmHandler.UpdateVmGuestAgentVersion(getVm()); messages.add("$toolsVersion " + getVm().getPartialVersion()); messages.add("$serverVersion " + vdsVersion.getRpmName()); @@ -325,18 +321,18 @@ } }); - private ValidationResult validateHostIsReadyToRun(final VDS vds, StringBuilder sb, boolean isMigrate) { + private VdcBllMessages validateHostIsReadyToRun(final VDS vds, StringBuilder sb, boolean isMigrate) { // buffer the mismatches as we go sb.append(" VDS ").append(vds.getName()).append(" ").append(vds.getId()).append(" "); for(HostValidator validator : this.hostValidators) { VdcBllMessages result = validator.validate(vds, sb, isMigrate); if(result != null) { - return new ValidationResult(result); + return result; } } - return ValidationResult.VALID; + return null; } /** @@ -431,7 +427,7 @@ StringBuilder sb = new StringBuilder(); final List<VDS> readyToRun = new ArrayList<VDS>(); for (VDS curVds : vdss) { - if (validateHostIsReadyToRun(curVds, sb, isMigrate) == ValidationResult.VALID) { + if (validateHostIsReadyToRun(curVds, sb, isMigrate) == null) { readyToRun.add(curVds); } } diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmCountVdsLoadBalancingAlgorithm.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/VmCountVdsLoadBalancingAlgorithm.java similarity index 99% rename from backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmCountVdsLoadBalancingAlgorithm.java rename to backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/VmCountVdsLoadBalancingAlgorithm.java index adeb99c..142070a 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmCountVdsLoadBalancingAlgorithm.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/VmCountVdsLoadBalancingAlgorithm.java @@ -1,4 +1,4 @@ -package org.ovirt.engine.core.bll; +package org.ovirt.engine.core.bll.sla; import java.util.Collections; import java.util.Comparator; diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/a.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/a.java new file mode 100644 index 0000000..6858b82 --- /dev/null +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/sla/a.java @@ -0,0 +1,5 @@ +package org.ovirt.engine.core.bll.sla; + +public class a { + +} diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/validator/RunVmValidator.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/validator/RunVmValidator.java index 8303cb9..ac239ce 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/validator/RunVmValidator.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/validator/RunVmValidator.java @@ -12,9 +12,9 @@ import org.ovirt.engine.core.bll.ImagesHandler; import org.ovirt.engine.core.bll.IsoDomainListSyncronizer; import org.ovirt.engine.core.bll.ValidationResult; -import org.ovirt.engine.core.bll.VdsSelector; import org.ovirt.engine.core.bll.VmHandler; import org.ovirt.engine.core.bll.interfaces.BackendInternal; +import org.ovirt.engine.core.bll.sla.VdsSelector; import org.ovirt.engine.core.bll.snapshots.SnapshotsValidator; import org.ovirt.engine.core.bll.storage.StoragePoolValidator; import org.ovirt.engine.core.common.VdcActionUtils; diff --git a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/RunVmCommandTest.java b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/RunVmCommandTest.java index e16a91a..e84f422 100644 --- a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/RunVmCommandTest.java +++ b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/RunVmCommandTest.java @@ -28,6 +28,7 @@ import org.mockito.runners.MockitoJUnitRunner; import org.mockito.stubbing.Answer; import org.ovirt.engine.core.bll.interfaces.BackendInternal; +import org.ovirt.engine.core.bll.sla.VdsSelector; import org.ovirt.engine.core.bll.snapshots.SnapshotsValidator; import org.ovirt.engine.core.bll.validator.RunVmValidator; import org.ovirt.engine.core.common.action.RunVmParams; -- To view, visit http://gerrit.ovirt.org/14580 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Icac8f7bc8a696455134bb90ffc17afd420e18dd3 Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: master Gerrit-Owner: Gilad Chaplik <[email protected]> _______________________________________________ Engine-patches mailing list [email protected] http://lists.ovirt.org/mailman/listinfo/engine-patches
