diff --git a/core/src/com/cloud/agent/transport/Request.java b/core/src/com/cloud/agent/transport/Request.java index eb8cf304041..298eeed1107 100755 --- a/core/src/com/cloud/agent/transport/Request.java +++ b/core/src/com/cloud/agent/transport/Request.java @@ -29,6 +29,7 @@ import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; import com.cloud.agent.api.SecStorageFirewallCfgCommand.PortConfig; import com.cloud.exception.UnsupportedVersionException; +import com.cloud.storage.VolumeVO; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; import com.cloud.utils.exception.CloudRuntimeException; @@ -92,8 +93,8 @@ public class Request { s_gBuilder = new GsonBuilder(); s_gBuilder.registerTypeAdapter(Command[].class, new ArrayTypeAdaptor()); s_gBuilder.registerTypeAdapter(Answer[].class, new ArrayTypeAdaptor()); -// final Type listType = new TypeToken>() {}.getType(); -// s_gBuilder.registerTypeAdapter(listType, new VolListTypeAdaptor()); + final Type listType = new TypeToken>() {}.getType(); + s_gBuilder.registerTypeAdapter(listType, new VolListTypeAdaptor()); s_gBuilder.registerTypeAdapter(new TypeToken>() {}.getType(), new PortConfigListTypeAdaptor()); s_gBuilder.registerTypeAdapter(new TypeToken>() {}.getType(), new NwGroupsCommandTypeAdaptor()); s_logger.info("Builder inited."); @@ -121,7 +122,6 @@ public class Request { _seq = seq; _agentId = agentId; _mgmtId = mgmtId; - setInSequence(cmds); } protected Request(Version ver, long seq, long agentId, long mgmtId, short flags, final String content) { @@ -140,18 +140,6 @@ public class Request { setRevertOnError(revert); } - protected void setInSequence(Command[] cmds) { - if (cmds == null) { - return; - } - for (Command cmd : cmds) { - if (cmd.executeInSequence()) { - setInSequence(true); - break; - } - } - } - protected Request(final Request that, final Command[] cmds) { this._ver = that._ver; this._seq = that._seq; @@ -302,34 +290,6 @@ public class Request { protected short getFlags() { return (short)(((this instanceof Response) ? FLAG_RESPONSE : FLAG_REQUEST) | _flags); } - - public void log(long agentId, String msg) { - if (!s_logger.isDebugEnabled()) { - return; - } - - StringBuilder buf = new StringBuilder("Seq "); - buf.append(agentId).append("-").append(_seq).append(": "); - boolean debug = false; - if (_cmds != null) { - for (Command cmd : _cmds) { - if (!cmd.logTrace()) { - debug = true; - break; - } - } - } else { - debug = true; - } - - buf.append(msg).append(toString()); - - if (executeInSequence() || debug) { - s_logger.debug(buf.toString()); - } else { - s_logger.trace(buf.toString()); - } - } /** * Factory method for Request and Response. It expects the bytes to be @@ -419,6 +379,10 @@ public class Request { } public static class NwGroupsCommandTypeAdaptor implements JsonDeserializer>, JsonSerializer> { + static final GsonBuilder s_gBuilder; + static { + s_gBuilder = Request.initBuilder(); + } public NwGroupsCommandTypeAdaptor() { } @@ -468,6 +432,12 @@ public class Request { } public static class PortConfigListTypeAdaptor implements JsonDeserializer>, JsonSerializer> { + static final GsonBuilder s_gBuilder; + static { + s_gBuilder = Request.initBuilder(); + } + + static final Type listType = new TypeToken>() {}.getType(); public PortConfigListTypeAdaptor() { } @@ -504,5 +474,6 @@ public class Request { } return pcs; } + } } diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java index f648646fcba..9052eedb695 100755 --- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -846,7 +846,6 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene @Override public boolean advanceStop(T vm, boolean forced, User user, Account account) throws AgentUnavailableException, OperationTimedoutException, ConcurrentOperationException { - long vmId = vm.getId(); State state = vm.getState(); if (state == State.Stopped) { if (s_logger.isDebugEnabled()) { @@ -861,25 +860,25 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene } return true; } + + Long hostId = vm.getHostId(); + if (hostId == null) { + try { + stateTransitTo(vm, Event.AgentReportStopped, null, null); + } catch (NoTransitionException e) { + s_logger.warn(e.getMessage()); + } + return true; + } VirtualMachineGuru vmGuru = getVmGuru(vm); try { - if (!stateTransitTo(vm, Event.StopRequested, vm.getHostId())) { + if (!stateTransitTo(vm, forced ? Event.AgentReportStopped : Event.StopRequested, vm.getHostId(), null)) { throw new ConcurrentOperationException("VM is being operated on."); } } catch (NoTransitionException e1) { - if (!forced) { - throw new ConcurrentOperationException("VM is being operated on by someone else."); - } - - vm = vmGuru.findById(vmId); - if (vm == null) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Unable to find VM " + vmId); - } - return true; - } + throw new CloudRuntimeException("We cannot stop " + vm + " when it is in state " + vm.getState()); } if ((vm.getState() == State.Starting || vm.getState() == State.Stopping || vm.getState() == State.Migrating) && forced) { diff --git a/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java b/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java index d4979cc6a10..f79c9196976 100644 --- a/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java +++ b/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java @@ -197,7 +197,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase implem SearchCriteria sc = HostIdUpTypesSearch.create(); sc.setParameters("hostid", hostid); sc.setParameters("types", (Object[]) types); - sc.setParameters("states", new Object[] {State.Destroyed, State.Stopped, State.Expunging}); + sc.setParameters("states", new Object[] {State.Destroyed, State.Stopped, State.Expunging}); return listBy(sc); } @@ -242,8 +242,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase implem } @Override - public boolean updateState(State oldState, Event event, - State newState, VirtualMachine vm, Long hostId) { + public boolean updateState(State oldState, Event event, State newState, VirtualMachine vm, Long hostId) { if (newState == null) { if (s_logger.isDebugEnabled()) { s_logger.debug("There's no way to transition from old state: " + oldState.toString() + " event: " + event.toString()); @@ -253,6 +252,8 @@ public class VMInstanceDaoImpl extends GenericDaoBase implem VMInstanceVO vmi = (VMInstanceVO)vm; Long oldHostId = vmi.getHostId(); + Long oldUpdated = vmi.getUpdated(); + Date oldUpdateDate = vmi.getUpdateTime(); SearchCriteria sc = StateChangeSearch.create(); sc.setParameters("id", vmi.getId()); @@ -269,15 +270,11 @@ public class VMInstanceDaoImpl extends GenericDaoBase implem int result = update(vmi, sc); if (result == 0 && s_logger.isDebugEnabled()) { - /*update builder will change the state/hostid/updated, even update is failed*/ - vmi.setState(oldState); - vmi.setHostId(oldHostId); - vmi.decrUpdated(); - VMInstanceVO vo = findById(vm.getId()); StringBuilder str = new StringBuilder("Unable to update ").append(vo.toString()); - str.append(": DB Data={Host=").append(vo.getHostId()).append("; State=").append(vo.getState().toString()).append("; updated=").append(vo.getUpdated()); - str.append("} Stale Data: {Host=").append(vm.getHostId()).append("; State=").append(vm.getState().toString()).append("; updated=").append(vmi.getUpdated()).append("}"); + str.append(": DB Data={Host=").append(vo.getHostId()).append("; State=").append(vo.getState().toString()).append("; updated=").append(vo.getUpdated()).append("; time=").append(vo.getUpdateTime()); + str.append("} New Data: {Host=").append(vm.getHostId()).append("; State=").append(vm.getState().toString()).append("; updated=").append(vmi.getUpdated()).append("; time=").append(vo.getUpdateTime()); + str.append("} Stale Data: {Host=").append(oldHostId).append("; State=").append(oldState).append("; updated=").append(oldUpdated).append("; time=").append(oldUpdateDate).append("}"); s_logger.debug(str.toString()); } return result > 0; diff --git a/utils/src/com/cloud/utils/db/UpdateBuilder.java b/utils/src/com/cloud/utils/db/UpdateBuilder.java index 4ea4b0ae791..d1bf42c9889 100755 --- a/utils/src/com/cloud/utils/db/UpdateBuilder.java +++ b/utils/src/com/cloud/utils/db/UpdateBuilder.java @@ -47,7 +47,7 @@ public class UpdateBuilder implements MethodInterceptor { makeIncrChange(name, args); } else if (name.startsWith("decr")) { makeDecrChange(name, args); - } + } return methodProxy.invokeSuper(object, args); } @@ -118,7 +118,7 @@ public class UpdateBuilder implements MethodInterceptor { return _changes.get(name).second(); } - protected void clear() { + public void clear() { _changes.clear(); } diff --git a/utils/src/com/cloud/utils/fsm/StateMachine2.java b/utils/src/com/cloud/utils/fsm/StateMachine2.java index bac99232d80..d0ab1835486 100644 --- a/utils/src/com/cloud/utils/fsm/StateMachine2.java +++ b/utils/src/com/cloud/utils/fsm/StateMachine2.java @@ -114,12 +114,15 @@ public class StateMachine2> { Long oldHostId = vo.getHostId(); transitionStatus = dao.updateState(currentState, e, nextState, vo, id); + if (!transitionStatus) { + return false; + } for (StateListener listener : _listeners) { listener.postStateTransitionEvent(currentState, e, nextState, vo, transitionStatus, oldHostId); } - - return transitionStatus; + + return true; } public boolean registerListener(StateListener listener) {