fix for migration

This commit is contained in:
edison 2010-12-03 22:24:22 -08:00
parent d17beeb348
commit b7cdae2688
17 changed files with 319 additions and 74 deletions

View File

@ -121,5 +121,32 @@ public interface DeploymentPlanner extends Adapter {
return false;
}
public boolean shouldAvoid(Cluster cluster) {
if (_dcIds != null && _dcIds.contains(cluster.getDataCenterId())) {
return true;
}
if (_podIds != null && _podIds.contains(cluster.getPodId())) {
return true;
}
if (_clusterIds != null && _clusterIds.contains(cluster.getId())) {
return true;
}
return false;
}
public boolean shouldAvoid(Pod pod) {
if (_dcIds != null && _dcIds.contains(pod.getDataCenterId())) {
return true;
}
if (_podIds != null && _podIds.contains(pod.getId())) {
return true;
}
return false;
}
}
}

View File

@ -38,6 +38,8 @@ public interface VirtualMachine extends RunningOn, ControlledEntity {
ExpungeOperation,
OperationSucceeded,
OperationFailed,
MigrationFailedOnSource,
MigrationFailedOnDest,
OperationRetry,
OperationCancelled
};

View File

@ -2159,9 +2159,9 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, ResourceS
if (capacityVOCpus != null && !capacityVOCpus.isEmpty()) {
CapacityVO CapacityVOCpu = capacityVOCpus.get(0);
long newTotalCpu = (long)(server.getCpus().longValue() * server.getSpeed().longValue()*_cpuOverProvisioningFactor);
if (CapacityVOCpu.getTotalCapacity() < newTotalCpu) {
if ((CapacityVOCpu.getTotalCapacity() <= newTotalCpu) || ((CapacityVOCpu.getUsedCapacity() + CapacityVOCpu.getReservedCapacity()) <= newTotalCpu)) {
CapacityVOCpu.setTotalCapacity(newTotalCpu);
} else if (CapacityVOCpu.getUsedCapacity() + CapacityVOCpu.getReservedCapacity() > newTotalCpu && CapacityVOCpu.getUsedCapacity() < newTotalCpu) {
} else if ((CapacityVOCpu.getUsedCapacity() + CapacityVOCpu.getReservedCapacity() > newTotalCpu) && (CapacityVOCpu.getUsedCapacity() < newTotalCpu)) {
CapacityVOCpu.setReservedCapacity(0);
CapacityVOCpu.setTotalCapacity(newTotalCpu);
} else {
@ -2180,12 +2180,12 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, ResourceS
capacityMem.addAnd("dataCenterId", SearchCriteria.Op.EQ, server.getDataCenterId());
capacityMem.addAnd("podId", SearchCriteria.Op.EQ, server.getPodId());
capacityMem.addAnd("capacityType", SearchCriteria.Op.EQ, CapacityVO.CAPACITY_TYPE_MEMORY);
List<CapacityVO> capacityVOMems = _capacityDao.search(capacitySC, null);
List<CapacityVO> capacityVOMems = _capacityDao.search(capacityMem, null);
if (capacityVOMems != null && !capacityVOMems.isEmpty()) {
CapacityVO CapacityVOMem = capacityVOMems.get(0);
long newTotalMem = server.getTotalMemory();
if (CapacityVOMem.getTotalCapacity() < newTotalMem) {
if (CapacityVOMem.getTotalCapacity() <= newTotalMem || (CapacityVOMem.getUsedCapacity() + CapacityVOMem.getReservedCapacity() <= newTotalMem)) {
CapacityVOMem.setTotalCapacity(newTotalMem);
} else if (CapacityVOMem.getUsedCapacity() + CapacityVOMem.getReservedCapacity() > newTotalMem && CapacityVOMem.getUsedCapacity() < newTotalMem) {
CapacityVOMem.setReservedCapacity(0);

View File

@ -1,11 +1,12 @@
package com.cloud.deploy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.ejb.Local;
import org.apache.log4j.Logger;
import com.cloud.capacity.CapacityVO;
import com.cloud.capacity.dao.CapacityDao;
import com.cloud.dc.ClusterVO;
@ -26,7 +27,6 @@ import com.cloud.offering.ServiceOffering;
import com.cloud.org.Cluster;
import com.cloud.storage.GuestOSCategoryVO;
import com.cloud.storage.GuestOSVO;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.dao.GuestOSCategoryDao;
import com.cloud.storage.dao.GuestOSDao;
import com.cloud.template.VirtualMachineTemplate;
@ -35,8 +35,10 @@ import com.cloud.utils.db.DB;
import com.cloud.utils.db.Transaction;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachineProfile;
@Local(value=DeploymentPlanner.class)
public class FirstFitPlanner extends PlannerBase implements DeploymentPlanner {
private static final Logger s_logger = Logger.getLogger(FirstFitPlanner.class);
@Inject private HostDao _hostDao;
@Inject private CapacityDao _capacityDao;
@Inject private DataCenterDao _dcDao;
@ -56,10 +58,12 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentPlanner {
int cpu_requested = offering.getCpu() * offering.getSpeed();
long ram_requested = offering.getRamSize() * 1024L * 1024L;
s_logger.debug("try to allocate a host from dc:" + plan.getDataCenterId() + ", pod:" + plan.getPodId() + ",cluster:" + plan.getClusterId() +
", requested cpu: " + cpu_requested + ", requested ram: " + ram_requested);
if (vm.getLastHostId() != null) {
HostVO host = _hostDao.findById(vm.getLastHostId());
if (host.getStatus() == Status.Up) {
if (host != null && host.getStatus() == Status.Up) {
boolean canDepployToLastHost = deployToHost(host, cpu_requested, ram_requested, true, avoid);
if (canDepployToLastHost) {
Pod pod = _podDao.findById(vm.getPodId());
@ -70,29 +74,52 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentPlanner {
}
/*Go through all the pods/clusters under zone*/
List<HostPodVO> pods;
List<HostPodVO> pods = null;
if (plan.getPodId() != null) {
pods = new ArrayList<HostPodVO>(1);
pods.add(_podDao.findById(plan.getPodId()));
} else {
pods = _podDao.listByDataCenterId(plan.getDataCenterId());
}
HostPodVO pod = _podDao.findById(plan.getPodId());
if (pod != null && dc.getId() == pod.getDataCenterId()) {
pods = new ArrayList<HostPodVO>(1);
pods.add(pod);
} else {
s_logger.debug("Can't enforce the pod selector");
return null;
}
}
if (pods == null)
pods = _podDao.listByDataCenterId(plan.getDataCenterId());
//Collections.shuffle(pods);
for (HostPodVO hostPod : pods) {
if (avoid.shouldAvoid(hostPod)) {
continue;
}
//Collections.shuffle(clusters);
List<ClusterVO> clusters;
List<ClusterVO> clusters = null;
if (plan.getClusterId() != null) {
clusters = new ArrayList<ClusterVO>(1);
clusters.add(_clusterDao.findById(plan.getClusterId()));
} else {
ClusterVO cluster = _clusterDao.findById(plan.getClusterId());
if (cluster != null && hostPod.getId() == cluster.getPodId()) {
clusters = new ArrayList<ClusterVO>(1);
clusters.add(cluster);
} else {
s_logger.debug("Can't enforce the cluster selector");
return null;
}
}
if (clusters == null) {
clusters = _clusterDao.listByPodId(hostPod.getId());
}
for (ClusterVO clusterVO : clusters) {
if (avoid.shouldAvoid(clusterVO)) {
continue;
}
if (clusterVO.getHypervisorType() != vmProfile.getHypervisorType()) {
avoid.addCluster(clusterVO.getId());
continue;
}
@ -111,8 +138,11 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentPlanner {
Host host = _hostDao.findById(hostVO.getId());
return new DeployDestination(dc, pod, cluster, host);
}
avoid.addHost(hostVO.getId());
}
avoid.addCluster(clusterVO.getId());
}
avoid.addPod(hostPod.getId());
}
return null;

View File

@ -777,7 +777,7 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager {
HostPodVO podVO = _podDao.findById(vm.getPodId());
_alertMgr.sendAlert(alertType, fromHost.getDataCenterId(), fromHost.getPodId(), "Unable to migrate vm " + vm.getHostName() + " from host " + fromHost.getName() + " in zone " + dcVO.getName() + " and pod " + podVO.getName(), "Migrate Command failed. Please check logs.");
_itMgr.stateTransitTo(vm, Event.OperationFailed, vm.getHostId());
_itMgr.stateTransitTo(vm, Event.MigrationFailedOnSource, toHost.getId());
_agentMgr.maintenanceFailed(vm.getHostId());
Command cleanup = mgr.cleanup(vm, null);
@ -807,7 +807,7 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager {
} catch (final OperationTimedoutException e) {
s_logger.warn("Operation timed outfor " + vm.toString());
}
_itMgr.stateTransitTo(vm, Event.OperationFailed, toHost.getId());
_itMgr.stateTransitTo(vm, Event.MigrationFailedOnDest, toHost.getId());
return (System.currentTimeMillis() >> 10) + _migrateRetryInterval;
}

View File

@ -94,6 +94,10 @@ import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.fsm.StateMachine2;
import com.cloud.vm.ItWorkVO.Type;
import com.cloud.vm.VirtualMachine.Event;
import com.cloud.vm.dao.ConsoleProxyDao;
import com.cloud.vm.dao.DomainRouterDao;
import com.cloud.vm.dao.SecondaryStorageVmDao;
import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.VMInstanceDao;
@Local(value=VmManager.class)
@ -113,6 +117,10 @@ public class MauriceMoss implements VmManager, ClusterManagerListener {
@Inject private ClusterManager _clusterMgr;
@Inject private ItWorkDao _workDao;
@Inject private CapacityDao _capacityDao;
@Inject private UserVmDao _userVmDao;
@Inject private DomainRouterDao _routerDao;
@Inject private ConsoleProxyDao _consoleDao;
@Inject private SecondaryStorageVmDao _secondaryDao;
@Inject(adapter=DeploymentPlanner.class)
private Adapters<DeploymentPlanner> _planners;
@ -340,13 +348,15 @@ public class MauriceMoss implements VmManager, ClusterManagerListener {
ExcludeList avoids = new ExcludeList();
int retry = _retry;
while (retry-- != 0) { // It's != so that it can match -1.
DeployDestination dest = null;
while (retry-- != 0) { // It's != so that it can match -1.
/*this will release resource allocated on dest host*/
if (retry < (_retry -1)) {
stateTransitTo(vm, Event.OperationRetry, null);
stateTransitTo(vm, Event.OperationRetry, dest.getHost().getId());
}
VirtualMachineProfileImpl<T> vmProfile = new VirtualMachineProfileImpl<T>(vm, template, offering, null, params);
DeployDestination dest = null;
for (DeploymentPlanner planner : _planners) {
dest = planner.plan(vmProfile, plan, avoids);
if (dest != null) {
@ -366,7 +376,7 @@ public class MauriceMoss implements VmManager, ClusterManagerListener {
try {
_storageMgr.prepare(vmProfile, dest);
} catch (ConcurrentOperationException e) {
stateTransitTo(vm, Event.OperationFailed, null);
stateTransitTo(vm, Event.OperationFailed, dest.getHost().getId());
throw e;
} catch (StorageUnavailableException e) {
s_logger.warn("Unable to contact storage.", e);
@ -401,7 +411,7 @@ public class MauriceMoss implements VmManager, ClusterManagerListener {
}
}
stateTransitTo(vm, Event.OperationFailed, null);
stateTransitTo(vm, Event.OperationFailed, dest.getHost().getId());
if (s_logger.isDebugEnabled()) {
s_logger.debug("Creation complete for VM " + vm);
@ -463,7 +473,7 @@ public class MauriceMoss implements VmManager, ClusterManagerListener {
}
boolean cleanup = false;
VirtualMachineProfile<T> profile = new VirtualMachineProfileImpl<T>(vm);
try {
_networkMgr.release(profile);
@ -510,7 +520,7 @@ public class MauriceMoss implements VmManager, ClusterManagerListener {
}
private void setStateMachine() {
_stateMachine = new StateMachine2<State, VirtualMachine.Event, VMInstanceVO >(_vmDao);
_stateMachine = new StateMachine2<State, VirtualMachine.Event, VMInstanceVO>();
_stateMachine.addTransition(null, VirtualMachine.Event.CreateRequested, State.Creating);
_stateMachine.addTransition(State.Creating, VirtualMachine.Event.OperationSucceeded, State.Stopped);
@ -534,6 +544,8 @@ public class MauriceMoss implements VmManager, ClusterManagerListener {
_stateMachine.addTransition(State.Migrating, VirtualMachine.Event.MigrationRequested, State.Migrating);
_stateMachine.addTransition(State.Migrating, VirtualMachine.Event.OperationSucceeded, State.Running);
_stateMachine.addTransition(State.Migrating, VirtualMachine.Event.OperationFailed, State.Running);
_stateMachine.addTransition(State.Migrating, VirtualMachine.Event.MigrationFailedOnSource, State.Running);
_stateMachine.addTransition(State.Migrating, VirtualMachine.Event.MigrationFailedOnDest, State.Running);
_stateMachine.addTransition(State.Migrating, VirtualMachine.Event.AgentReportRunning, State.Running);
_stateMachine.addTransition(State.Migrating, VirtualMachine.Event.AgentReportStopped, State.Stopped);
_stateMachine.addTransition(State.Stopping, VirtualMachine.Event.OperationSucceeded, State.Stopped);
@ -544,11 +556,20 @@ public class MauriceMoss implements VmManager, ClusterManagerListener {
_stateMachine.addTransition(State.Expunging, VirtualMachine.Event.OperationFailed, State.Expunging);
_stateMachine.addTransition(State.Expunging, VirtualMachine.Event.ExpungeOperation, State.Expunging);
_stateMachine.registerListener(new VMStateListener(_capacityDao, _offeringDao, _vmDao));
_stateMachine.registerListener(new VMStateListener(_capacityDao, _offeringDao));
}
@Override
public boolean stateTransitTo(VMInstanceVO vm, VirtualMachine.Event e, Long id) {
return _stateMachine.transitTO(vm, e, id);
if (vm instanceof UserVmVO) {
return _stateMachine.transitTO(vm, e, id, _userVmDao);
} else if (vm instanceof ConsoleProxyVO) {
return _stateMachine.transitTO(vm, e, id, _consoleDao);
} else if (vm instanceof SecondaryStorageVmVO) {
return _stateMachine.transitTO(vm, e, id, _secondaryDao);
} else if (vm instanceof DomainRouterVO) {
return _stateMachine.transitTO(vm, e, id, _routerDao);
}
return false;
}
}

View File

@ -7,6 +7,7 @@ import com.cloud.capacity.dao.CapacityDao;
import com.cloud.service.ServiceOfferingVO;
import com.cloud.service.dao.ServiceOfferingDao;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.fsm.StateDao;
import com.cloud.utils.fsm.StateListener;
import com.cloud.vm.VirtualMachine.Event;
import com.cloud.vm.dao.VMInstanceDao;
@ -15,25 +16,20 @@ public class VMStateListener implements StateListener<State, VirtualMachine.Even
private static final Logger s_logger = Logger.getLogger(VMStateListener.class);
CapacityDao _capacityDao;
ServiceOfferingDao _offeringDao;
VMInstanceDao _vmDao;
public VMStateListener(CapacityDao capacityDao, ServiceOfferingDao offering, VMInstanceDao vmDao) {
public VMStateListener(CapacityDao capacityDao, ServiceOfferingDao offering) {
_capacityDao = capacityDao;
_offeringDao = offering;
this._vmDao = vmDao;
}
@Override
public boolean processStateTransitionEvent(State oldState,
Event event, State newState, VMInstanceVO vm, boolean transitionStatus, Long id) {
if (oldState == State.Starting) {
if (event == Event.OperationRetry || event == Event.OperationFailed) {
releaseResource(vm, false, false);
}
}
Event event, State newState, VMInstanceVO vm, boolean transitionStatus, Long id, StateDao<State, VirtualMachine.Event, VMInstanceVO> vmDao) {
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 true;
return false;
}
Transaction txn = Transaction.open(Transaction.CLOUD_DB);
@ -42,53 +38,58 @@ public class VMStateListener implements StateListener<State, VirtualMachine.Even
if (oldState == State.Starting) {
if (event == Event.OperationSucceeded) {
if (vm.getLastHostId() != null && vm.getLastHostId() != id) {
/*need to release the reserved capacity on lasthost*/
releaseResource(vm, true, false, vm.getLastHostId());
}
vm.setLastHostId(id);
_vmDao.update(vm.getId(), vm);
} else if (event == Event.OperationRetry || event == Event.OperationFailed) {
/*need to release resource from host, passed in from id, cause vm.gethostid is null*/
releaseResource(vm, false, false, id);
id = null;
}
} else if (oldState == State.Running) {
if (event == Event.AgentReportStopped) {
releaseResource(vm, false, true);
releaseResource(vm, false, true, vm.getHostId());
}
} else if (oldState == State.Migrating) {
if (event == Event.AgentReportStopped) {
/*Release capacity from original host*/
releaseResource(vm, false, true);
} else if (event == Event.OperationFailed) {
if (vm.getHostId() == id) {
/*Migrate command failed, vm still on the orginal host*/
/*no change for the capacity*/
} else {
/*CheckVirtualMachineCommand cmd got exception, assume vm is running on dest host*/
/*Need to clean up capacity*/
releaseResource(vm, false, false);
if (id != null) {
addResource(vm, id);
}
}
releaseResource(vm, false, true, vm.getHostId());
} else if (event == Event.MigrationFailedOnSource) {
/*release capacity from dest host*/
releaseResource(vm, false, false, id);
id = vm.getHostId();
} else if (event == Event.MigrationFailedOnDest) {
/*release capacify from original host*/
releaseResource(vm, false, false, vm.getHostId());
} else if (event == Event.OperationSucceeded) {
releaseResource(vm, false, false);
addResource(vm, id);
releaseResource(vm, false, false, vm.getHostId());
}
} else if (oldState == State.Stopping) {
if (event == Event.AgentReportStopped || event == Event.OperationSucceeded) {
releaseResource(vm, false, true);
releaseResource(vm, false, true, vm.getHostId());
}
} else if (oldState == State.Stopped) {
if (event == Event.DestroyRequested) {
releaseResource(vm, true, false);
releaseResource(vm, true, false, vm.getHostId());
vm.setLastHostId(null);
_vmDao.update(vm.getId(), vm);
}
}
transitionStatus = _vmDao.updateState(oldState, event, newState, vm, id);
transitionStatus = vmDao.updateState(oldState, event, newState, vm, id);
if (transitionStatus) {
txn.commit();
} else {
s_logger.debug("Failed to transit vm's state");
txn.rollback();
}
} catch (Exception e) {
s_logger.debug("Failed to transit vm's state, due to " + e.getMessage());
txn.rollback();
} finally {
txn.close();
@ -97,10 +98,15 @@ public class VMStateListener implements StateListener<State, VirtualMachine.Even
return transitionStatus;
}
private void releaseResource(VMInstanceVO vm, boolean moveFromReserved, boolean moveToReservered) {
private void releaseResource(VMInstanceVO vm, boolean moveFromReserved, boolean moveToReservered, Long hostId) {
ServiceOfferingVO svo = _offeringDao.findById(vm.getServiceOfferingId());
CapacityVO capacityCpu = _capacityDao.findByHostIdType(vm.getHostId(), CapacityVO.CAPACITY_TYPE_CPU);
CapacityVO capacityMemory = _capacityDao.findByHostIdType(vm.getHostId(), CapacityVO.CAPACITY_TYPE_MEMORY);
CapacityVO capacityCpu = _capacityDao.findByHostIdType(hostId, CapacityVO.CAPACITY_TYPE_CPU);
CapacityVO capacityMemory = _capacityDao.findByHostIdType(hostId, CapacityVO.CAPACITY_TYPE_MEMORY);
if (capacityCpu == null || capacityMemory == null || svo == null) {
return;
}
int vmCPU = svo.getCpu() * svo.getSpeed();
long vmMem = svo.getRamSize() * 1024L * 1024L;

View File

@ -24,11 +24,13 @@ import java.util.List;
import com.cloud.info.ConsoleProxyLoadInfo;
import com.cloud.utils.Pair;
import com.cloud.utils.db.GenericDao;
import com.cloud.utils.fsm.StateDao;
import com.cloud.vm.ConsoleProxyVO;
import com.cloud.vm.State;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine;
public interface ConsoleProxyDao extends GenericDao<ConsoleProxyVO, Long> {
public interface ConsoleProxyDao extends GenericDao<ConsoleProxyVO, Long>, StateDao<State, VirtualMachine.Event, VMInstanceVO> {
public void update(long id, int activeSession, Date updateTime, byte[] sessionDetails);

View File

@ -39,7 +39,9 @@ import com.cloud.utils.db.Transaction;
import com.cloud.utils.db.UpdateBuilder;
import com.cloud.vm.ConsoleProxyVO;
import com.cloud.vm.State;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachine.Event;
@Local(value={ConsoleProxyDao.class})
public class ConsoleProxyDaoImpl extends GenericDaoBase<ConsoleProxyVO, Long> implements ConsoleProxyDao {
@ -386,5 +388,40 @@ public class ConsoleProxyDaoImpl extends GenericDaoBase<ConsoleProxyVO, Long> im
} catch (Throwable e) {
}
return l;
}
}
@Override
public boolean updateState(State oldState, Event event,
State newState, VMInstanceVO 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());
}
return false;
}
ConsoleProxyVO consoleVM = (ConsoleProxyVO)vm;
SearchCriteria<ConsoleProxyVO> sc = StateChangeSearch.create();
sc.setParameters("id", consoleVM.getId());
sc.setParameters("states", oldState);
sc.setParameters("host", consoleVM.getHostId());
sc.setParameters("update", consoleVM.getUpdated());
vm.incrUpdated();
UpdateBuilder ub = getUpdateBuilder(consoleVM);
ub.set(consoleVM, "state", newState);
ub.set(consoleVM, "hostId", hostId);
ub.set(consoleVM, _updateTimeAttr, new Date());
int result = update(consoleVM, sc);
if (result == 0 && s_logger.isDebugEnabled()) {
ConsoleProxyVO vo = findById(consoleVM.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(consoleVM.getHostId()).append("; State=").append(consoleVM.getState().toString()).append("; updated=").append(consoleVM.getUpdated()).append("}");
s_logger.debug(str.toString());
}
return result > 0;
}
}

View File

@ -21,14 +21,17 @@ import java.util.List;
import com.cloud.network.router.VirtualRouter.Role;
import com.cloud.utils.db.GenericDao;
import com.cloud.utils.fsm.StateDao;
import com.cloud.vm.DomainRouterVO;
import com.cloud.vm.State;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine;
/**
*
* DomainRouterDao implements
*/
public interface DomainRouterDao extends GenericDao<DomainRouterVO, Long> {
public interface DomainRouterDao extends GenericDao<DomainRouterVO, Long>, StateDao<State, VirtualMachine.Event, VMInstanceVO> {
//@Deprecated
//public boolean updateIf(DomainRouterVO router, State state, State... ifStates);

View File

@ -36,9 +36,12 @@ import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.db.UpdateBuilder;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.ConsoleProxyVO;
import com.cloud.vm.DomainRouterVO;
import com.cloud.vm.State;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachine.Event;
@Local(value = { DomainRouterDao.class })
public class DomainRouterDaoImpl extends GenericDaoBase<DomainRouterVO, Long> implements DomainRouterDao {
@ -307,4 +310,39 @@ public class DomainRouterDaoImpl extends GenericDaoBase<DomainRouterVO, Long> im
sc.setParameters("network", networkConfigurationId);
return findOneBy(sc);
}
@Override
public boolean updateState(State oldState, Event event,
State newState, VMInstanceVO 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());
}
return false;
}
DomainRouterVO routerVM = (DomainRouterVO)vm;
SearchCriteria<DomainRouterVO> sc = StateChangeSearch.create();
sc.setParameters("id", routerVM.getId());
sc.setParameters("states", oldState);
sc.setParameters("host", routerVM.getHostId());
sc.setParameters("update", routerVM.getUpdated());
vm.incrUpdated();
UpdateBuilder ub = getUpdateBuilder(routerVM);
ub.set(routerVM, "state", newState);
ub.set(routerVM, "hostId", hostId);
ub.set(routerVM, _updateTimeAttr, new Date());
int result = update(routerVM, sc);
if (result == 0 && s_logger.isDebugEnabled()) {
DomainRouterVO vo = findById(routerVM.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(routerVM.getHostId()).append("; State=").append(routerVM.getState().toString()).append("; updated=").append(routerVM.getUpdated()).append("}");
s_logger.debug(str.toString());
}
return result > 0;
}
}

View File

@ -21,11 +21,13 @@ import java.util.List;
import com.cloud.utils.db.GenericDao;
import com.cloud.utils.fsm.StateDao;
import com.cloud.vm.SecondaryStorageVmVO;
import com.cloud.vm.State;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine;
public interface SecondaryStorageVmDao extends GenericDao<SecondaryStorageVmVO, Long> {
public interface SecondaryStorageVmDao extends GenericDao<SecondaryStorageVmVO, Long>, StateDao<State, VirtualMachine.Event, VMInstanceVO> {
public List<SecondaryStorageVmVO> getSecStorageVmListInStates(long dataCenterId, State... states);
public List<SecondaryStorageVmVO> getSecStorageVmListInStates(State... states);

View File

@ -34,9 +34,12 @@ import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.db.UpdateBuilder;
import com.cloud.vm.ConsoleProxyVO;
import com.cloud.vm.SecondaryStorageVmVO;
import com.cloud.vm.State;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachine.Event;
@Local(value={SecondaryStorageVmDao.class})
public class SecondaryStorageVmDaoImpl extends GenericDaoBase<SecondaryStorageVmVO, Long> implements SecondaryStorageVmDao {
@ -209,5 +212,40 @@ public class SecondaryStorageVmDaoImpl extends GenericDaoBase<SecondaryStorageVm
SearchCriteria<SecondaryStorageVmVO> sc = ZoneSearch.create();
sc.setParameters("zone", zoneId);
return listBy(sc);
}
@Override
public boolean updateState(State oldState, Event event,
State newState, VMInstanceVO 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());
}
return false;
}
SecondaryStorageVmVO secondaryVM = (SecondaryStorageVmVO)vm;
SearchCriteria<SecondaryStorageVmVO> sc = StateChangeSearch.create();
sc.setParameters("id", secondaryVM.getId());
sc.setParameters("states", oldState);
sc.setParameters("host", secondaryVM.getHostId());
sc.setParameters("update", secondaryVM.getUpdated());
vm.incrUpdated();
UpdateBuilder ub = getUpdateBuilder(secondaryVM);
ub.set(secondaryVM, "state", newState);
ub.set(secondaryVM, "hostId", hostId);
ub.set(secondaryVM, _updateTimeAttr, new Date());
int result = update(secondaryVM, sc);
if (result == 0 && s_logger.isDebugEnabled()) {
SecondaryStorageVmVO vo = findById(secondaryVM.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(secondaryVM.getHostId()).append("; State=").append(secondaryVM.getState().toString()).append("; updated=").append(secondaryVM.getUpdated()).append("}");
s_logger.debug(str.toString());
}
return result > 0;
}
}

View File

@ -22,11 +22,13 @@ import java.util.List;
import com.cloud.uservm.UserVm;
import com.cloud.utils.db.GenericDao;
import com.cloud.utils.fsm.StateDao;
import com.cloud.vm.State;
import com.cloud.vm.UserVmVO;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine;
public interface UserVmDao extends GenericDao<UserVmVO, Long> {
public interface UserVmDao extends GenericDao<UserVmVO, Long>, StateDao<State, VirtualMachine.Event, VMInstanceVO> {
List<UserVmVO> listByAccountId(long id);
List<UserVmVO> listByAccountAndPod(long accountId, long podId);

View File

@ -37,7 +37,9 @@ import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.UpdateBuilder;
import com.cloud.vm.State;
import com.cloud.vm.UserVmVO;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachine.Event;
@Local(value={UserVmDao.class})
public class UserVmDaoImpl extends GenericDaoBase<UserVmVO, Long> implements UserVmDao {
@ -311,4 +313,39 @@ public class UserVmDaoImpl extends GenericDaoBase<UserVmVO, Long> implements Use
return findOneBy(sc);
}
@Override
public boolean updateState(State oldState, Event event,
State newState, VMInstanceVO 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());
}
return false;
}
UserVmVO userVM = (UserVmVO)vm;
SearchCriteria<UserVmVO> sc = StateChangeSearch.create();
sc.setParameters("id", userVM.getId());
sc.setParameters("states", oldState);
sc.setParameters("host", userVM.getHostId());
sc.setParameters("update", userVM.getUpdated());
vm.incrUpdated();
UpdateBuilder ub = getUpdateBuilder(userVM);
ub.set(userVM, "state", newState);
ub.set(userVM, "hostId", hostId);
ub.set(userVM, _updateTimeAttr, new Date());
int result = update(userVM, sc);
if (result == 0 && s_logger.isDebugEnabled()) {
UserVmVO vo = findById(userVM.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(userVM.getHostId()).append("; State=").append(userVM.getState().toString()).append("; updated=").append(userVM.getUpdated()).append("}");
s_logger.debug(str.toString());
}
return result > 0;
}
}

View File

@ -1,5 +1,5 @@
package com.cloud.utils.fsm;
public interface StateListener <S,E,V> {
public boolean processStateTransitionEvent(S oldState, E event, S newState, V vo, boolean status, Long id);
public boolean processStateTransitionEvent(S oldState, E event, S newState, V vo, boolean status, Long id, StateDao<S,E,V> vmDao);
}

View File

@ -41,12 +41,12 @@ import com.cloud.utils.db.Transaction;
public class StateMachine2<S, E, V extends StateObject<S>> {
private final HashMap<S, StateEntry> _states = new HashMap<S, StateEntry>();
private final StateEntry _initialStateEntry;
private StateDao<S, E, V> _instanceDao;
private List<StateListener<S,E,V>> _listeners = new ArrayList<StateListener<S,E,V>>();
public StateMachine2(StateDao<S, E, V> dao) {
public StateMachine2() {
_initialStateEntry = new StateEntry(null);
_instanceDao = dao;
}
public void addTransition(S currentState, E event, S toState) {
@ -98,7 +98,7 @@ public class StateMachine2<S, E, V extends StateObject<S>> {
}
public boolean transitTO(V vo, E e, Long id) {
public boolean transitTO(V vo, E e, Long id, StateDao<S,E,V> dao) {
S currentState = vo.getState();
S nextState = getNextState(currentState, e);
@ -108,7 +108,7 @@ public class StateMachine2<S, E, V extends StateObject<S>> {
}
for (StateListener<S,E, V> listener : _listeners) {
transitionStatus = listener.processStateTransitionEvent(currentState, e, nextState, vo, transitionStatus, id);
transitionStatus = listener.processStateTransitionEvent(currentState, e, nextState, vo, transitionStatus, id, dao);
}
return transitionStatus;