Search in sources :

Example 21 with StopAnswer

use of com.cloud.agent.api.StopAnswer in project cloudstack by apache.

the class VirtualMachineManagerImpl method advanceStop.

private void advanceStop(final VMInstanceVO vm, final boolean cleanUpEvenIfUnableToStop) throws AgentUnavailableException, OperationTimedoutException, ConcurrentOperationException {
    final State state = vm.getState();
    if (state == State.Stopped) {
        if (s_logger.isDebugEnabled()) {
            s_logger.debug("VM is already stopped: " + vm);
        }
        return;
    }
    if (state == State.Destroyed || state == State.Expunging || state == State.Error) {
        if (s_logger.isDebugEnabled()) {
            s_logger.debug("Stopped called on " + vm + " but the state is " + state);
        }
        return;
    }
    // grab outstanding work item if any
    final ItWorkVO work = _workDao.findByOutstandingWork(vm.getId(), vm.getState());
    if (work != null) {
        if (s_logger.isDebugEnabled()) {
            s_logger.debug("Found an outstanding work item for this vm " + vm + " with state:" + vm.getState() + ", work id:" + work.getId());
        }
    }
    final Long hostId = vm.getHostId();
    if (hostId == null) {
        if (!cleanUpEvenIfUnableToStop) {
            if (s_logger.isDebugEnabled()) {
                s_logger.debug("HostId is null but this is not a forced stop, cannot stop vm " + vm + " with state:" + vm.getState());
            }
            throw new CloudRuntimeException("Unable to stop " + vm);
        }
        try {
            stateTransitTo(vm, Event.AgentReportStopped, null, null);
        } catch (final NoTransitionException e) {
            s_logger.warn(e.getMessage());
        }
        // mark outstanding work item if any as done
        if (work != null) {
            if (s_logger.isDebugEnabled()) {
                s_logger.debug("Updating work item to Done, id:" + work.getId());
            }
            work.setStep(Step.Done);
            _workDao.update(work.getId(), work);
        }
        return;
    }
    final VirtualMachineGuru vmGuru = getVmGuru(vm);
    final VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm);
    try {
        if (!stateTransitTo(vm, Event.StopRequested, vm.getHostId())) {
            throw new ConcurrentOperationException("VM is being operated on.");
        }
    } catch (final NoTransitionException e1) {
        if (!cleanUpEvenIfUnableToStop) {
            throw new CloudRuntimeException("We cannot stop " + vm + " when it is in state " + vm.getState());
        }
        final boolean doCleanup = true;
        if (s_logger.isDebugEnabled()) {
            s_logger.debug("Unable to transition the state but we're moving on because it's forced stop");
        }
        if (doCleanup) {
            if (cleanup(vmGuru, new VirtualMachineProfileImpl(vm), work, Event.StopRequested, cleanUpEvenIfUnableToStop)) {
                try {
                    if (s_logger.isDebugEnabled() && work != null) {
                        s_logger.debug("Updating work item to Done, id:" + work.getId());
                    }
                    if (!changeState(vm, Event.AgentReportStopped, null, work, Step.Done)) {
                        throw new CloudRuntimeException("Unable to stop " + vm);
                    }
                } catch (final NoTransitionException e) {
                    s_logger.warn("Unable to cleanup " + vm);
                    throw new CloudRuntimeException("Unable to stop " + vm, e);
                }
            } else {
                if (s_logger.isDebugEnabled()) {
                    s_logger.debug("Failed to cleanup VM: " + vm);
                }
                throw new CloudRuntimeException("Failed to cleanup " + vm + " , current state " + vm.getState());
            }
        }
    }
    if (vm.getState() != State.Stopping) {
        throw new CloudRuntimeException("We cannot proceed with stop VM " + vm + " since it is not in 'Stopping' state, current state: " + vm.getState());
    }
    vmGuru.prepareStop(profile);
    StopCommand stpCmd = new StopCommand(vm, getExecuteInSequence(vm.getHypervisorType()), false);
    stpCmd.setControlIp(getControlNicIpForVM(vm));
    final StopCommand stop = stpCmd;
    boolean stopped = false;
    Answer answer = null;
    try {
        answer = _agentMgr.send(vm.getHostId(), stop);
        if (answer != null) {
            if (answer instanceof StopAnswer) {
                final StopAnswer stopAns = (StopAnswer) answer;
                if (vm.getType() == VirtualMachine.Type.User) {
                    final String platform = stopAns.getPlatform();
                    if (platform != null) {
                        final UserVmVO userVm = _userVmDao.findById(vm.getId());
                        _userVmDao.loadDetails(userVm);
                        userVm.setDetail("platform", platform);
                        _userVmDao.saveDetails(userVm);
                    }
                }
            }
            stopped = answer.getResult();
            if (!stopped) {
                throw new CloudRuntimeException("Unable to stop the virtual machine due to " + answer.getDetails());
            }
            vmGuru.finalizeStop(profile, answer);
            final GPUDeviceTO gpuDevice = stop.getGpuDevice();
            if (gpuDevice != null) {
                _resourceMgr.updateGPUDetails(vm.getHostId(), gpuDevice.getGroupDetails());
            }
        } else {
            throw new CloudRuntimeException("Invalid answer received in response to a StopCommand on " + vm.instanceName);
        }
    } catch (final AgentUnavailableException e) {
        s_logger.warn("Unable to stop vm, agent unavailable: " + e.toString());
    } catch (final OperationTimedoutException e) {
        s_logger.warn("Unable to stop vm, operation timed out: " + e.toString());
    } finally {
        if (!stopped) {
            if (!cleanUpEvenIfUnableToStop) {
                s_logger.warn("Unable to stop vm " + vm);
                try {
                    stateTransitTo(vm, Event.OperationFailed, vm.getHostId());
                } catch (final NoTransitionException e) {
                    s_logger.warn("Unable to transition the state " + vm);
                }
                throw new CloudRuntimeException("Unable to stop " + vm);
            } else {
                s_logger.warn("Unable to actually stop " + vm + " but continue with release because it's a force stop");
                vmGuru.finalizeStop(profile, answer);
            }
        }
    }
    if (s_logger.isDebugEnabled()) {
        s_logger.debug(vm + " is stopped on the host.  Proceeding to release resource held.");
    }
    try {
        _networkMgr.release(profile, cleanUpEvenIfUnableToStop);
        s_logger.debug("Successfully released network resources for the vm " + vm);
    } catch (final Exception e) {
        s_logger.warn("Unable to release some network resources.", e);
    }
    try {
        if (vm.getHypervisorType() != HypervisorType.BareMetal) {
            volumeMgr.release(profile);
            s_logger.debug("Successfully released storage resources for the vm " + vm);
        }
    } catch (final Exception e) {
        s_logger.warn("Unable to release storage resources.", e);
    }
    try {
        if (work != null) {
            if (s_logger.isDebugEnabled()) {
                s_logger.debug("Updating the outstanding work item to Done, id:" + work.getId());
            }
            work.setStep(Step.Done);
            _workDao.update(work.getId(), work);
        }
        if (!stateTransitTo(vm, Event.OperationSucceeded, null)) {
            throw new CloudRuntimeException("unable to stop " + vm);
        }
    } catch (final NoTransitionException e) {
        s_logger.warn(e.getMessage());
        throw new CloudRuntimeException("Unable to stop " + vm);
    }
}
Also used : OperationTimedoutException(com.cloud.exception.OperationTimedoutException) GPUDeviceTO(com.cloud.agent.api.to.GPUDeviceTO) ConcurrentOperationException(com.cloud.exception.ConcurrentOperationException) ExecutionException(com.cloud.utils.exception.ExecutionException) ConnectionException(com.cloud.exception.ConnectionException) NoTransitionException(com.cloud.utils.fsm.NoTransitionException) AgentUnavailableException(com.cloud.exception.AgentUnavailableException) TransactionCallbackWithException(com.cloud.utils.db.TransactionCallbackWithException) OperationTimedoutException(com.cloud.exception.OperationTimedoutException) InsufficientCapacityException(com.cloud.exception.InsufficientCapacityException) InsufficientServerCapacityException(com.cloud.exception.InsufficientServerCapacityException) InsufficientAddressCapacityException(com.cloud.exception.InsufficientAddressCapacityException) ResourceUnavailableException(com.cloud.exception.ResourceUnavailableException) StorageUnavailableException(com.cloud.exception.StorageUnavailableException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) SQLException(java.sql.SQLException) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) AffinityConflictException(com.cloud.exception.AffinityConflictException) ConcurrentOperationException(com.cloud.exception.ConcurrentOperationException) InsufficientVirtualNetworkCapacityException(com.cloud.exception.InsufficientVirtualNetworkCapacityException) ConfigurationException(javax.naming.ConfigurationException) AgentControlAnswer(com.cloud.agent.api.AgentControlAnswer) RebootAnswer(com.cloud.agent.api.RebootAnswer) StartAnswer(com.cloud.agent.api.StartAnswer) RestoreVMSnapshotAnswer(com.cloud.agent.api.RestoreVMSnapshotAnswer) PlugNicAnswer(com.cloud.agent.api.PlugNicAnswer) StopAnswer(com.cloud.agent.api.StopAnswer) Answer(com.cloud.agent.api.Answer) UnPlugNicAnswer(com.cloud.agent.api.UnPlugNicAnswer) ClusterVMMetaDataSyncAnswer(com.cloud.agent.api.ClusterVMMetaDataSyncAnswer) CheckVirtualMachineAnswer(com.cloud.agent.api.CheckVirtualMachineAnswer) StopCommand(com.cloud.agent.api.StopCommand) PowerState(com.cloud.vm.VirtualMachine.PowerState) State(com.cloud.vm.VirtualMachine.State) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) AgentUnavailableException(com.cloud.exception.AgentUnavailableException) NoTransitionException(com.cloud.utils.fsm.NoTransitionException) StopAnswer(com.cloud.agent.api.StopAnswer)

