package org.ovirt.engine.core.bll; import java.util.ArrayList; import java.util.Collections; import java.util.List; import javax.inject.Inject; import org.ovirt.engine.core.bll.context.CommandContext; import org.ovirt.engine.core.common.AuditLogType; import org.ovirt.engine.core.common.action.ProcessDownVmParameters; import org.ovirt.engine.core.common.action.VdcActionType; import org.ovirt.engine.core.common.action.VdsActionParameters; 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.VmExitStatus; import org.ovirt.engine.core.common.businessentities.comparators.VmsComparer; import org.ovirt.engine.core.common.errors.EngineMessage; import org.ovirt.engine.core.common.vdscommands.SetVmStatusVDSCommandParameters; import org.ovirt.engine.core.common.vdscommands.UpdateVdsVMsClearedVDSCommandParameters; import org.ovirt.engine.core.common.vdscommands.VDSCommandType; import org.ovirt.engine.core.common.vdscommands.VDSReturnValue; import org.ovirt.engine.core.compat.Guid; import org.ovirt.engine.core.dao.VmDao; import org.ovirt.engine.core.dao.VmDynamicDao; @NonTransactiveCommandAttribute public class ClearNonResponsiveVdsVmsCommand<T extends VdsActionParameters> extends VdsCommand<T> { @Inject private HaAutoStartVmsRunner haAutoStartVmsRunner; @Inject private VmDynamicDao vmDynamicDao; @Inject private VmDao vmDao; /** * Constructor for command creation when compensation is applied on startup */ protected ClearNonResponsiveVdsVmsCommand(Guid commandId) { super(commandId); } public ClearNonResponsiveVdsVmsCommand(T parameters, CommandContext commandContext) { super(parameters, commandContext); } @Override public AuditLogType getAuditLogTypeValue() { return getSucceeded() ? AuditLogType.USER_CLEAR_UNKNOWN_VMS : AuditLogType.USER_FAILED_CLEAR_UNKNOWN_VMS; } @Override protected void executeCommand() { List<VM> vms = vmDao.getAllRunningForVds(getVdsId()); Collections.sort(vms, Collections.reverseOrder(new VmsComparer())); List<Guid> autoStartVmIdsToRerun = new ArrayList<>(); for (VM vm : vms) { if (vm.isAutoStartup()) { autoStartVmIdsToRerun.add(vm.getId()); } VDSReturnValue returnValue = runVdsCommand(VDSCommandType.SetVmStatus, new SetVmStatusVDSCommandParameters(vm.getId(), VMStatus.Down, VmExitStatus.Error)); // Write that this VM was shut down by host reboot or manual fence if (returnValue != null && returnValue.getSucceeded()) { logSettingVmToDown(vm); } runInternalActionWithTasksContext(VdcActionType.ProcessDownVm, new ProcessDownVmParameters(vm.getId(), true)); } runVdsCommand(VDSCommandType.UpdateVdsVMsCleared, new UpdateVdsVMsClearedVDSCommandParameters(getVdsId())); if (!autoStartVmIdsToRerun.isEmpty()) { haAutoStartVmsRunner.addVmsToRun(autoStartVmIdsToRerun); } setSucceeded(true); } @Override protected boolean validate() { if (getVds() == null) { return failValidation(EngineMessage.VDS_INVALID_SERVER_ID); } if (hasVMs() && getVds().getStatus() != VDSStatus.NonResponsive && getVds().getStatus() != VDSStatus.Reboot && getVds().getStatus() != VDSStatus.Kdumping) { return failValidation(EngineMessage.VDS_CANNOT_CLEAR_VMS_WRONG_STATUS); } return true; } private boolean hasVMs() { return !vmDynamicDao.getAllRunningForVds(getVdsId()).isEmpty(); } }