mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
fix for migration
This commit is contained in:
parent
d17beeb348
commit
b7cdae2688
@ -121,5 +121,32 @@ public interface DeploymentPlanner extends Adapter {
|
|||||||
|
|
||||||
return false;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -38,6 +38,8 @@ public interface VirtualMachine extends RunningOn, ControlledEntity {
|
|||||||
ExpungeOperation,
|
ExpungeOperation,
|
||||||
OperationSucceeded,
|
OperationSucceeded,
|
||||||
OperationFailed,
|
OperationFailed,
|
||||||
|
MigrationFailedOnSource,
|
||||||
|
MigrationFailedOnDest,
|
||||||
OperationRetry,
|
OperationRetry,
|
||||||
OperationCancelled
|
OperationCancelled
|
||||||
};
|
};
|
||||||
|
|||||||
@ -2159,9 +2159,9 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, ResourceS
|
|||||||
if (capacityVOCpus != null && !capacityVOCpus.isEmpty()) {
|
if (capacityVOCpus != null && !capacityVOCpus.isEmpty()) {
|
||||||
CapacityVO CapacityVOCpu = capacityVOCpus.get(0);
|
CapacityVO CapacityVOCpu = capacityVOCpus.get(0);
|
||||||
long newTotalCpu = (long)(server.getCpus().longValue() * server.getSpeed().longValue()*_cpuOverProvisioningFactor);
|
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);
|
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.setReservedCapacity(0);
|
||||||
CapacityVOCpu.setTotalCapacity(newTotalCpu);
|
CapacityVOCpu.setTotalCapacity(newTotalCpu);
|
||||||
} else {
|
} else {
|
||||||
@ -2180,12 +2180,12 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, ResourceS
|
|||||||
capacityMem.addAnd("dataCenterId", SearchCriteria.Op.EQ, server.getDataCenterId());
|
capacityMem.addAnd("dataCenterId", SearchCriteria.Op.EQ, server.getDataCenterId());
|
||||||
capacityMem.addAnd("podId", SearchCriteria.Op.EQ, server.getPodId());
|
capacityMem.addAnd("podId", SearchCriteria.Op.EQ, server.getPodId());
|
||||||
capacityMem.addAnd("capacityType", SearchCriteria.Op.EQ, CapacityVO.CAPACITY_TYPE_MEMORY);
|
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()) {
|
if (capacityVOMems != null && !capacityVOMems.isEmpty()) {
|
||||||
CapacityVO CapacityVOMem = capacityVOMems.get(0);
|
CapacityVO CapacityVOMem = capacityVOMems.get(0);
|
||||||
long newTotalMem = server.getTotalMemory();
|
long newTotalMem = server.getTotalMemory();
|
||||||
if (CapacityVOMem.getTotalCapacity() < newTotalMem) {
|
if (CapacityVOMem.getTotalCapacity() <= newTotalMem || (CapacityVOMem.getUsedCapacity() + CapacityVOMem.getReservedCapacity() <= newTotalMem)) {
|
||||||
CapacityVOMem.setTotalCapacity(newTotalMem);
|
CapacityVOMem.setTotalCapacity(newTotalMem);
|
||||||
} else if (CapacityVOMem.getUsedCapacity() + CapacityVOMem.getReservedCapacity() > newTotalMem && CapacityVOMem.getUsedCapacity() < newTotalMem) {
|
} else if (CapacityVOMem.getUsedCapacity() + CapacityVOMem.getReservedCapacity() > newTotalMem && CapacityVOMem.getUsedCapacity() < newTotalMem) {
|
||||||
CapacityVOMem.setReservedCapacity(0);
|
CapacityVOMem.setReservedCapacity(0);
|
||||||
|
|||||||
@ -1,11 +1,12 @@
|
|||||||
package com.cloud.deploy;
|
package com.cloud.deploy;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.ejb.Local;
|
import javax.ejb.Local;
|
||||||
|
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import com.cloud.capacity.CapacityVO;
|
import com.cloud.capacity.CapacityVO;
|
||||||
import com.cloud.capacity.dao.CapacityDao;
|
import com.cloud.capacity.dao.CapacityDao;
|
||||||
import com.cloud.dc.ClusterVO;
|
import com.cloud.dc.ClusterVO;
|
||||||
@ -26,7 +27,6 @@ import com.cloud.offering.ServiceOffering;
|
|||||||
import com.cloud.org.Cluster;
|
import com.cloud.org.Cluster;
|
||||||
import com.cloud.storage.GuestOSCategoryVO;
|
import com.cloud.storage.GuestOSCategoryVO;
|
||||||
import com.cloud.storage.GuestOSVO;
|
import com.cloud.storage.GuestOSVO;
|
||||||
import com.cloud.storage.VMTemplateVO;
|
|
||||||
import com.cloud.storage.dao.GuestOSCategoryDao;
|
import com.cloud.storage.dao.GuestOSCategoryDao;
|
||||||
import com.cloud.storage.dao.GuestOSDao;
|
import com.cloud.storage.dao.GuestOSDao;
|
||||||
import com.cloud.template.VirtualMachineTemplate;
|
import com.cloud.template.VirtualMachineTemplate;
|
||||||
@ -35,8 +35,10 @@ import com.cloud.utils.db.DB;
|
|||||||
import com.cloud.utils.db.Transaction;
|
import com.cloud.utils.db.Transaction;
|
||||||
import com.cloud.vm.VirtualMachine;
|
import com.cloud.vm.VirtualMachine;
|
||||||
import com.cloud.vm.VirtualMachineProfile;
|
import com.cloud.vm.VirtualMachineProfile;
|
||||||
|
|
||||||
@Local(value=DeploymentPlanner.class)
|
@Local(value=DeploymentPlanner.class)
|
||||||
public class FirstFitPlanner extends PlannerBase implements DeploymentPlanner {
|
public class FirstFitPlanner extends PlannerBase implements DeploymentPlanner {
|
||||||
|
private static final Logger s_logger = Logger.getLogger(FirstFitPlanner.class);
|
||||||
@Inject private HostDao _hostDao;
|
@Inject private HostDao _hostDao;
|
||||||
@Inject private CapacityDao _capacityDao;
|
@Inject private CapacityDao _capacityDao;
|
||||||
@Inject private DataCenterDao _dcDao;
|
@Inject private DataCenterDao _dcDao;
|
||||||
@ -56,10 +58,12 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentPlanner {
|
|||||||
int cpu_requested = offering.getCpu() * offering.getSpeed();
|
int cpu_requested = offering.getCpu() * offering.getSpeed();
|
||||||
long ram_requested = offering.getRamSize() * 1024L * 1024L;
|
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) {
|
if (vm.getLastHostId() != null) {
|
||||||
HostVO host = _hostDao.findById(vm.getLastHostId());
|
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);
|
boolean canDepployToLastHost = deployToHost(host, cpu_requested, ram_requested, true, avoid);
|
||||||
if (canDepployToLastHost) {
|
if (canDepployToLastHost) {
|
||||||
Pod pod = _podDao.findById(vm.getPodId());
|
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*/
|
/*Go through all the pods/clusters under zone*/
|
||||||
List<HostPodVO> pods;
|
List<HostPodVO> pods = null;
|
||||||
if (plan.getPodId() != null) {
|
if (plan.getPodId() != null) {
|
||||||
|
HostPodVO pod = _podDao.findById(plan.getPodId());
|
||||||
|
if (pod != null && dc.getId() == pod.getDataCenterId()) {
|
||||||
pods = new ArrayList<HostPodVO>(1);
|
pods = new ArrayList<HostPodVO>(1);
|
||||||
pods.add(_podDao.findById(plan.getPodId()));
|
pods.add(pod);
|
||||||
} else {
|
} else {
|
||||||
pods = _podDao.listByDataCenterId(plan.getDataCenterId());
|
s_logger.debug("Can't enforce the pod selector");
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pods == null)
|
||||||
|
pods = _podDao.listByDataCenterId(plan.getDataCenterId());
|
||||||
|
|
||||||
//Collections.shuffle(pods);
|
//Collections.shuffle(pods);
|
||||||
|
|
||||||
for (HostPodVO hostPod : pods) {
|
for (HostPodVO hostPod : pods) {
|
||||||
|
if (avoid.shouldAvoid(hostPod)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
//Collections.shuffle(clusters);
|
//Collections.shuffle(clusters);
|
||||||
List<ClusterVO> clusters;
|
List<ClusterVO> clusters = null;
|
||||||
if (plan.getClusterId() != null) {
|
if (plan.getClusterId() != null) {
|
||||||
|
ClusterVO cluster = _clusterDao.findById(plan.getClusterId());
|
||||||
|
if (cluster != null && hostPod.getId() == cluster.getPodId()) {
|
||||||
clusters = new ArrayList<ClusterVO>(1);
|
clusters = new ArrayList<ClusterVO>(1);
|
||||||
clusters.add(_clusterDao.findById(plan.getClusterId()));
|
clusters.add(cluster);
|
||||||
} else {
|
} else {
|
||||||
|
s_logger.debug("Can't enforce the cluster selector");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clusters == null) {
|
||||||
clusters = _clusterDao.listByPodId(hostPod.getId());
|
clusters = _clusterDao.listByPodId(hostPod.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ClusterVO clusterVO : clusters) {
|
for (ClusterVO clusterVO : clusters) {
|
||||||
|
if (avoid.shouldAvoid(clusterVO)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (clusterVO.getHypervisorType() != vmProfile.getHypervisorType()) {
|
if (clusterVO.getHypervisorType() != vmProfile.getHypervisorType()) {
|
||||||
|
avoid.addCluster(clusterVO.getId());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,8 +138,11 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentPlanner {
|
|||||||
Host host = _hostDao.findById(hostVO.getId());
|
Host host = _hostDao.findById(hostVO.getId());
|
||||||
return new DeployDestination(dc, pod, cluster, host);
|
return new DeployDestination(dc, pod, cluster, host);
|
||||||
}
|
}
|
||||||
|
avoid.addHost(hostVO.getId());
|
||||||
}
|
}
|
||||||
|
avoid.addCluster(clusterVO.getId());
|
||||||
}
|
}
|
||||||
|
avoid.addPod(hostPod.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@ -777,7 +777,7 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager {
|
|||||||
HostPodVO podVO = _podDao.findById(vm.getPodId());
|
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.");
|
_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());
|
_agentMgr.maintenanceFailed(vm.getHostId());
|
||||||
|
|
||||||
Command cleanup = mgr.cleanup(vm, null);
|
Command cleanup = mgr.cleanup(vm, null);
|
||||||
@ -807,7 +807,7 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager {
|
|||||||
} catch (final OperationTimedoutException e) {
|
} catch (final OperationTimedoutException e) {
|
||||||
s_logger.warn("Operation timed outfor " + vm.toString());
|
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;
|
return (System.currentTimeMillis() >> 10) + _migrateRetryInterval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -94,6 +94,10 @@ import com.cloud.utils.exception.CloudRuntimeException;
|
|||||||
import com.cloud.utils.fsm.StateMachine2;
|
import com.cloud.utils.fsm.StateMachine2;
|
||||||
import com.cloud.vm.ItWorkVO.Type;
|
import com.cloud.vm.ItWorkVO.Type;
|
||||||
import com.cloud.vm.VirtualMachine.Event;
|
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;
|
import com.cloud.vm.dao.VMInstanceDao;
|
||||||
|
|
||||||
@Local(value=VmManager.class)
|
@Local(value=VmManager.class)
|
||||||
@ -113,6 +117,10 @@ public class MauriceMoss implements VmManager, ClusterManagerListener {
|
|||||||
@Inject private ClusterManager _clusterMgr;
|
@Inject private ClusterManager _clusterMgr;
|
||||||
@Inject private ItWorkDao _workDao;
|
@Inject private ItWorkDao _workDao;
|
||||||
@Inject private CapacityDao _capacityDao;
|
@Inject private CapacityDao _capacityDao;
|
||||||
|
@Inject private UserVmDao _userVmDao;
|
||||||
|
@Inject private DomainRouterDao _routerDao;
|
||||||
|
@Inject private ConsoleProxyDao _consoleDao;
|
||||||
|
@Inject private SecondaryStorageVmDao _secondaryDao;
|
||||||
|
|
||||||
@Inject(adapter=DeploymentPlanner.class)
|
@Inject(adapter=DeploymentPlanner.class)
|
||||||
private Adapters<DeploymentPlanner> _planners;
|
private Adapters<DeploymentPlanner> _planners;
|
||||||
@ -340,13 +348,15 @@ public class MauriceMoss implements VmManager, ClusterManagerListener {
|
|||||||
|
|
||||||
ExcludeList avoids = new ExcludeList();
|
ExcludeList avoids = new ExcludeList();
|
||||||
int retry = _retry;
|
int retry = _retry;
|
||||||
|
DeployDestination dest = null;
|
||||||
while (retry-- != 0) { // It's != so that it can match -1.
|
while (retry-- != 0) { // It's != so that it can match -1.
|
||||||
|
/*this will release resource allocated on dest host*/
|
||||||
if (retry < (_retry -1)) {
|
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);
|
VirtualMachineProfileImpl<T> vmProfile = new VirtualMachineProfileImpl<T>(vm, template, offering, null, params);
|
||||||
DeployDestination dest = null;
|
|
||||||
for (DeploymentPlanner planner : _planners) {
|
for (DeploymentPlanner planner : _planners) {
|
||||||
dest = planner.plan(vmProfile, plan, avoids);
|
dest = planner.plan(vmProfile, plan, avoids);
|
||||||
if (dest != null) {
|
if (dest != null) {
|
||||||
@ -366,7 +376,7 @@ public class MauriceMoss implements VmManager, ClusterManagerListener {
|
|||||||
try {
|
try {
|
||||||
_storageMgr.prepare(vmProfile, dest);
|
_storageMgr.prepare(vmProfile, dest);
|
||||||
} catch (ConcurrentOperationException e) {
|
} catch (ConcurrentOperationException e) {
|
||||||
stateTransitTo(vm, Event.OperationFailed, null);
|
stateTransitTo(vm, Event.OperationFailed, dest.getHost().getId());
|
||||||
throw e;
|
throw e;
|
||||||
} catch (StorageUnavailableException e) {
|
} catch (StorageUnavailableException e) {
|
||||||
s_logger.warn("Unable to contact storage.", 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()) {
|
if (s_logger.isDebugEnabled()) {
|
||||||
s_logger.debug("Creation complete for VM " + vm);
|
s_logger.debug("Creation complete for VM " + vm);
|
||||||
@ -510,7 +520,7 @@ public class MauriceMoss implements VmManager, ClusterManagerListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void setStateMachine() {
|
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(null, VirtualMachine.Event.CreateRequested, State.Creating);
|
||||||
_stateMachine.addTransition(State.Creating, VirtualMachine.Event.OperationSucceeded, State.Stopped);
|
_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.MigrationRequested, State.Migrating);
|
||||||
_stateMachine.addTransition(State.Migrating, VirtualMachine.Event.OperationSucceeded, State.Running);
|
_stateMachine.addTransition(State.Migrating, VirtualMachine.Event.OperationSucceeded, State.Running);
|
||||||
_stateMachine.addTransition(State.Migrating, VirtualMachine.Event.OperationFailed, 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.AgentReportRunning, State.Running);
|
||||||
_stateMachine.addTransition(State.Migrating, VirtualMachine.Event.AgentReportStopped, State.Stopped);
|
_stateMachine.addTransition(State.Migrating, VirtualMachine.Event.AgentReportStopped, State.Stopped);
|
||||||
_stateMachine.addTransition(State.Stopping, VirtualMachine.Event.OperationSucceeded, 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.OperationFailed, State.Expunging);
|
||||||
_stateMachine.addTransition(State.Expunging, VirtualMachine.Event.ExpungeOperation, 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
|
@Override
|
||||||
public boolean stateTransitTo(VMInstanceVO vm, VirtualMachine.Event e, Long id) {
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import com.cloud.capacity.dao.CapacityDao;
|
|||||||
import com.cloud.service.ServiceOfferingVO;
|
import com.cloud.service.ServiceOfferingVO;
|
||||||
import com.cloud.service.dao.ServiceOfferingDao;
|
import com.cloud.service.dao.ServiceOfferingDao;
|
||||||
import com.cloud.utils.db.Transaction;
|
import com.cloud.utils.db.Transaction;
|
||||||
|
import com.cloud.utils.fsm.StateDao;
|
||||||
import com.cloud.utils.fsm.StateListener;
|
import com.cloud.utils.fsm.StateListener;
|
||||||
import com.cloud.vm.VirtualMachine.Event;
|
import com.cloud.vm.VirtualMachine.Event;
|
||||||
import com.cloud.vm.dao.VMInstanceDao;
|
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);
|
private static final Logger s_logger = Logger.getLogger(VMStateListener.class);
|
||||||
CapacityDao _capacityDao;
|
CapacityDao _capacityDao;
|
||||||
ServiceOfferingDao _offeringDao;
|
ServiceOfferingDao _offeringDao;
|
||||||
VMInstanceDao _vmDao;
|
|
||||||
|
|
||||||
public VMStateListener(CapacityDao capacityDao, ServiceOfferingDao offering, VMInstanceDao vmDao) {
|
|
||||||
|
public VMStateListener(CapacityDao capacityDao, ServiceOfferingDao offering) {
|
||||||
_capacityDao = capacityDao;
|
_capacityDao = capacityDao;
|
||||||
_offeringDao = offering;
|
_offeringDao = offering;
|
||||||
this._vmDao = vmDao;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean processStateTransitionEvent(State oldState,
|
public boolean processStateTransitionEvent(State oldState,
|
||||||
Event event, State newState, VMInstanceVO vm, boolean transitionStatus, Long id) {
|
Event event, State newState, VMInstanceVO vm, boolean transitionStatus, Long id, StateDao<State, VirtualMachine.Event, VMInstanceVO> vmDao) {
|
||||||
if (oldState == State.Starting) {
|
s_logger.debug("VM state transitted from :" + oldState + " to " + newState + " with event: " + event +
|
||||||
if (event == Event.OperationRetry || event == Event.OperationFailed) {
|
"vm's original host id: " + vm.getHostId() + " new host id: " + id);
|
||||||
releaseResource(vm, false, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!transitionStatus) {
|
if (!transitionStatus) {
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Transaction txn = Transaction.open(Transaction.CLOUD_DB);
|
Transaction txn = Transaction.open(Transaction.CLOUD_DB);
|
||||||
@ -42,53 +38,58 @@ public class VMStateListener implements StateListener<State, VirtualMachine.Even
|
|||||||
|
|
||||||
if (oldState == State.Starting) {
|
if (oldState == State.Starting) {
|
||||||
if (event == Event.OperationSucceeded) {
|
if (event == Event.OperationSucceeded) {
|
||||||
vm.setLastHostId(id);
|
if (vm.getLastHostId() != null && vm.getLastHostId() != id) {
|
||||||
_vmDao.update(vm.getId(), vm);
|
/*need to release the reserved capacity on lasthost*/
|
||||||
|
releaseResource(vm, true, false, vm.getLastHostId());
|
||||||
}
|
}
|
||||||
|
vm.setLastHostId(id);
|
||||||
|
|
||||||
|
} 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) {
|
} else if (oldState == State.Running) {
|
||||||
if (event == Event.AgentReportStopped) {
|
if (event == Event.AgentReportStopped) {
|
||||||
releaseResource(vm, false, true);
|
releaseResource(vm, false, true, vm.getHostId());
|
||||||
}
|
}
|
||||||
} else if (oldState == State.Migrating) {
|
} else if (oldState == State.Migrating) {
|
||||||
if (event == Event.AgentReportStopped) {
|
if (event == Event.AgentReportStopped) {
|
||||||
/*Release capacity from original host*/
|
/*Release capacity from original host*/
|
||||||
releaseResource(vm, false, true);
|
releaseResource(vm, false, true, vm.getHostId());
|
||||||
} else if (event == Event.OperationFailed) {
|
} else if (event == Event.MigrationFailedOnSource) {
|
||||||
if (vm.getHostId() == id) {
|
/*release capacity from dest host*/
|
||||||
/*Migrate command failed, vm still on the orginal host*/
|
releaseResource(vm, false, false, id);
|
||||||
/*no change for the capacity*/
|
id = vm.getHostId();
|
||||||
} else {
|
} else if (event == Event.MigrationFailedOnDest) {
|
||||||
/*CheckVirtualMachineCommand cmd got exception, assume vm is running on dest host*/
|
/*release capacify from original host*/
|
||||||
/*Need to clean up capacity*/
|
releaseResource(vm, false, false, vm.getHostId());
|
||||||
releaseResource(vm, false, false);
|
|
||||||
if (id != null) {
|
|
||||||
addResource(vm, id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (event == Event.OperationSucceeded) {
|
} else if (event == Event.OperationSucceeded) {
|
||||||
releaseResource(vm, false, false);
|
releaseResource(vm, false, false, vm.getHostId());
|
||||||
addResource(vm, id);
|
|
||||||
}
|
}
|
||||||
} else if (oldState == State.Stopping) {
|
} else if (oldState == State.Stopping) {
|
||||||
if (event == Event.AgentReportStopped || event == Event.OperationSucceeded) {
|
if (event == Event.AgentReportStopped || event == Event.OperationSucceeded) {
|
||||||
releaseResource(vm, false, true);
|
releaseResource(vm, false, true, vm.getHostId());
|
||||||
}
|
}
|
||||||
} else if (oldState == State.Stopped) {
|
} else if (oldState == State.Stopped) {
|
||||||
if (event == Event.DestroyRequested) {
|
if (event == Event.DestroyRequested) {
|
||||||
releaseResource(vm, true, false);
|
releaseResource(vm, true, false, vm.getHostId());
|
||||||
|
|
||||||
vm.setLastHostId(null);
|
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) {
|
if (transitionStatus) {
|
||||||
txn.commit();
|
txn.commit();
|
||||||
} else {
|
} else {
|
||||||
|
s_logger.debug("Failed to transit vm's state");
|
||||||
txn.rollback();
|
txn.rollback();
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
s_logger.debug("Failed to transit vm's state, due to " + e.getMessage());
|
||||||
txn.rollback();
|
txn.rollback();
|
||||||
} finally {
|
} finally {
|
||||||
txn.close();
|
txn.close();
|
||||||
@ -97,10 +98,15 @@ public class VMStateListener implements StateListener<State, VirtualMachine.Even
|
|||||||
return transitionStatus;
|
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());
|
ServiceOfferingVO svo = _offeringDao.findById(vm.getServiceOfferingId());
|
||||||
CapacityVO capacityCpu = _capacityDao.findByHostIdType(vm.getHostId(), CapacityVO.CAPACITY_TYPE_CPU);
|
CapacityVO capacityCpu = _capacityDao.findByHostIdType(hostId, CapacityVO.CAPACITY_TYPE_CPU);
|
||||||
CapacityVO capacityMemory = _capacityDao.findByHostIdType(vm.getHostId(), CapacityVO.CAPACITY_TYPE_MEMORY);
|
CapacityVO capacityMemory = _capacityDao.findByHostIdType(hostId, CapacityVO.CAPACITY_TYPE_MEMORY);
|
||||||
|
|
||||||
|
if (capacityCpu == null || capacityMemory == null || svo == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int vmCPU = svo.getCpu() * svo.getSpeed();
|
int vmCPU = svo.getCpu() * svo.getSpeed();
|
||||||
long vmMem = svo.getRamSize() * 1024L * 1024L;
|
long vmMem = svo.getRamSize() * 1024L * 1024L;
|
||||||
|
|
||||||
|
|||||||
@ -24,11 +24,13 @@ import java.util.List;
|
|||||||
import com.cloud.info.ConsoleProxyLoadInfo;
|
import com.cloud.info.ConsoleProxyLoadInfo;
|
||||||
import com.cloud.utils.Pair;
|
import com.cloud.utils.Pair;
|
||||||
import com.cloud.utils.db.GenericDao;
|
import com.cloud.utils.db.GenericDao;
|
||||||
|
import com.cloud.utils.fsm.StateDao;
|
||||||
import com.cloud.vm.ConsoleProxyVO;
|
import com.cloud.vm.ConsoleProxyVO;
|
||||||
import com.cloud.vm.State;
|
import com.cloud.vm.State;
|
||||||
|
import com.cloud.vm.VMInstanceVO;
|
||||||
import com.cloud.vm.VirtualMachine;
|
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);
|
public void update(long id, int activeSession, Date updateTime, byte[] sessionDetails);
|
||||||
|
|
||||||
|
|||||||
@ -39,7 +39,9 @@ import com.cloud.utils.db.Transaction;
|
|||||||
import com.cloud.utils.db.UpdateBuilder;
|
import com.cloud.utils.db.UpdateBuilder;
|
||||||
import com.cloud.vm.ConsoleProxyVO;
|
import com.cloud.vm.ConsoleProxyVO;
|
||||||
import com.cloud.vm.State;
|
import com.cloud.vm.State;
|
||||||
|
import com.cloud.vm.VMInstanceVO;
|
||||||
import com.cloud.vm.VirtualMachine;
|
import com.cloud.vm.VirtualMachine;
|
||||||
|
import com.cloud.vm.VirtualMachine.Event;
|
||||||
|
|
||||||
@Local(value={ConsoleProxyDao.class})
|
@Local(value={ConsoleProxyDao.class})
|
||||||
public class ConsoleProxyDaoImpl extends GenericDaoBase<ConsoleProxyVO, Long> implements ConsoleProxyDao {
|
public class ConsoleProxyDaoImpl extends GenericDaoBase<ConsoleProxyVO, Long> implements ConsoleProxyDao {
|
||||||
@ -387,4 +389,39 @@ public class ConsoleProxyDaoImpl extends GenericDaoBase<ConsoleProxyVO, Long> im
|
|||||||
}
|
}
|
||||||
return l;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,14 +21,17 @@ import java.util.List;
|
|||||||
|
|
||||||
import com.cloud.network.router.VirtualRouter.Role;
|
import com.cloud.network.router.VirtualRouter.Role;
|
||||||
import com.cloud.utils.db.GenericDao;
|
import com.cloud.utils.db.GenericDao;
|
||||||
|
import com.cloud.utils.fsm.StateDao;
|
||||||
import com.cloud.vm.DomainRouterVO;
|
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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* DomainRouterDao implements
|
* DomainRouterDao implements
|
||||||
*/
|
*/
|
||||||
public interface DomainRouterDao extends GenericDao<DomainRouterVO, Long> {
|
public interface DomainRouterDao extends GenericDao<DomainRouterVO, Long>, StateDao<State, VirtualMachine.Event, VMInstanceVO> {
|
||||||
//@Deprecated
|
//@Deprecated
|
||||||
//public boolean updateIf(DomainRouterVO router, State state, State... ifStates);
|
//public boolean updateIf(DomainRouterVO router, State state, State... ifStates);
|
||||||
|
|
||||||
|
|||||||
@ -36,9 +36,12 @@ import com.cloud.utils.db.SearchCriteria;
|
|||||||
import com.cloud.utils.db.Transaction;
|
import com.cloud.utils.db.Transaction;
|
||||||
import com.cloud.utils.db.UpdateBuilder;
|
import com.cloud.utils.db.UpdateBuilder;
|
||||||
import com.cloud.utils.exception.CloudRuntimeException;
|
import com.cloud.utils.exception.CloudRuntimeException;
|
||||||
|
import com.cloud.vm.ConsoleProxyVO;
|
||||||
import com.cloud.vm.DomainRouterVO;
|
import com.cloud.vm.DomainRouterVO;
|
||||||
import com.cloud.vm.State;
|
import com.cloud.vm.State;
|
||||||
|
import com.cloud.vm.VMInstanceVO;
|
||||||
import com.cloud.vm.VirtualMachine;
|
import com.cloud.vm.VirtualMachine;
|
||||||
|
import com.cloud.vm.VirtualMachine.Event;
|
||||||
|
|
||||||
@Local(value = { DomainRouterDao.class })
|
@Local(value = { DomainRouterDao.class })
|
||||||
public class DomainRouterDaoImpl extends GenericDaoBase<DomainRouterVO, Long> implements DomainRouterDao {
|
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);
|
sc.setParameters("network", networkConfigurationId);
|
||||||
return findOneBy(sc);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,11 +21,13 @@ import java.util.List;
|
|||||||
|
|
||||||
|
|
||||||
import com.cloud.utils.db.GenericDao;
|
import com.cloud.utils.db.GenericDao;
|
||||||
|
import com.cloud.utils.fsm.StateDao;
|
||||||
import com.cloud.vm.SecondaryStorageVmVO;
|
import com.cloud.vm.SecondaryStorageVmVO;
|
||||||
import com.cloud.vm.State;
|
import com.cloud.vm.State;
|
||||||
|
import com.cloud.vm.VMInstanceVO;
|
||||||
import com.cloud.vm.VirtualMachine;
|
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(long dataCenterId, State... states);
|
||||||
public List<SecondaryStorageVmVO> getSecStorageVmListInStates(State... states);
|
public List<SecondaryStorageVmVO> getSecStorageVmListInStates(State... states);
|
||||||
|
|||||||
@ -34,9 +34,12 @@ import com.cloud.utils.db.SearchBuilder;
|
|||||||
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.db.UpdateBuilder;
|
import com.cloud.utils.db.UpdateBuilder;
|
||||||
|
import com.cloud.vm.ConsoleProxyVO;
|
||||||
import com.cloud.vm.SecondaryStorageVmVO;
|
import com.cloud.vm.SecondaryStorageVmVO;
|
||||||
import com.cloud.vm.State;
|
import com.cloud.vm.State;
|
||||||
|
import com.cloud.vm.VMInstanceVO;
|
||||||
import com.cloud.vm.VirtualMachine;
|
import com.cloud.vm.VirtualMachine;
|
||||||
|
import com.cloud.vm.VirtualMachine.Event;
|
||||||
|
|
||||||
@Local(value={SecondaryStorageVmDao.class})
|
@Local(value={SecondaryStorageVmDao.class})
|
||||||
public class SecondaryStorageVmDaoImpl extends GenericDaoBase<SecondaryStorageVmVO, Long> implements SecondaryStorageVmDao {
|
public class SecondaryStorageVmDaoImpl extends GenericDaoBase<SecondaryStorageVmVO, Long> implements SecondaryStorageVmDao {
|
||||||
@ -210,4 +213,39 @@ public class SecondaryStorageVmDaoImpl extends GenericDaoBase<SecondaryStorageVm
|
|||||||
sc.setParameters("zone", zoneId);
|
sc.setParameters("zone", zoneId);
|
||||||
return listBy(sc);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,11 +22,13 @@ import java.util.List;
|
|||||||
|
|
||||||
import com.cloud.uservm.UserVm;
|
import com.cloud.uservm.UserVm;
|
||||||
import com.cloud.utils.db.GenericDao;
|
import com.cloud.utils.db.GenericDao;
|
||||||
|
import com.cloud.utils.fsm.StateDao;
|
||||||
import com.cloud.vm.State;
|
import com.cloud.vm.State;
|
||||||
import com.cloud.vm.UserVmVO;
|
import com.cloud.vm.UserVmVO;
|
||||||
|
import com.cloud.vm.VMInstanceVO;
|
||||||
import com.cloud.vm.VirtualMachine;
|
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> listByAccountId(long id);
|
||||||
|
|
||||||
List<UserVmVO> listByAccountAndPod(long accountId, long podId);
|
List<UserVmVO> listByAccountAndPod(long accountId, long podId);
|
||||||
|
|||||||
@ -37,7 +37,9 @@ import com.cloud.utils.db.SearchCriteria;
|
|||||||
import com.cloud.utils.db.UpdateBuilder;
|
import com.cloud.utils.db.UpdateBuilder;
|
||||||
import com.cloud.vm.State;
|
import com.cloud.vm.State;
|
||||||
import com.cloud.vm.UserVmVO;
|
import com.cloud.vm.UserVmVO;
|
||||||
|
import com.cloud.vm.VMInstanceVO;
|
||||||
import com.cloud.vm.VirtualMachine;
|
import com.cloud.vm.VirtualMachine;
|
||||||
|
import com.cloud.vm.VirtualMachine.Event;
|
||||||
|
|
||||||
@Local(value={UserVmDao.class})
|
@Local(value={UserVmDao.class})
|
||||||
public class UserVmDaoImpl extends GenericDaoBase<UserVmVO, Long> implements UserVmDao {
|
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);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
package com.cloud.utils.fsm;
|
package com.cloud.utils.fsm;
|
||||||
|
|
||||||
public interface StateListener <S,E,V> {
|
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);
|
||||||
}
|
}
|
||||||
@ -41,12 +41,12 @@ import com.cloud.utils.db.Transaction;
|
|||||||
public class StateMachine2<S, E, V extends StateObject<S>> {
|
public class StateMachine2<S, E, V extends StateObject<S>> {
|
||||||
private final HashMap<S, StateEntry> _states = new HashMap<S, StateEntry>();
|
private final HashMap<S, StateEntry> _states = new HashMap<S, StateEntry>();
|
||||||
private final StateEntry _initialStateEntry;
|
private final StateEntry _initialStateEntry;
|
||||||
private StateDao<S, E, V> _instanceDao;
|
|
||||||
private List<StateListener<S,E,V>> _listeners = new ArrayList<StateListener<S,E,V>>();
|
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);
|
_initialStateEntry = new StateEntry(null);
|
||||||
_instanceDao = dao;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addTransition(S currentState, E event, S toState) {
|
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 currentState = vo.getState();
|
||||||
S nextState = getNextState(currentState, e);
|
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) {
|
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;
|
return transitionStatus;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user