Roy Golan has uploaded a new change for review. Change subject: core: monitoring - Create a VM manager to co-ordinate monitoring and commands ......................................................................
core: monitoring - Create a VM manager to co-ordinate monitoring and commands Change-Id: I54c6091a3996c23a4b70c7ef89412d34f1b58e34 Signed-off-by: Roy Golan <[email protected]> --- M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RemoveVmCommand.java M backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/CreateVmVDSCommand.java M backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/DestroyVmVDSCommand.java M backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/HibernateVDSCommand.java M backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/HostMonitoring.java A backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/ManagingVmCommand.java M backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/MigrateVDSCommand.java M backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/ResourceManager.java M backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/ResumeVDSCommand.java M backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VdsManager.java A backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VmManager.java M backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VmsMonitoring.java 12 files changed, 287 insertions(+), 149 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/73/28173/1 diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RemoveVmCommand.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RemoveVmCommand.java index d14f7b3..e84ff1d 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RemoveVmCommand.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RemoveVmCommand.java @@ -45,6 +45,7 @@ import org.ovirt.engine.core.dal.dbbroker.DbFacade; import org.ovirt.engine.core.utils.transaction.TransactionMethod; import org.ovirt.engine.core.utils.transaction.TransactionSupport; +import org.ovirt.engine.core.vdsbroker.ResourceManager; @DisableInPrepareMode @LockIdNameAttribute @@ -118,7 +119,7 @@ } removeMemoryVolumes(); - + ResourceManager.getInstance().onVmDelete(getVmId()); return true; } diff --git a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/CreateVmVDSCommand.java b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/CreateVmVDSCommand.java index ebaf240..bb885bc 100644 --- a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/CreateVmVDSCommand.java +++ b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/CreateVmVDSCommand.java @@ -19,18 +19,13 @@ import org.ovirt.engine.core.vdsbroker.vdsbroker.CreateVmFromSysPrepVDSCommand; import org.ovirt.engine.core.vdsbroker.vdsbroker.VDSGenericException; -public class CreateVmVDSCommand<P extends CreateVmVDSCommandParameters> extends VdsIdVDSCommandBase<P> { +public class CreateVmVDSCommand<P extends CreateVmVDSCommandParameters> extends ManagingVmCommand<P> { public CreateVmVDSCommand(P parameters) { super(parameters); } @Override - protected void executeVdsIdCommand() { - if (_vdsManager == null) { - getVDSReturnValue().setSucceeded(false); - return; - } - + protected void executeVmCommand() { final VM vm = getParameters().getVm(); vm.setLastStartTime(new Date()); // if the VM is not suspended, it means that if there is 'hibernation volume' @@ -46,11 +41,11 @@ saveSetInitializedToDb(vm.getId()); vm.setInitialized(true); - vm.setRunOnVds(getVdsId()); + vm.setRunOnVds(getParameters().getVdsId()); if (clearHibernationVolume) { vm.setHibernationVolHandle(StringUtils.EMPTY); } - DbFacade.getInstance().getVmDynamicDao().update(vm.getDynamicData()); + vmManager.update(vm.getDynamicData()); } else { handleCommandResult(command); ResourceManager.getInstance().RemoveAsyncRunningVm(getParameters().getVmId()); @@ -72,7 +67,7 @@ // use answer file to run after sysprep. CreateVmVDSCommandParameters createVmFromSysPrepParam = new CreateVmVDSCommandParameters( - getVdsId(), + getParameters().getVdsId(), vm); createVmFromSysPrepParam.setSysPrepParams(getParameters().getSysPrepParams()); return new CreateVmFromSysPrepVDSCommand<CreateVmVDSCommandParameters>(createVmFromSysPrepParam); @@ -121,8 +116,8 @@ private void handleCommandResult(CreateVDSCommand<?> command) { if (!command.getVDSReturnValue().getSucceeded() && command.getVDSReturnValue().getExceptionObject() != null) { if (command.getVDSReturnValue().getExceptionObject() instanceof VDSGenericException) { - log.errorFormat("VDS::create Failed creating vm '{0}' in vds = {1} : {2} error = {3}", - getParameters().getVm().getName(), getVds().getId(), getVds().getName(), + log.errorFormat("VDS::create Failed creating vm '{0}' in vds = {1} error = {2}", + getParameters().getVm().getName(), getParameters().getVdsId(), command.getVDSReturnValue().getExceptionString()); getVDSReturnValue().setReturnValue(VMStatus.Down); getVDSReturnValue().setSucceeded(false); diff --git a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/DestroyVmVDSCommand.java b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/DestroyVmVDSCommand.java index aebb925..42faf01 100644 --- a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/DestroyVmVDSCommand.java +++ b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/DestroyVmVDSCommand.java @@ -14,85 +14,81 @@ import org.ovirt.engine.core.utils.transaction.TransactionSupport; import org.ovirt.engine.core.vdsbroker.vdsbroker.DestroyVDSCommand; -public class DestroyVmVDSCommand<P extends DestroyVmVDSCommandParameters> extends VdsIdVDSCommandBase<P> { +public class DestroyVmVDSCommand<P extends DestroyVmVDSCommandParameters> extends ManagingVmCommand<P> { public DestroyVmVDSCommand(P parameters) { super(parameters); } @Override - protected void executeVdsIdCommand() { + protected void executeVmCommand() { - if (_vdsManager != null) { + final DestroyVmVDSCommandParameters parameters = getParameters(); + ResourceManager.getInstance().RemoveAsyncRunningVm(parameters.getVmId()); - final DestroyVmVDSCommandParameters parameters = getParameters(); - ResourceManager.getInstance().RemoveAsyncRunningVm(parameters.getVmId()); + final VM curVm = DbFacade.getInstance().getVmDao().get(parameters.getVmId()); + curVm.setInterfaces(DbFacade.getInstance().getVmNetworkInterfaceDao().getAllForVm(curVm.getId())); - final VM curVm = DbFacade.getInstance().getVmDao().get(parameters.getVmId()); - curVm.setInterfaces(DbFacade.getInstance().getVmNetworkInterfaceDao().getAllForVm(curVm.getId())); + DestroyVDSCommand<DestroyVmVDSCommandParameters> vdsBrokerCommand = + new DestroyVDSCommand<DestroyVmVDSCommandParameters>(parameters); + vdsBrokerCommand.execute(); + if (vdsBrokerCommand.getVDSReturnValue().getSucceeded()) { + if (curVm.getStatus() == VMStatus.Down) { + getVDSReturnValue().setReturnValue(VMStatus.Down); + } - DestroyVDSCommand<DestroyVmVDSCommandParameters> vdsBrokerCommand = - new DestroyVDSCommand<DestroyVmVDSCommandParameters>(parameters); - vdsBrokerCommand.execute(); - if (vdsBrokerCommand.getVDSReturnValue().getSucceeded()) { - if (curVm.getStatus() == VMStatus.Down) { - getVDSReturnValue().setReturnValue(VMStatus.Down); - } + changeStatus(parameters, curVm); - changeStatus(parameters, curVm); + TransactionSupport.executeInNewTransaction(new TransactionMethod<Void>() { + @Override + public Void runInTransaction() { - TransactionSupport.executeInNewTransaction(new TransactionMethod<Void>() { - @Override - public Void runInTransaction() { - - curVm.guestLogoutTimeTreatmentAfterDestroy(); - curVm.setStopReason(getParameters().getReason()); - // SaveVmDynamicToDBThreaded(curVm); - DbFacade.getInstance().getVmDynamicDao().update(curVm.getDynamicData()); - DbFacade.getInstance().getVmStatisticsDao().update(curVm.getStatisticsData()); - List<VmNetworkInterface> interfaces = curVm.getInterfaces(); - if (interfaces != null && interfaces.size() > 0) { - for (VmNetworkInterface ifc : interfaces) { - VmNetworkStatistics stats = ifc.getStatistics(); - DbFacade.getInstance().getVmNetworkStatisticsDao().update(stats); - } + curVm.guestLogoutTimeTreatmentAfterDestroy(); + curVm.setStopReason(getParameters().getReason()); + // SaveVmDynamicToDBThreaded(curVm); + vmManager.update(curVm.getDynamicData()); + vmManager.update(curVm.getStatisticsData()); + List<VmNetworkInterface> interfaces = curVm.getInterfaces(); + if (interfaces != null && interfaces.size() > 0) { + for (VmNetworkInterface ifc : interfaces) { + VmNetworkStatistics stats = ifc.getStatistics(); + vmManager.update(stats); } + } + synchronized (ResourceManager.getInstance().GetVdsManager(parameters.getVdsId()).getLockObj()) { DbFacade.getInstance() .getVdsDynamicDao() - .updatePartialVdsDynamicCalc(getVdsId(), 0, 0, 0, + .updatePartialVdsDynamicCalc(getParameters().getVdsId(), 0, 0, 0, -curVm.getVmMemSizeMb(), -curVm.getNumOfCpus()); - return null; } - }); - - // if using stop then call to ProcessOnVmStop because - // will not be called from UpdateRunTimeInfo - if (!parameters.getGracefully()) { - onVmStop(curVm); + return null; } + }); - getVDSReturnValue().setReturnValue(curVm.getStatus()); - } else if (vdsBrokerCommand.getVDSReturnValue().getExceptionObject() != null) { - log.errorFormat("VDS::destroy Failed destroying vm '{0}' in vds = {1} : {2}, error = {3}", - parameters.getVmId(), - getVds().getId(), - getVds().getName(), - vdsBrokerCommand - .getVDSReturnValue().getExceptionString()); - getVDSReturnValue().setSucceeded(false); - getVDSReturnValue().setExceptionString(vdsBrokerCommand.getVDSReturnValue() - .getExceptionString()); - getVDSReturnValue().setExceptionObject(vdsBrokerCommand.getVDSReturnValue() - .getExceptionObject()); - getVDSReturnValue().setVdsError(vdsBrokerCommand.getVDSReturnValue().getVdsError()); + // if using stop then call to ProcessOnVmStop because + // will not be called from UpdateRunTimeInfo + if (!parameters.getGracefully()) { + onVmStop(curVm); } - } else { + + getVDSReturnValue().setReturnValue(curVm.getStatus()); + } else if (vdsBrokerCommand.getVDSReturnValue().getExceptionObject() != null) { + log.errorFormat("VDS::destroy Failed destroying vm '{0}' in vds = {1} , error = {2}", + parameters.getVmId(), + getParameters().getVdsId(), + vdsBrokerCommand + .getVDSReturnValue().getExceptionString()); getVDSReturnValue().setSucceeded(false); + getVDSReturnValue().setExceptionString(vdsBrokerCommand.getVDSReturnValue() + .getExceptionString()); + getVDSReturnValue().setExceptionObject(vdsBrokerCommand.getVDSReturnValue() + .getExceptionObject()); + getVDSReturnValue().setVdsError(vdsBrokerCommand.getVDSReturnValue().getVdsError()); } } private void changeStatus(DestroyVmVDSCommandParameters parameters, VM curVm) { // do the state transition only if that VM is really running on SRC - if (getVdsId().equals(curVm.getRunOnVds())) { + if (getParameters().getVdsId().equals(curVm.getRunOnVds())) { ResourceManager.getInstance().InternalSetVmStatus(curVm, parameters.getGracefully() ? VMStatus.PoweringDown : VMStatus.Down); } diff --git a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/HibernateVDSCommand.java b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/HibernateVDSCommand.java index e852546..ee379bc 100644 --- a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/HibernateVDSCommand.java +++ b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/HibernateVDSCommand.java @@ -1,35 +1,25 @@ package org.ovirt.engine.core.vdsbroker; -import org.ovirt.engine.core.common.businessentities.VMStatus; -import org.ovirt.engine.core.common.businessentities.VmDynamic; import org.ovirt.engine.core.common.vdscommands.HibernateVDSCommandParameters; import org.ovirt.engine.core.common.vdscommands.VDSReturnValue; -import org.ovirt.engine.core.dal.dbbroker.DbFacade; -import org.ovirt.engine.core.utils.transaction.TransactionMethod; -import org.ovirt.engine.core.utils.transaction.TransactionSupport; import org.ovirt.engine.core.vdsbroker.vdsbroker.HibernateBrokerVDSCommand; -public class HibernateVDSCommand<P extends HibernateVDSCommandParameters> extends VdsIdVDSCommandBase<P> { +public class HibernateVDSCommand<P extends HibernateVDSCommandParameters> extends ManagingVmCommand<P> { public HibernateVDSCommand(P parameters) { super(parameters); } @Override - protected void executeVdsIdCommand() { - if (_vdsManager == null) { - getVDSReturnValue().setSucceeded(false); - return; - } - + protected void executeVmCommand() { VDSReturnValue retVal = runHibernateBrokerVDSCommand(); if (retVal.getSucceeded()) { - changeVmStatusToSavingState(); + vmManager.succededToHibernate(); getVDSReturnValue().setSucceeded(true); } else { - log.errorFormat("Failed to hibernate vm '{0}' in vds = {1} : {2}, error = {3}", - getParameters().getVmId(), getVds().getId(), getVds().getName(), retVal.getExceptionString()); + log.errorFormat("Failed to hibernate vm '{0}' in vds = {1} : error = {2}", + getParameters().getVmId(), getParameters().getVdsId(), retVal.getExceptionString()); getVDSReturnValue().setSucceeded(false); getVDSReturnValue().setExceptionString(retVal.getExceptionString()); getVDSReturnValue().setExceptionObject(retVal.getExceptionObject()); @@ -42,18 +32,5 @@ new HibernateBrokerVDSCommand<HibernateVDSCommandParameters>(getParameters()); command.execute(); return command.getVDSReturnValue(); - } - - private void changeVmStatusToSavingState() { - TransactionSupport.executeInNewTransaction( - new TransactionMethod<Object>() { - @Override - public Object runInTransaction() { - VmDynamic vmDynamic = DbFacade.getInstance().getVmDynamicDao().get(getParameters().getVmId()); - vmDynamic.setStatus(VMStatus.SavingState); - _vdsManager.updateVmDynamic(vmDynamic); - return null; - } - }); } } diff --git a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/HostMonitoring.java b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/HostMonitoring.java index 048f659..a270d2f 100644 --- a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/HostMonitoring.java +++ b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/HostMonitoring.java @@ -57,7 +57,6 @@ private boolean saveVdsStatistics; private boolean processHardwareCapsNeeded; private boolean refreshedCapabilities = false; - private VmsMonitoring vmsMonitoring; private static Map<Guid, Long> hostDownTimes = new HashMap<>(); private static final Log log = LogFactory.getLog(HostMonitoring.class); @@ -67,7 +66,6 @@ this.vds = vds; firstStatus = vds.getStatus(); this.monitoringStrategy = monitoringStrategy; - vmsMonitoring = new VmsMonitoring(vdsManager, vds); } public void refresh() { @@ -123,7 +121,6 @@ saveVdsDynamic = true; } beforeFirstRefreshTreatment(isVdsUpOrGoingToMaintenance); - vmsMonitoring.refreshVmStats(); updateVirtualMemAndCpu(); } catch (VDSRecoveringException e) { // if PreparingForMaintenance and vds is in install failed keep to @@ -184,8 +181,6 @@ saveCpuStatisticsDataToDb(); saveNumaStatisticsDataToDb(); } - - vmsMonitoring.saveVmsToDb(); } private void saveCpuStatisticsDataToDb() { @@ -441,8 +436,6 @@ : "unknown"); } } - vmsMonitoring.afterVMsRefreshTreatment(); - } catch (IRSErrorException ex) { logFailureMessage("ResourceManager::RerunFailedCommand:", ex); if (log.isDebugEnabled()) { @@ -732,12 +725,12 @@ } private void updateVirtualMemAndCpu() { - if (vmsMonitoring.getMemCommited() != vds.getMemCommited()) { - vds.setMemCommited(vmsMonitoring.getMemCommited()); + if (vdsManager.getMemCommited() != vds.getMemCommited()) { + vds.setMemCommited(vdsManager.getMemCommited()); saveVdsDynamic = true; } - if (vmsMonitoring.getVmsCoresCount() != vds.getVmsCoresCount()) { - vds.setVmsCoresCount(vmsMonitoring.getVmsCoresCount()); + if (vdsManager.getVmsCoresCount() != vds.getVmsCoresCount()) { + vds.setVmsCoresCount(vdsManager.getVmsCoresCount()); saveVdsDynamic = true; } } diff --git a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/ManagingVmCommand.java b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/ManagingVmCommand.java new file mode 100644 index 0000000..ea47acd --- /dev/null +++ b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/ManagingVmCommand.java @@ -0,0 +1,24 @@ +package org.ovirt.engine.core.vdsbroker; + +import org.ovirt.engine.core.common.vdscommands.VdsAndVmIDVDSParametersBase; + +public abstract class ManagingVmCommand<P extends VdsAndVmIDVDSParametersBase> extends VDSCommandBase<P> { + + protected final VmManager vmManager; + + public ManagingVmCommand(P parameters) { + super(parameters); + vmManager = ResourceManager.getInstance().getVmManager(parameters.getVmId()); + } + + protected void executeVDSCommand() { + try { + vmManager.lock(); + executeVmCommand(); + } finally { + vmManager.unlock(); + } + } + + protected abstract void executeVmCommand(); +} diff --git a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/MigrateVDSCommand.java b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/MigrateVDSCommand.java index ec0bc0d..dbbe963 100644 --- a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/MigrateVDSCommand.java +++ b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/MigrateVDSCommand.java @@ -11,7 +11,7 @@ import org.ovirt.engine.core.utils.log.LogFactory; import org.ovirt.engine.core.vdsbroker.vdsbroker.MigrateBrokerVDSCommand; -public class MigrateVDSCommand<P extends MigrateVDSCommandParameters> extends VdsIdVDSCommandBase<P> { +public class MigrateVDSCommand<P extends MigrateVDSCommandParameters> extends ManagingVmCommand<P> { private static final Log log = LogFactory.getLog(MigrateVDSCommand.class); @@ -20,12 +20,7 @@ } @Override - protected void executeVdsIdCommand() { - if (_vdsManager == null) { - getVDSReturnValue().setSucceeded(false); - return; - } - + protected void executeVmCommand() { MigrateBrokerVDSCommand<?> command = new MigrateBrokerVDSCommand<>(getParameters()); command.execute(); VDSReturnValue vdsReturnValue = command.getVDSReturnValue(); @@ -34,11 +29,9 @@ if (vdsReturnValue.getSucceeded()) { ResourceManager.getInstance().AddAsyncRunningVm(getParameters().getVmId()); - ResourceManager.getInstance().InternalSetVmStatus(vm, VMStatus.MigratingFrom); vm.setMigratingToVds(getParameters().getDstVdsId()); - getVmDynamicDAO().update(vm.getDynamicData()); - + vmManager.update(vm.getDynamicData()); getVDSReturnValue().setReturnValue(VMStatus.MigratingFrom); } else { log.error("Failed Vm migration"); diff --git a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/ResourceManager.java b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/ResourceManager.java index 79a239c..27c55c1 100644 --- a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/ResourceManager.java +++ b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/ResourceManager.java @@ -52,6 +52,7 @@ private final Map<Guid, VdsManager> vdsManagersDict = new ConcurrentHashMap<>(); private final Set<Guid> asyncRunningVms = Collections.newSetFromMap(new ConcurrentHashMap<Guid, Boolean>()); + private ConcurrentHashMap<Guid, VmManager> vmManagers; private static final String VDSCommandPrefix = "VDSCommand"; @@ -424,4 +425,12 @@ return null; } + + public VmManager getVmManager(Guid vmId) { + return vmManagers.putIfAbsent(vmId, new VmManager(vmId)); + } + + public void onVmDelete(Guid vmId) { + vmManagers.remove(vmId); + } } diff --git a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/ResumeVDSCommand.java b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/ResumeVDSCommand.java index 55514e4..1a8ed89 100644 --- a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/ResumeVDSCommand.java +++ b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/ResumeVDSCommand.java @@ -7,35 +7,31 @@ import org.ovirt.engine.core.utils.log.LogFactory; import org.ovirt.engine.core.vdsbroker.vdsbroker.ResumeBrokerVDSCommand; -public class ResumeVDSCommand<P extends ResumeVDSCommandParameters> extends VdsIdVDSCommandBase<P> { +public class ResumeVDSCommand<P extends ResumeVDSCommandParameters> extends ManagingVmCommand<P> { public ResumeVDSCommand(P parameters) { super(parameters); } @Override - protected void executeVdsIdCommand() { + protected void executeVmCommand() { ResumeVDSCommandParameters parameters = getParameters(); - if (_vdsManager != null) { - VMStatus retval = VMStatus.Unknown; - ResumeBrokerVDSCommand<VdsAndVmIDVDSParametersBase> command = - new ResumeBrokerVDSCommand<VdsAndVmIDVDSParametersBase>(parameters); - command.execute(); - if (command.getVDSReturnValue().getSucceeded()) { - retval = VMStatus.PoweringUp; - ResourceManager.getInstance().AddAsyncRunningVm(parameters.getVmId()); - } else if (command.getVDSReturnValue().getExceptionObject() != null) { - log.errorFormat("VDS::pause Failed resume vm '{0}' in vds = {1} : {2}, error = {3}", parameters - .getVmId(), getVds().getId(), getVds().getName(), command.getVDSReturnValue() - .getExceptionString()); - getVDSReturnValue().setSucceeded(false); - getVDSReturnValue().setExceptionString(command.getVDSReturnValue().getExceptionString()); - getVDSReturnValue().setExceptionObject(command.getVDSReturnValue().getExceptionObject()); - getVDSReturnValue().setVdsError(command.getVDSReturnValue().getVdsError()); - } - getVDSReturnValue().setReturnValue(retval); - } else { + VMStatus retval = VMStatus.Unknown; + ResumeBrokerVDSCommand<VdsAndVmIDVDSParametersBase> command = + new ResumeBrokerVDSCommand<VdsAndVmIDVDSParametersBase>(parameters); + command.execute(); + if (command.getVDSReturnValue().getSucceeded()) { + retval = VMStatus.PoweringUp; + ResourceManager.getInstance().AddAsyncRunningVm(parameters.getVmId()); + } else if (command.getVDSReturnValue().getExceptionObject() != null) { + log.errorFormat("VDS::pause Failed resume vm '{0}' in vds = {1} error = {2}", parameters + .getVmId(), getParameters().getVdsId(), command.getVDSReturnValue() + .getExceptionString()); getVDSReturnValue().setSucceeded(false); + getVDSReturnValue().setExceptionString(command.getVDSReturnValue().getExceptionString()); + getVDSReturnValue().setExceptionObject(command.getVDSReturnValue().getExceptionObject()); + getVDSReturnValue().setVdsError(command.getVDSReturnValue().getVdsError()); } + getVDSReturnValue().setReturnValue(retval); } private static final Log log = LogFactory.getLog(ResumeVDSCommand.class); diff --git a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VdsManager.java b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VdsManager.java index 0661c72..91ea671 100644 --- a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VdsManager.java +++ b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VdsManager.java @@ -71,6 +71,7 @@ private long updateStartTime; private long nextMaintenanceAttemptTime; private String onTimerJobId; + private String vmsMonitoringJobId; private int refreshIteration = 1; private boolean isSetNonOperationalExecuted; private MonitoringStrategy monitoringStrategy; @@ -79,6 +80,8 @@ private IVdsServer vdsProxy; private boolean mBeforeFirstRefresh = true; private HostMonitoring hostMonitoring; + private AtomicInteger memCommited; + private AtomicInteger vmsCoresCount; private VdsManager(VDS vds) { log.info("Entered VdsManager constructor"); @@ -139,6 +142,16 @@ sched.scheduleAFixedDelayJob( this, "onTimer", + new Class[0], + new Object[0], + refreshRate, + refreshRate, + TimeUnit.MILLISECONDS); + + vmsMonitoringJobId = + sched.scheduleAFixedDelayJob( + this, + "vmsMonitoring", new Class[0], new Object[0], refreshRate, @@ -238,6 +251,11 @@ LockManagerFactory.getLockManager().releaseLock(monitoringLock); } } + } + + @OnTimerMethodAnnotation("vmsMonitoring") + public void vmsMonitoring() { + new VmsMonitoring(this, vds).begin(); } private void logFailureMessage(RuntimeException ex) { @@ -660,9 +678,15 @@ return true; } + protected void updateMetrics(int memCommited, int vmsCoresCount) { + this.memCommited.set(memCommited); + this.vmsCoresCount.set(vmsCoresCount); + } + public void dispose() { log.info("vdsManager::disposing"); SchedulerUtilQuartzImpl.getInstance().deleteJob(onTimerJobId); + SchedulerUtilQuartzImpl.getInstance().deleteJob(vmsMonitoringJobId); XmlRpcUtils.shutDownConnection(((VdsServerWrapper) vdsProxy).getHttpClient()); } @@ -791,4 +815,12 @@ public void setbeforeFirstRefresh(boolean value) { mBeforeFirstRefresh = value; } + + public int getMemCommited() { + return this.memCommited.get(); + } + + public int getVmsCoresCount() { + return this.vmsCoresCount.get(); + } } diff --git a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VmManager.java b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VmManager.java new file mode 100644 index 0000000..1569ca0 --- /dev/null +++ b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VmManager.java @@ -0,0 +1,79 @@ +package org.ovirt.engine.core.vdsbroker; + +import org.ovirt.engine.core.common.businessentities.VMStatus; +import org.ovirt.engine.core.common.businessentities.VmDynamic; +import org.ovirt.engine.core.common.businessentities.VmStatistics; +import org.ovirt.engine.core.common.businessentities.network.VmNetworkStatistics; +import org.ovirt.engine.core.compat.Guid; +import org.ovirt.engine.core.dal.dbbroker.DbFacade; +import org.ovirt.engine.core.dao.VmDynamicDAO; +import org.ovirt.engine.core.dao.VmStatisticsDAO; +import org.ovirt.engine.core.dao.network.VmNetworkStatisticsDao; +import org.ovirt.engine.core.utils.transaction.TransactionMethod; +import org.ovirt.engine.core.utils.transaction.TransactionSupport; + +import java.util.concurrent.locks.ReentrantLock; + +public class VmManager { + + private Guid id; + private final ReentrantLock lock = new ReentrantLock(); + + public VmManager(Guid id) { + this.id = id; + } + + public void succededToHibernate() { + TransactionSupport.executeInNewTransaction( + new TransactionMethod<Object>() { + @Override + public Object runInTransaction() { + VmDynamic vmDynamic = db().getVmDynamicDao().get(id); + vmDynamic.setStatus(VMStatus.SavingState); + update(vmDynamic); + return null; + } + } + ); + } + + public void lock() { + lock.lock(); + } + + public void unlock() { + lock.unlock(); + } + + public boolean trylock() { + return lock.tryLock(); + } + + public void update(VmDynamic dynamic) { + getVmDynamicDao().update(dynamic); + } + + public void update(VmStatistics statistics) { + getVmStatisticsDao().update(statistics); + } + + public void update(VmNetworkStatistics networkStatistics) { + getVmNetworkStatisticsDao().update(networkStatistics); + } + + private VmDynamicDAO getVmDynamicDao() { + return db().getVmDynamicDao(); + } + + private VmStatisticsDAO getVmStatisticsDao() { + return db().getVmStatisticsDao(); + } + + private VmNetworkStatisticsDao getVmNetworkStatisticsDao() { + return db().getVmNetworkStatisticsDao(); + } + + protected DbFacade db() { + return DbFacade.getInstance(); + } +} diff --git a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VmsMonitoring.java b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VmsMonitoring.java index de38dfd..7ff8692 100644 --- a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VmsMonitoring.java +++ b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VmsMonitoring.java @@ -77,6 +77,7 @@ private VdsManager vdsManager; private final Map<Guid, VM> vmDict; private Map<Guid, VmInternalData> runningVms; + private Map<Guid, VmManager> vmManagers; private int memCommited; private int vmsCoresCount; @@ -123,15 +124,49 @@ this.vds = vds; this.vdsManager = vdsManager; this.vmDict = getDbFacade().getVmDao().getAllRunningByVds(vds.getId()); + vmManagers = new HashMap<>(vmDict.size()); // max size is the one's that in the db } - public void refreshVmStats() { + public void begin() { + try { + lockVmsManager(); + refreshVmStats(); + saveVmsToDb(); + afterVMsRefreshTreatment(); + vdsManager.updateMetrics(memCommited, vmsCoresCount); + } finally { + unlockVmsManager(); + } + + } + + private void lockVmsManager() { + for (Guid vmId : vmDict.keySet()) { + VmManager vmManager = ResourceManager.getInstance().getVmManager(vmId); + if (!vmManager.trylock()) { + // if we can't hold this vm lock than skip this monitoring cycle for it. + // so remove it from both vmDict and the list returned from vdsm + vmManagers.put(vmId, vmManager); + } + } + } + + private void unlockVmsManager() { + for (VmManager vmManager : vmManagers.values()) { + vmManager.unlock(); + } + } + + private void refreshVmStats() { log.debug("refresh VMs list entered"); if (fetchRunningVms()) { // refreshCommitedMemory must be called before we modify runningVms, because // we iterate over it there, assuming it is the same as it was received from VDSM refreshCommitedMemory(); + + filterVmsFromMonitoringCycle(); + List<Guid> staleRunningVms = checkVmsStatusChanged(); proceedWatchdogEvents(); @@ -161,13 +196,29 @@ updateLunDisks(); } + saveVmsToDb(); + } + + /** + * if we can't hold this VM lock we filter it out and + * so we don't try to detect state-transition and so on. + * - VMs which are anyway not exist in db should never be filtered out + * - metrics calculation like memCommited and vmsCoresCount should be calculated *before* + * this filtering. + */ + private void filterVmsFromMonitoringCycle() { + for (Guid vmId : runningVms.keySet()) { + if (!vmManagers.containsKey(vmId)) { + runningVms.remove(vmId); + } + } } /** * fetch running VMs and populate the internal structure. if we fail, handle the error * @return true if we could get vms otherwise false */ - public boolean fetchRunningVms() { + protected boolean fetchRunningVms() { VDSCommandType commandType = vdsManager.getRefreshStatistics() ? VDSCommandType.GetAllVmStats @@ -753,7 +804,7 @@ } } - void saveVmsToDb() { + private void saveVmsToDb() { getDbFacade().getVmDynamicDao().updateAllInBatch(vmDynamicToSave.values()); getDbFacade().getVmStatisticsDao().updateAllInBatch(vmStatisticsToSave.values()); @@ -773,7 +824,7 @@ getVdsEventListener().addExternallyManagedVms(externalVmsToAdd); } - void afterVMsRefreshTreatment() { + private void afterVMsRefreshTreatment() { // rerun all vms from rerun list for (Guid vm_guid : vmsToRerun) { log.errorFormat("Rerun vm {0}. Called from vds {1}", vm_guid, vds.getName()); @@ -1473,13 +1524,5 @@ protected IVdsEventListener getVdsEventListener() { return ResourceManager.getInstance().getEventListener(); - } - - public int getMemCommited() { - return memCommited; - } - - public int getVmsCoresCount() { - return vmsCoresCount; } } -- To view, visit http://gerrit.ovirt.org/28173 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I54c6091a3996c23a4b70c7ef89412d34f1b58e34 Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: master Gerrit-Owner: Roy Golan <[email protected]> _______________________________________________ Engine-patches mailing list [email protected] http://lists.ovirt.org/mailman/listinfo/engine-patches
