fix capacity caclulation issue after migration

This commit is contained in:
Edison Su 2011-02-09 13:33:20 -05:00
parent cec16baf8e
commit 08285af33f
8 changed files with 79 additions and 68 deletions

View File

@ -210,6 +210,7 @@ public interface VirtualMachine extends RunningOn, ControlledEntity, StateObject
* @return id of the host it was assigned last time. * @return id of the host it was assigned last time.
*/ */
public Long getLastHostId(); public Long getLastHostId();
public Long getHostId();
public void setLastHostId(Long lastHostId); public void setLastHostId(Long lastHostId);

View File

@ -29,9 +29,16 @@ import javax.naming.ConfigurationException;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import com.cloud.agent.Listener;
import com.cloud.agent.api.AgentControlAnswer;
import com.cloud.agent.api.AgentControlCommand;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.StartupCommand;
import com.cloud.capacity.dao.CapacityDao; import com.cloud.capacity.dao.CapacityDao;
import com.cloud.configuration.Config; import com.cloud.configuration.Config;
import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.exception.ConnectionException;
import com.cloud.host.Host; import com.cloud.host.Host;
import com.cloud.host.HostVO; import com.cloud.host.HostVO;
import com.cloud.host.Status; import com.cloud.host.Status;
@ -46,12 +53,15 @@ import com.cloud.utils.concurrency.NamedThreadFactory;
import com.cloud.utils.db.DB; import com.cloud.utils.db.DB;
import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.Transaction; import com.cloud.utils.db.Transaction;
import com.cloud.utils.fsm.StateListener;
import com.cloud.vm.VMInstanceVO; import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachine.Event;
import com.cloud.vm.VirtualMachine.State;
import com.cloud.vm.dao.VMInstanceDao; import com.cloud.vm.dao.VMInstanceDao;
@Local(value=CapacityManager.class) @Local(value=CapacityManager.class)
public class CapacityManagerImpl implements CapacityManager { public class CapacityManagerImpl implements CapacityManager , StateListener<State, VirtualMachine.Event, VirtualMachine>{
private static final Logger s_logger = Logger.getLogger(CapacityManagerImpl.class); private static final Logger s_logger = Logger.getLogger(CapacityManagerImpl.class);
String _name; String _name;
@Inject CapacityDao _capacityDao; @Inject CapacityDao _capacityDao;
@ -59,6 +69,7 @@ public class CapacityManagerImpl implements CapacityManager {
@Inject ServiceOfferingDao _offeringsDao; @Inject ServiceOfferingDao _offeringsDao;
@Inject HostDao _hostDao; @Inject HostDao _hostDao;
@Inject VMInstanceDao _vmDao; @Inject VMInstanceDao _vmDao;
private int _hostCapacityCheckerDelay; private int _hostCapacityCheckerDelay;
private int _hostCapacityCheckerInterval; private int _hostCapacityCheckerInterval;
private int _vmCapacityReleaseInterval; private int _vmCapacityReleaseInterval;
@ -73,6 +84,7 @@ public class CapacityManagerImpl implements CapacityManager {
_hostCapacityCheckerInterval = NumbersUtil.parseInt(_configDao.getValue(Config.HostCapacityCheckerInterval.key()), 3600); _hostCapacityCheckerInterval = NumbersUtil.parseInt(_configDao.getValue(Config.HostCapacityCheckerInterval.key()), 3600);
_vmCapacityReleaseInterval = NumbersUtil.parseInt(_configDao.getValue(Config.VmHostCapacityReleaseInterval.key()), 86400); _vmCapacityReleaseInterval = NumbersUtil.parseInt(_configDao.getValue(Config.VmHostCapacityReleaseInterval.key()), 86400);
_executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("HostCapacity-Checker")); _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("HostCapacity-Checker"));
VirtualMachine.State.getStateMachine().registerListener(this);
return true; return true;
} }
@ -330,4 +342,55 @@ public class CapacityManagerImpl implements CapacityManager {
} }
} }
} }
@Override
public boolean preStateTransitionEvent(State oldState,
Event event, State newState, VirtualMachine vm, boolean transitionStatus, Long id) {
return true;
}
@Override
public boolean postStateTransitionEvent(State oldState, Event event, State newState, VirtualMachine vm, boolean status, Long oldHostId) {
s_logger.debug("VM state transitted from :" + oldState + " to " + newState + " with event: " + event +
"vm's original host id: " + vm.getLastHostId() + " new host id: " + vm.getHostId());
if (!status) {
return false;
}
if (oldState == State.Starting) {
if (event == Event.OperationFailed) {
releaseVmCapacity(vm, false, false, oldHostId);
} else if (event == Event.OperationRetry) {
releaseVmCapacity(vm, false, false, oldHostId);
} else if (event == Event.AgentReportStopped) {
releaseVmCapacity(vm, false, true, oldHostId);
}
} else if (oldState == State.Running) {
if (event == Event.AgentReportStopped) {
releaseVmCapacity(vm, false, true, oldHostId);
}
} else if (oldState == State.Migrating) {
if (event == Event.AgentReportStopped) {
/*Release capacity from original host*/
releaseVmCapacity(vm, false, false, vm.getLastHostId());
releaseVmCapacity(vm, false, true, oldHostId);
} else if (event == Event.MigrationFailedOnSource) {
/*Release from dest host*/
releaseVmCapacity(vm, false, false, oldHostId);
} else if (event == Event.OperationSucceeded) {
releaseVmCapacity(vm, false, false, vm.getLastHostId());
}
} else if (oldState == State.Stopping) {
if (event == Event.AgentReportStopped || event == Event.OperationSucceeded) {
releaseVmCapacity(vm, false, true, oldHostId);
}
} else if (oldState == State.Stopped) {
if (event == Event.DestroyRequested) {
releaseVmCapacity(vm, true, false, vm.getLastHostId());
}
}
return true;
}
} }

