package org.ovirt.engine.core.bll; import java.util.Collections; import java.util.List; import org.ovirt.engine.core.common.AuditLogType; import org.ovirt.engine.core.common.action.MaintananceVdsParameters; import org.ovirt.engine.core.common.action.MigrateVmParameters; import org.ovirt.engine.core.common.action.StoragePoolParametersBase; import org.ovirt.engine.core.common.action.VdcActionType; import org.ovirt.engine.core.common.action.VdcReturnValueBase; import org.ovirt.engine.core.common.businessentities.MigrationSupport; import org.ovirt.engine.core.common.businessentities.StoragePoolStatus; import org.ovirt.engine.core.common.businessentities.VDS; import org.ovirt.engine.core.common.businessentities.VDSStatus; import org.ovirt.engine.core.common.businessentities.VM; import org.ovirt.engine.core.common.businessentities.VMStatus; import org.ovirt.engine.core.common.businessentities.VmsComparer; import org.ovirt.engine.core.common.vdscommands.DisconnectStoragePoolVDSCommandParameters; import org.ovirt.engine.core.common.vdscommands.SetVdsStatusVDSCommandParameters; import org.ovirt.engine.core.common.vdscommands.VDSCommandType; import org.ovirt.engine.core.compat.Guid; import org.ovirt.engine.core.compat.LogCompat; import org.ovirt.engine.core.compat.LogFactoryCompat; import org.ovirt.engine.core.compat.TransactionScopeOption; import org.ovirt.engine.core.dal.VdcBllMessages; import org.ovirt.engine.core.dal.dbbroker.DbFacade; import org.ovirt.engine.core.vdsbroker.irsbroker.IrsBrokerCommand; public class MaintananceVdsCommand<T extends MaintananceVdsParameters> extends VdsCommand<T> { private final boolean _isInternal; private List<VM> vms; public MaintananceVdsCommand(T parameters) { super(parameters); _isInternal = parameters.getIsInternal(); } @Override protected void executeCommand() { if (getVds().getstatus() == VDSStatus.Maintenance) { // nothing to do setSucceeded(true); } else { setSucceeded(MigrateAllVms()); /** * if non responsive move directly to maintenance */ if (getVds().getstatus() == VDSStatus.NonResponsive || getVds().getstatus() == VDSStatus.Problematic || getVds().getstatus() == VDSStatus.Down) { Backend.getInstance() .getResourceManager() .RunVdsCommand(VDSCommandType.SetVdsStatus, new SetVdsStatusVDSCommandParameters(getVdsId(), VDSStatus.Maintenance)); } } } protected void orderListOfRunningVmsOnVds(Guid vdsId) { vms = DbFacade.getInstance().getVmDAO().getAllRunningForVds(vdsId); Collections.sort(vms, Collections.reverseOrder(new VmsComparer())); } protected boolean MigrateAllVms() { return MigrateAllVms(false); } protected boolean MigrateAllVms(boolean HAOnly) { orderListOfRunningVmsOnVds(getVdsId()); boolean succeeded = true; for (VM vm : vms) { // if HAOnly is true check that vm is HA (auto_startup should be // true) if (vm.getstatus() != VMStatus.MigratingFrom && (!HAOnly || (HAOnly && vm.getauto_startup()))) { MigrateVmParameters tempVar = new MigrateVmParameters(false, vm.getvm_guid()); tempVar.setTransactionScopeOption(TransactionScopeOption.RequiresNew); VdcReturnValueBase result = Backend.getInstance().runInternalAction(VdcActionType.InternalMigrateVm, tempVar); if (!result.getCanDoAction() || !(((Boolean) result.getActionReturnValue()).booleanValue())) { succeeded = false; AppendCustomValue("failedVms", vm.getvm_name(), ","); log.errorFormat("ResourceManager::vdsMaintenance - Failed migrating desktop '{0}'", vm.getvm_name()); } } } return succeeded; } @Override protected boolean canDoAction() { return CanMaintananceVds(getVdsId(), getReturnValue().getCanDoActionMessages()); } @Override public AuditLogType getAuditLogTypeValue() { if (_isInternal) { if (getSucceeded()) { return AuditLogType.VDS_MAINTENANCE; } else { return AuditLogType.VDS_MAINTENANCE_FAILED; } } else { if (getSucceeded()) { return AuditLogType.USER_VDS_MAINTENANCE; } else { return AuditLogType.USER_VDS_MAINTENANCE_MIGRATION_FAILED; } } } public boolean CanMaintananceVds(Guid vdsId, java.util.ArrayList<String> reasons) { boolean returnValue = true; // VDS vds = ResourceManager.Instance.getVds(vdsId); VDS vds = DbFacade.getInstance().getVdsDAO().get(vdsId); // we can get here when vds status was set already to Maintenance if ((vds.getstatus() != VDSStatus.Maintenance) && (vds.getstatus() != VDSStatus.NonResponsive) && (vds.getstatus() != VDSStatus.Up) && (vds.getstatus() != VDSStatus.Error) && (vds.getstatus() != VDSStatus.PreparingForMaintenance) && (vds.getstatus() != VDSStatus.Down)) { returnValue = false; reasons.add(VdcBllMessages.VDS_CANNOT_MAINTENANCE_VDS_IS_NOT_OPERATIONAL.toString()); } orderListOfRunningVmsOnVds(vdsId); for (VM vm : vms) { if (vm.getMigrationSupport() != MigrationSupport.MIGRATABLE) { reasons.add(VdcBllMessages.VDS_CANNOT_MAINTENANCE_IT_INCLUDES_NON_MIGRATABLE_VM.toString()); return false; } } return returnValue; } public static void ProcessStorageOnVdsInactive(VDS vds) { // Clear the problematic timers since the VDS is in maintenance so it doesn't make sense to check it // anymore. IrsBrokerCommand.clearVdsFromCache(vds.getstorage_pool_id(), vds.getvds_id(), vds.getvds_name()); if (!vds.getstorage_pool_id().equals(Guid.Empty) && StoragePoolStatus.Uninitialized != DbFacade.getInstance() .getStoragePoolDAO() .get(vds.getstorage_pool_id()) .getstatus() && Backend .getInstance() .getResourceManager() .RunVdsCommand( VDSCommandType.DisconnectStoragePool, new DisconnectStoragePoolVDSCommandParameters(vds.getvds_id(), vds.getstorage_pool_id(), vds.getvds_spm_id())).getSucceeded()) { StoragePoolParametersBase tempVar = new StoragePoolParametersBase(vds.getstorage_pool_id()); tempVar.setVdsId(vds.getvds_id()); tempVar.setTransactionScopeOption(TransactionScopeOption.RequiresNew); Backend.getInstance().runInternalAction(VdcActionType.DisconnectHostFromStoragePoolServers, tempVar); } } private static LogCompat log = LogFactoryCompat.getLog(MaintananceVdsCommand.class); }