6363import com .cloud .hypervisor .Hypervisor .HypervisorType ;
6464import com .cloud .resource .ResourceManager ;
6565import com .cloud .server .ManagementServer ;
66+ import com .cloud .service .ServiceOfferingVO ;
67+ import com .cloud .service .dao .ServiceOfferingDao ;
6668import com .cloud .storage .StorageManager ;
6769import com .cloud .storage .dao .GuestOSCategoryDao ;
6870import com .cloud .storage .dao .GuestOSDao ;
7173import com .cloud .utils .component .ManagerBase ;
7274import com .cloud .utils .concurrency .NamedThreadFactory ;
7375import com .cloud .utils .exception .CloudRuntimeException ;
76+ import com .cloud .utils .fsm .StateListener ;
7477import com .cloud .vm .VMInstanceVO ;
7578import com .cloud .vm .VirtualMachine ;
7679import com .cloud .vm .VirtualMachine .State ;
100103 * ha.retry.wait | time to wait before retrying the work item | seconds | 120 || || stop.retry.wait | time to wait
101104 * before retrying the stop | seconds | 120 || * }
102105 **/
103- @ Local (value = {HighAvailabilityManager .class })
104- public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvailabilityManager , ClusterManagerListener {
106+ @ Local (value = { HighAvailabilityManager .class })
107+ public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvailabilityManager , ClusterManagerListener ,
108+ StateListener <State , VirtualMachine .Event , VirtualMachine > {
109+
105110 protected static final Logger s_logger = Logger .getLogger (HighAvailabilityManagerImpl .class );
106111 WorkerThread [] _workers ;
107112 boolean _stopped ;
@@ -118,6 +123,10 @@ public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvai
118123 HostPodDao _podDao ;
119124 @ Inject
120125 ClusterDetailsDao _clusterDetailsDao ;
126+
127+ @ Inject
128+ ServiceOfferingDao _serviceOfferingDao ;
129+
121130 long _serverId ;
122131
123132 @ Inject
@@ -317,7 +326,6 @@ public void scheduleRestart(VMInstanceVO vm, boolean investigate) {
317326 assert false : "How do we hit this when force is true?" ;
318327 throw new CloudRuntimeException ("Caught exception even though it should be handled." , e );
319328 }
320- return ;
321329 }
322330
323331 if (vm .getHypervisorType () == HypervisorType .VMware || vm .getHypervisorType () == HypervisorType .Hyperv ) {
@@ -786,6 +794,7 @@ public boolean configure(final String name, final Map<String, Object> xmlParams)
786794 _stopped = true ;
787795
788796 _executor = Executors .newScheduledThreadPool (count , new NamedThreadFactory ("HA" ));
797+ VirtualMachine .State .getStateMachine ().registerListener (this );
789798
790799 return true ;
791800 }
@@ -934,4 +943,26 @@ public String getHaTag() {
934943 public DeploymentPlanner getHAPlanner () {
935944 return _haPlanners .get (0 );
936945 }
946+
947+ @ Override
948+ public boolean preStateTransitionEvent (State oldState , VirtualMachine .Event event , State newState , VirtualMachine vo , boolean status , Object opaque ) {
949+ return true ;
950+ }
951+
952+ @ Override
953+ public boolean postStateTransitionEvent (State oldState , VirtualMachine .Event event , State newState , VirtualMachine vo , boolean status , Object opaque ) {
954+ if (oldState == State .Running && event == VirtualMachine .Event .FollowAgentPowerOffReport && newState == State .Stopped ) {
955+ long serviceOfferingId = vo .getServiceOfferingId ();
956+
957+ ServiceOfferingVO serviceOffering = _serviceOfferingDao .findById (serviceOfferingId );
958+ if (serviceOffering != null && serviceOffering .getOfferHA ()) {
959+
960+ VMInstanceVO vm = _instanceDao .findById (vo .getId ());
961+
962+ s_logger .info ("Detected out-of-band stop of a HA enabled VM " + vm .getInstanceName () + ", will schedule restart" );
963+ scheduleRestart (vm , true );
964+ }
965+ }
966+ return true ;
967+ }
937968}
0 commit comments