Search in sources :

Example 1 with UnknownVM

use of com.cloud.ha.Investigator.UnknownVM in project cloudstack by apache.

the class HighAvailabilityManagerImpl method restart.

protected Long restart(final HaWorkVO work) {
    List<HaWorkVO> items = _haDao.listFutureHaWorkForVm(work.getInstanceId(), work.getId());
    if (items.size() > 0) {
        StringBuilder str = new StringBuilder("Cancelling this work item because newer ones have been scheduled.  Work Ids = [");
        for (HaWorkVO item : items) {
            str.append(item.getId()).append(", ");
        }
        str.delete(str.length() - 2, str.length()).append("]");
        s_logger.info(str.toString());
        return null;
    }
    items = _haDao.listRunningHaWorkForVm(work.getInstanceId());
    if (items.size() > 0) {
        StringBuilder str = new StringBuilder("Waiting because there's HA work being executed on an item currently.  Work Ids =[");
        for (HaWorkVO item : items) {
            str.append(item.getId()).append(", ");
        }
        str.delete(str.length() - 2, str.length()).append("]");
        s_logger.info(str.toString());
        return (System.currentTimeMillis() >> 10) + _investigateRetryInterval;
    }
    long vmId = work.getInstanceId();
    VirtualMachine vm = _itMgr.findById(work.getInstanceId());
    if (vm == null) {
        s_logger.info("Unable to find vm: " + vmId);
        return null;
    }
    s_logger.info("HA on " + vm);
    if (vm.getState() != work.getPreviousState() || vm.getUpdated() != work.getUpdateTime()) {
        s_logger.info("VM " + vm + " has been changed.  Current State = " + vm.getState() + " Previous State = " + work.getPreviousState() + " last updated = " + vm.getUpdated() + " previous updated = " + work.getUpdateTime());
        return null;
    }
    AlertManager.AlertType alertType = AlertManager.AlertType.ALERT_TYPE_USERVM;
    if (VirtualMachine.Type.DomainRouter.equals(vm.getType())) {
        alertType = AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER;
    } else if (VirtualMachine.Type.ConsoleProxy.equals(vm.getType())) {
        alertType = AlertManager.AlertType.ALERT_TYPE_CONSOLE_PROXY;
    } else if (VirtualMachine.Type.SecondaryStorageVm.equals(vm.getType())) {
        alertType = AlertManager.AlertType.ALERT_TYPE_SSVM;
    }
    HostVO host = _hostDao.findById(work.getHostId());
    boolean isHostRemoved = false;
    if (host == null) {
        host = _hostDao.findByIdIncludingRemoved(work.getHostId());
        if (host != null) {
            s_logger.debug("VM " + vm.toString() + " is now no longer on host " + work.getHostId() + " as the host is removed");
            isHostRemoved = true;
        }
    }
    DataCenterVO dcVO = _dcDao.findById(host.getDataCenterId());
    HostPodVO podVO = _podDao.findById(host.getPodId());
    String hostDesc = "name: " + host.getName() + "(id:" + host.getId() + "), availability zone: " + dcVO.getName() + ", pod: " + podVO.getName();
    Boolean alive = null;
    if (work.getStep() == Step.Investigating) {
        if (!isHostRemoved) {
            if (vm.getHostId() == null || vm.getHostId() != work.getHostId()) {
                s_logger.info("VM " + vm.toString() + " is now no longer on host " + work.getHostId());
                return null;
            }
            Investigator investigator = null;
            for (Investigator it : investigators) {
                investigator = it;
                try {
                    alive = investigator.isVmAlive(vm, host);
                    s_logger.info(investigator.getName() + " found " + vm + " to be alive? " + alive);
                    break;
                } catch (UnknownVM e) {
                    s_logger.info(investigator.getName() + " could not find " + vm);
                }
            }
            boolean fenced = false;
            if (alive == null) {
                s_logger.debug("Fencing off VM that we don't know the state of");
                for (FenceBuilder fb : fenceBuilders) {
                    Boolean result = fb.fenceOff(vm, host);
                    s_logger.info("Fencer " + fb.getName() + " returned " + result);
                    if (result != null && result) {
                        fenced = true;
                        break;
                    }
                }
            } else if (!alive) {
                fenced = true;
            } else {
                s_logger.debug("VM " + vm.getInstanceName() + " is found to be alive by " + investigator.getName());
                if (host.getStatus() == Status.Up) {
                    s_logger.info(vm + " is alive and host is up. No need to restart it.");
                    return null;
                } else {
                    s_logger.debug("Rescheduling because the host is not up but the vm is alive");
                    return (System.currentTimeMillis() >> 10) + _investigateRetryInterval;
                }
            }
            if (!fenced) {
                s_logger.debug("We were unable to fence off the VM " + vm);
                _alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodIdToDeployIn(), "Unable to restart " + vm.getHostName() + " which was running on host " + hostDesc, "Insufficient capacity to restart VM, name: " + vm.getHostName() + ", id: " + vmId + " which was running on host " + hostDesc);
                return (System.currentTimeMillis() >> 10) + _restartRetryInterval;
            }
            try {
                _itMgr.advanceStop(vm.getUuid(), true);
            } catch (ResourceUnavailableException e) {
                assert false : "How do we hit this when force is true?";
                throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
            } catch (OperationTimedoutException e) {
                assert false : "How do we hit this when force is true?";
                throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
            } catch (ConcurrentOperationException e) {
                assert false : "How do we hit this when force is true?";
                throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
            }
            work.setStep(Step.Scheduled);
            _haDao.update(work.getId(), work);
        } else {
            s_logger.debug("How come that HA step is Investigating and the host is removed? Calling forced Stop on Vm anyways");
            try {
                _itMgr.advanceStop(vm.getUuid(), true);
            } catch (ResourceUnavailableException e) {
                assert false : "How do we hit this when force is true?";
                throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
            } catch (OperationTimedoutException e) {
                assert false : "How do we hit this when force is true?";
                throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
            } catch (ConcurrentOperationException e) {
                assert false : "How do we hit this when force is true?";
                throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
            }
        }
    }
    vm = _itMgr.findById(vm.getId());
    if (!_forceHA && !vm.isHaEnabled()) {
        if (s_logger.isDebugEnabled()) {
            s_logger.debug("VM is not HA enabled so we're done.");
        }
        // VM doesn't require HA
        return null;
    }
    if ((host == null || host.getRemoved() != null || host.getState() != Status.Up) && !volumeMgr.canVmRestartOnAnotherServer(vm.getId())) {
        if (s_logger.isDebugEnabled()) {
            s_logger.debug("VM can not restart on another server.");
        }
        return null;
    }
    try {
        HashMap<VirtualMachineProfile.Param, Object> params = new HashMap<VirtualMachineProfile.Param, Object>();
        if (_haTag != null) {
            params.put(VirtualMachineProfile.Param.HaTag, _haTag);
        }
        WorkType wt = work.getWorkType();
        if (wt.equals(WorkType.HA)) {
            params.put(VirtualMachineProfile.Param.HaOperation, true);
        }
        try {
            // First try starting the vm with its original planner, if it doesn't succeed send HAPlanner as its an emergency.
            _itMgr.advanceStart(vm.getUuid(), params, null);
        } catch (InsufficientCapacityException e) {
            s_logger.warn("Failed to deploy vm " + vmId + " with original planner, sending HAPlanner");
            _itMgr.advanceStart(vm.getUuid(), params, _haPlanners.get(0));
        }
        VMInstanceVO started = _instanceDao.findById(vm.getId());
        if (started != null && started.getState() == VirtualMachine.State.Running) {
            s_logger.info("VM is now restarted: " + vmId + " on " + started.getHostId());
            return null;
        }
        if (s_logger.isDebugEnabled()) {
            s_logger.debug("Rescheduling VM " + vm.toString() + " to try again in " + _restartRetryInterval);
        }
    } catch (final InsufficientCapacityException e) {
        s_logger.warn("Unable to restart " + vm.toString() + " due to " + e.getMessage());
        _alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodIdToDeployIn(), "Unable to restart " + vm.getHostName() + " which was running on host " + hostDesc, "Insufficient capacity to restart VM, name: " + vm.getHostName() + ", id: " + vmId + " which was running on host " + hostDesc);
    } catch (final ResourceUnavailableException e) {
        s_logger.warn("Unable to restart " + vm.toString() + " due to " + e.getMessage());
        _alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodIdToDeployIn(), "Unable to restart " + vm.getHostName() + " which was running on host " + hostDesc, "The Storage is unavailable for trying to restart VM, name: " + vm.getHostName() + ", id: " + vmId + " which was running on host " + hostDesc);
    } catch (ConcurrentOperationException e) {
        s_logger.warn("Unable to restart " + vm.toString() + " due to " + e.getMessage());
        _alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodIdToDeployIn(), "Unable to restart " + vm.getHostName() + " which was running on host " + hostDesc, "The Storage is unavailable for trying to restart VM, name: " + vm.getHostName() + ", id: " + vmId + " which was running on host " + hostDesc);
    } catch (OperationTimedoutException e) {
        s_logger.warn("Unable to restart " + vm.toString() + " due to " + e.getMessage());
        _alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodIdToDeployIn(), "Unable to restart " + vm.getHostName() + " which was running on host " + hostDesc, "The Storage is unavailable for trying to restart VM, name: " + vm.getHostName() + ", id: " + vmId + " which was running on host " + hostDesc);
    }
    vm = _itMgr.findById(vm.getId());
    work.setUpdateTime(vm.getUpdated());
    work.setPreviousState(vm.getState());
    return (System.currentTimeMillis() >> 10) + _restartRetryInterval;
}
Also used : AlertManager(com.cloud.alert.AlertManager) OperationTimedoutException(com.cloud.exception.OperationTimedoutException) HashMap(java.util.HashMap) HostPodVO(com.cloud.dc.HostPodVO) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) UnknownVM(com.cloud.ha.Investigator.UnknownVM) InsufficientCapacityException(com.cloud.exception.InsufficientCapacityException) DataCenterVO(com.cloud.dc.DataCenterVO) VMInstanceVO(com.cloud.vm.VMInstanceVO) ConcurrentOperationException(com.cloud.exception.ConcurrentOperationException) HostVO(com.cloud.host.HostVO) ResourceUnavailableException(com.cloud.exception.ResourceUnavailableException) VirtualMachineProfile(com.cloud.vm.VirtualMachineProfile) VirtualMachine(com.cloud.vm.VirtualMachine)

Aggregations

AlertManager (com.cloud.alert.AlertManager)1 DataCenterVO (com.cloud.dc.DataCenterVO)1 HostPodVO (com.cloud.dc.HostPodVO)1 ConcurrentOperationException (com.cloud.exception.ConcurrentOperationException)1 InsufficientCapacityException (com.cloud.exception.InsufficientCapacityException)1 OperationTimedoutException (com.cloud.exception.OperationTimedoutException)1 ResourceUnavailableException (com.cloud.exception.ResourceUnavailableException)1 UnknownVM (com.cloud.ha.Investigator.UnknownVM)1 HostVO (com.cloud.host.HostVO)1 CloudRuntimeException (com.cloud.utils.exception.CloudRuntimeException)1 VMInstanceVO (com.cloud.vm.VMInstanceVO)1 VirtualMachine (com.cloud.vm.VirtualMachine)1 VirtualMachineProfile (com.cloud.vm.VirtualMachineProfile)1 HashMap (java.util.HashMap)1