Aggregations

StopAnswer (com.cloud.agent.api.StopAnswer)21 StartAnswer (com.cloud.agent.api.StartAnswer)7 StopCommand (com.cloud.agent.api.StopCommand)6 CloudRuntimeException (com.cloud.utils.exception.CloudRuntimeException)6 State (com.cloud.vm.VirtualMachine.State)6 ConfigurationException (javax.naming.ConfigurationException)6 Answer (com.cloud.agent.api.Answer)5 CheckVirtualMachineAnswer (com.cloud.agent.api.CheckVirtualMachineAnswer)5 GPUDeviceTO (com.cloud.agent.api.to.GPUDeviceTO)4 Test (org.junit.Test)4 AgentControlAnswer (com.cloud.agent.api.AgentControlAnswer)3 ClusterVMMetaDataSyncAnswer (com.cloud.agent.api.ClusterVMMetaDataSyncAnswer)3 PlugNicAnswer (com.cloud.agent.api.PlugNicAnswer)3 RebootAnswer (com.cloud.agent.api.RebootAnswer)3 RestoreVMSnapshotAnswer (com.cloud.agent.api.RestoreVMSnapshotAnswer)3 UnPlugNicAnswer (com.cloud.agent.api.UnPlugNicAnswer)3 AgentUnavailableException (com.cloud.exception.AgentUnavailableException)3 OperationTimedoutException (com.cloud.exception.OperationTimedoutException)3 Connect (org.libvirt.Connect)3 LibvirtException (org.libvirt.LibvirtException)3