View File

@ -92,7 +92,7 @@ public class OvsNetworkManagerImpl implements OvsNetworkManager {
} }
@Override @Override
public boolean postStateTransitionEvent(State oldState, Event event, State newState, VirtualMachine vm, boolean status) { public boolean postStateTransitionEvent(State oldState, Event event, State newState, VirtualMachine vm, boolean status, Long oldHostId) {
if (!_isEnabled || !status || (vm.getType() != VirtualMachine.Type.User && vm.getType() != VirtualMachine.Type.DomainRouter)) { if (!_isEnabled || !status || (vm.getType() != VirtualMachine.Type.User && vm.getType() != VirtualMachine.Type.DomainRouter)) {
return false; return false;
} }

View File

@ -1329,7 +1329,7 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG
} }
@Override @Override
public boolean postStateTransitionEvent(State oldState, Event event, State newState, VirtualMachine vm, boolean status) { public boolean postStateTransitionEvent(State oldState, Event event, State newState, VirtualMachine vm, boolean status, Long oldHostId) {
if (!status) { if (!status) {
return false; return false;
} }

View File

@ -138,7 +138,7 @@ import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.VMInstanceDao; import com.cloud.vm.dao.VMInstanceDao;
@Local(value=VirtualMachineManager.class) @Local(value=VirtualMachineManager.class)
public class VirtualMachineManagerImpl implements VirtualMachineManager, StateListener<State, VirtualMachine.Event, VirtualMachine>, Listener { public class VirtualMachineManagerImpl implements VirtualMachineManager, Listener {
private static final Logger s_logger = Logger.getLogger(VirtualMachineManagerImpl.class); private static final Logger s_logger = Logger.getLogger(VirtualMachineManagerImpl.class);
String _name; String _name;
@ -445,7 +445,6 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, StateLi
_executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("Vm-Operations-Cleanup")); _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("Vm-Operations-Cleanup"));
_nodeId = _clusterMgr.getId(); _nodeId = _clusterMgr.getId();
_stateMachine.registerListener(this);
_agentMgr.registerForHostEvents(this, true, true, true); _agentMgr.registerForHostEvents(this, true, true, true);
return true; return true;
} }
@ -906,6 +905,12 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, StateLi
@Override @Override
public boolean stateTransitTo(VMInstanceVO vm, VirtualMachine.Event e, Long hostId) { public boolean stateTransitTo(VMInstanceVO vm, VirtualMachine.Event e, Long hostId) {
State oldState = vm.getState();
if (oldState == State.Starting ) {
if (e == Event.OperationSucceeded) {
vm.setLastHostId(hostId);
}
}
return _stateMachine.transitTo(vm, e, hostId, _vmDao); return _stateMachine.transitTo(vm, e, hostId, _vmDao);
} }
@ -1157,67 +1162,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, StateLi
return rebootedVm; return rebootedVm;
} }
@Override
public boolean preStateTransitionEvent(State oldState,
Event event, State newState, VirtualMachine vm, boolean transitionStatus, Long id) {
s_logger.debug("VM state transitted from :" + oldState + " to " + newState + " with event: " + event +
"vm's original host id: " + vm.getHostId() + " new host id: " + id);
if (!transitionStatus) {
return false;
}
if (oldState == State.Starting) {
if (event == Event.OperationSucceeded) {
if (vm.getLastHostId() != null && vm.getLastHostId() != id) {
/*need to release the reserved capacity on lasthost*/
_capacityMgr.releaseVmCapacity(vm, true, false, vm.getLastHostId());
}
vm.setLastHostId(id);
} else if (event == Event.OperationFailed) {
_capacityMgr.releaseVmCapacity(vm, false, false, vm.getHostId());
} else if (event == Event.OperationRetry) {
_capacityMgr.releaseVmCapacity(vm, false, false, vm.getHostId());
} else if (event == Event.AgentReportStopped) {
_capacityMgr.releaseVmCapacity(vm, false, true, vm.getHostId());
}
} else if (oldState == State.Running) {
if (event == Event.AgentReportStopped) {
_capacityMgr.releaseVmCapacity(vm, false, true, vm.getHostId());
}
} else if (oldState == State.Migrating) {
if (event == Event.AgentReportStopped) {
/*Release capacity from original host*/
_capacityMgr.releaseVmCapacity(vm, false, true, vm.getHostId());
} else if (event == Event.MigrationFailedOnSource) {
/*release capacity from dest host*/
_capacityMgr.releaseVmCapacity(vm, false, false, id);
id = vm.getHostId();
} else if (event == Event.MigrationFailedOnDest) {
/*release capacify from original host*/
_capacityMgr.releaseVmCapacity(vm, false, false, vm.getHostId());
} else if (event == Event.OperationSucceeded) {
_capacityMgr.releaseVmCapacity(vm, false, false, vm.getHostId());
/*set lasthost id to migration destination host id*/
vm.setLastHostId(id);
}
} else if (oldState == State.Stopping) {
if (event == Event.AgentReportStopped || event == Event.OperationSucceeded) {
_capacityMgr.releaseVmCapacity(vm, false, true, vm.getHostId());
}
} else if (oldState == State.Stopped) {
if (event == Event.DestroyRequested) {
_capacityMgr.releaseVmCapacity(vm, true, false, vm.getLastHostId());
vm.setLastHostId(null);
}
}
return transitionStatus;
}
@Override
public boolean postStateTransitionEvent(State oldState, Event event, State newState, VirtualMachine vo, boolean status) {
return true;
}
@Override @Override
public VMInstanceVO findById(VirtualMachine.Type type, long vmId) { public VMInstanceVO findById(VirtualMachine.Type type, long vmId) {
VirtualMachineGuru<? extends VMInstanceVO> guru = _vmGurus.get(type); VirtualMachineGuru<? extends VMInstanceVO> guru = _vmGurus.get(type);

View File

@ -24,5 +24,5 @@ public interface StateListener <S,E,V> {
* @param status the state transition is allowed or not * @param status the state transition is allowed or not
* @return * @return
*/ */
public boolean postStateTransitionEvent(S oldState, E event, S newState, V vo, boolean status); public boolean postStateTransitionEvent(S oldState, E event, S newState, V vo, boolean status, Long id);
} }

View File

@ -108,10 +108,11 @@ public class StateMachine2<S, E, V extends StateObject<S>> {
listener.preStateTransitionEvent(currentState, e, nextState, vo, transitionStatus, id); listener.preStateTransitionEvent(currentState, e, nextState, vo, transitionStatus, id);
} }
Long oldHostId = vo.getHostId();
transitionStatus = dao.updateState(currentState, e, nextState, vo, id); transitionStatus = dao.updateState(currentState, e, nextState, vo, id);
for (StateListener<S,E, V> listener : _listeners) { for (StateListener<S,E, V> listener : _listeners) {
listener.postStateTransitionEvent(currentState, e, nextState, vo, transitionStatus); listener.postStateTransitionEvent(currentState, e, nextState, vo, transitionStatus, oldHostId);
} }
return transitionStatus; return transitionStatus;

View File

@ -5,4 +5,5 @@ public interface StateObject<S> {
* @return finite state. * @return finite state.
*/ */
S getState(); S getState();
Long getHostId();
} }