Add VM level HA for hypervisors that are not integrated with native HA with CloudStack, i.e., Xen/KVM.
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/7ce5e5b1 Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/7ce5e5b1 Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/7ce5e5b1 Branch: refs/heads/master Commit: 7ce5e5b1fbcdd12e37501ec6c132219d9977c15b Parents: 57a00a8 Author: Kelven Yang <kelv...@gmail.com> Authored: Fri Feb 21 15:19:30 2014 -0800 Committer: Kelven Yang <kelv...@gmail.com> Committed: Fri Feb 28 15:35:59 2014 -0800 ---------------------------------------------------------------------- .../cloud/ha/HighAvailabilityManagerImpl.java | 37 ++++++++++++++++++-- 1 file changed, 34 insertions(+), 3 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7ce5e5b1/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java b/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java index 24a3498..4a24d63 100755 --- a/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java +++ b/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java @@ -63,6 +63,8 @@ import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.resource.ResourceManager; import com.cloud.server.ManagementServer; +import com.cloud.service.ServiceOfferingVO; +import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.StorageManager; import com.cloud.storage.dao.GuestOSCategoryDao; import com.cloud.storage.dao.GuestOSDao; @@ -71,6 +73,7 @@ import com.cloud.utils.NumbersUtil; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.concurrency.NamedThreadFactory; import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.fsm.StateListener; import com.cloud.vm.VMInstanceVO; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine.State; @@ -100,8 +103,10 @@ import com.cloud.vm.dao.VMInstanceDao; * ha.retry.wait | time to wait before retrying the work item | seconds | 120 || || stop.retry.wait | time to wait * before retrying the stop | seconds | 120 || * } **/ -@Local(value = {HighAvailabilityManager.class}) -public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvailabilityManager, ClusterManagerListener { +@Local(value = { HighAvailabilityManager.class }) +public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvailabilityManager, ClusterManagerListener, + StateListener<State, VirtualMachine.Event, VirtualMachine> { + protected static final Logger s_logger = Logger.getLogger(HighAvailabilityManagerImpl.class); WorkerThread[] _workers; boolean _stopped; @@ -118,6 +123,10 @@ public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvai HostPodDao _podDao; @Inject ClusterDetailsDao _clusterDetailsDao; + + @Inject + ServiceOfferingDao _serviceOfferingDao; + long _serverId; @Inject @@ -317,7 +326,6 @@ public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvai assert false : "How do we hit this when force is true?"; throw new CloudRuntimeException("Caught exception even though it should be handled.", e); } - return; } if (vm.getHypervisorType() == HypervisorType.VMware || vm.getHypervisorType() == HypervisorType.Hyperv) { @@ -786,6 +794,7 @@ public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvai _stopped = true; _executor = Executors.newScheduledThreadPool(count, new NamedThreadFactory("HA")); + VirtualMachine.State.getStateMachine().registerListener(this); return true; } @@ -934,4 +943,26 @@ public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvai public DeploymentPlanner getHAPlanner() { return _haPlanners.get(0); } + + @Override + public boolean preStateTransitionEvent(State oldState, VirtualMachine.Event event, State newState, VirtualMachine vo, boolean status, Object opaque) { + return true; + } + + @Override + public boolean postStateTransitionEvent(State oldState, VirtualMachine.Event event, State newState, VirtualMachine vo, boolean status, Object opaque) { + if (oldState == State.Running && event == VirtualMachine.Event.FollowAgentPowerOffReport && newState == State.Stopped) { + long serviceOfferingId = vo.getServiceOfferingId(); + + ServiceOfferingVO serviceOffering = _serviceOfferingDao.findById(serviceOfferingId); + if (serviceOffering != null && serviceOffering.getOfferHA()) { + + VMInstanceVO vm = _instanceDao.findById(vo.getId()); + + s_logger.info("Detected out-of-band stop of a HA enabled VM " + vm.getInstanceName() + ", will schedule restart"); + scheduleRestart(vm, true); + } + } + return true; + } }