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.
*/
public Long getLastHostId();
public Long getHostId();
public void setLastHostId(Long lastHostId);

View File

@ -29,9 +29,16 @@ import javax.naming.ConfigurationException;
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.configuration.Config;
import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.exception.ConnectionException;
import com.cloud.host.Host;
import com.cloud.host.HostVO;
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.SearchCriteria;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.fsm.StateListener;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachine.Event;
import com.cloud.vm.VirtualMachine.State;
import com.cloud.vm.dao.VMInstanceDao;
@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);
String _name;
@Inject CapacityDao _capacityDao;
@ -59,6 +69,7 @@ public class CapacityManagerImpl implements CapacityManager {
@Inject ServiceOfferingDao _offeringsDao;
@Inject HostDao _hostDao;
@Inject VMInstanceDao _vmDao;
private int _hostCapacityCheckerDelay;
private int _hostCapacityCheckerInterval;
private int _vmCapacityReleaseInterval;
@ -73,6 +84,7 @@ public class CapacityManagerImpl implements CapacityManager {
_hostCapacityCheckerInterval = NumbersUtil.parseInt(_configDao.getValue(Config.HostCapacityCheckerInterval.key()), 3600);
_vmCapacityReleaseInterval = NumbersUtil.parseInt(_configDao.getValue(Config.VmHostCapacityReleaseInterval.key()), 86400);
_executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("HostCapacity-Checker"));
VirtualMachine.State.getStateMachine().registerListener(this);
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
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)) {
return false;
}

View File

@ -1329,7 +1329,7 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG
}
@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) {
return false;
}

View File

@ -138,7 +138,7 @@ import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.VMInstanceDao;
@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);
String _name;
@ -445,7 +445,6 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, StateLi
_executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("Vm-Operations-Cleanup"));
_nodeId = _clusterMgr.getId();
_stateMachine.registerListener(this);
_agentMgr.registerForHostEvents(this, true, true, true);
return true;
}
@ -906,6 +905,12 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, StateLi
@Override
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);
}
@ -1157,66 +1162,6 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, StateLi
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
public VMInstanceVO findById(VirtualMachine.Type type, long vmId) {

View File

@ -24,5 +24,5 @@ public interface StateListener <S,E,V> {
* @param status the state transition is allowed or not
* @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);
}
Long oldHostId = vo.getHostId();
transitionStatus = dao.updateState(currentState, e, nextState, vo, id);
for (StateListener<S,E, V> listener : _listeners) {
listener.postStateTransitionEvent(currentState, e, nextState, vo, transitionStatus);
listener.postStateTransitionEvent(currentState, e, nextState, vo, transitionStatus, oldHostId);
}
return transitionStatus;

View File

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