@@ -1706,43 +1706,62 @@ public void deltaSync(Map<String, Pair<String, State>> newStates) {
17061706 }
17071707
17081708
1709- public void fullSync (final long clusterId , Map <String , Pair <String , State >> newStates , boolean init ) {
1709+ public void fullSync (final long clusterId , Map <String , Pair <String , State >> newStates ) {
1710+ if (newStates ==null )return ;
17101711 Map <Long , AgentVmInfo > infos = convertToInfos (newStates );
17111712 Set <VMInstanceVO > set_vms = Collections .synchronizedSet (new HashSet <VMInstanceVO >());
17121713 set_vms .addAll (_vmDao .listByClusterId (clusterId ));
1713- set_vms .addAll (_vmDao .listStartingByClusterId (clusterId ));
1714-
1714+ set_vms .addAll (_vmDao .listLHByClusterId (clusterId ));
1715+
17151716 for (VMInstanceVO vm : set_vms ) {
17161717 if (vm .isRemoved () || vm .getState () == State .Destroyed || vm .getState () == State .Expunging ) continue ;
17171718 AgentVmInfo info = infos .remove (vm .getId ());
1718- if (init ){ // mark the VMs real state on initial sync
1719- VMInstanceVO castedVm = null ;
1720- if (info == null && vm .getState () == State .Running ) { // only work on VMs which were supposed to be running earlier
1721- info = new AgentVmInfo (vm .getInstanceName (), getVmGuru (vm ), vm , State .Stopped );
1722- castedVm = info .guru .findById (vm .getId ());
1723- try {
1724- Host host = _resourceMgr .findHostByGuid (info .getHostUuid ());
1725- long hostId = host == null ? (vm .getHostId () == null ? vm .getLastHostId () : vm .getHostId ()) : host .getId ();
1726- HypervisorGuru hvGuru = _hvGuruMgr .getGuru (castedVm .getHypervisorType ());
1727- Command command = compareState (hostId , castedVm , info , true , hvGuru .trackVmHostChange ());
1728- if (command != null ){
1729- Answer answer = _agentMgr .send (hostId , command );
1730- if (!answer .getResult ()) {
1731- s_logger .warn ("Failed to update state of the VM due to " + answer .getDetails ());
1732- }
1733- }
1734- } catch (Exception e ) {
1735- s_logger .warn ("Unable to update state of the VM due to exception " + e .getMessage ());
1736- e .printStackTrace ();
1737- }
1719+ VMInstanceVO castedVm = null ;
1720+ if ((info == null && (vm .getState () == State .Running || vm .getState () == State .Starting ))
1721+ || (info != null && (info .state == State .Running && vm .getState () == State .Starting )))
1722+ {
1723+ s_logger .info ("Found vm " + vm .getInstanceName () + " in inconsistent state. " + vm .getState () + " on CS while " + (info == null ? "Stopped" : "Running" ) + " on agent" );
1724+ info = new AgentVmInfo (vm .getInstanceName (), getVmGuru (vm ), vm , State .Stopped );
1725+ vm .setState (State .Running ); // set it as running and let HA take care of it
1726+ _vmDao .persist (vm );
1727+ castedVm = info .guru .findById (vm .getId ());
1728+ try {
1729+ Host host = _hostDao .findByGuid (info .getHostUuid ());
1730+ long hostId = host == null ? (vm .getHostId () == null ? vm .getLastHostId () : vm .getHostId ()) : host .getId ();
1731+ HypervisorGuru hvGuru = _hvGuruMgr .getGuru (castedVm .getHypervisorType ());
1732+ Command command = compareState (hostId , castedVm , info , true , hvGuru .trackVmHostChange ());
1733+ if (command != null ){
1734+ Answer answer = _agentMgr .send (hostId , command );
1735+ if (!answer .getResult ()) {
1736+ s_logger .warn ("Failed to update state of the VM due to " + answer .getDetails ());
1737+ }
1738+ }
1739+ } catch (Exception e ) {
1740+ s_logger .warn ("Unable to update state of the VM due to exception " + e .getMessage ());
1741+ e .printStackTrace ();
17381742 }
1739- }
1740-
1741- }
1743+ }
1744+ else
1745+ // host id can change
1746+ if (info != null && vm .getState () == State .Running ){
1747+ // check for host id changes
1748+ Host host = _hostDao .findByGuid (info .getHostUuid ());
1749+ if (host != null && (vm .getHostId () == null || host .getId () != vm .getHostId ())){
1750+ s_logger .info ("Found vm " + vm .getInstanceName () + " with inconsistent host in db, new host is " + host .getId ());
1751+ try {
1752+ stateTransitTo (vm , VirtualMachine .Event .AgentReportMigrated , host .getId ());
1753+ } catch (NoTransitionException e ) {
1754+ s_logger .warn (e .getMessage ());
1755+ }
1756+ }
1757+ }
17421758
1759+ }
1760+
17431761 for (final AgentVmInfo left : infos .values ()) {
1762+ if (VirtualMachineName .isValidVmName (left .name )) continue ; // if the vm follows cloudstack naming ignore it for stopping
17441763 try {
1745- Host host = _resourceMgr . findHostByGuid (left .getHostUuid ());
1764+ Host host = _hostDao . findByGuid (left .getHostUuid ());
17461765 if (host != null ){
17471766 s_logger .warn ("Stopping a VM which we do not have any record of " + left .name );
17481767 Answer answer = _agentMgr .send (host .getId (), cleanup (left .name ));
@@ -1754,10 +1773,11 @@ public void fullSync(final long clusterId, Map<String, Pair<String, State>> newS
17541773 s_logger .warn ("Unable to stop a VM due to " + e .getMessage ());
17551774 }
17561775 }
1757-
1776+
17581777 }
17591778
17601779
1780+
17611781 protected Map <Long , AgentVmInfo > convertToInfos (final Map <String , Pair <String , State >> newStates ) {
17621782 final HashMap <Long , AgentVmInfo > map = new HashMap <Long , AgentVmInfo >();
17631783 if (newStates == null ) {
@@ -2088,12 +2108,7 @@ public boolean processAnswers(long agentId, long seq, Answer[] answers) {
20882108 if (answer instanceof ClusterSyncAnswer ) {
20892109 ClusterSyncAnswer hs = (ClusterSyncAnswer ) answer ;
20902110 if (!hs .isExceuted ()){
2091- if (hs .isFull ()) {
2092- deltaSync (hs .getNewStates ());
2093- fullSync (hs .getClusterId (), hs .getAllStates (), false );
2094- } else if (hs .isDelta ()){
2095- deltaSync (hs .getNewStates ());
2096- }
2111+ deltaSync (hs .getNewStates ());
20972112 hs .setExecuted ();
20982113 }
20992114 } else if (!answer .getResult ()) {
@@ -2171,12 +2186,11 @@ public void processConnect(HostVO agent, StartupCommand cmd, boolean forRebalanc
21712186 StartupRoutingCommand startup = (StartupRoutingCommand ) cmd ;
21722187 HashMap <String , Pair <String , State >> allStates = startup .getClusterVMStateChanges ();
21732188 if (allStates != null ){
2174- this .fullSync (clusterId , allStates , true );
2189+ this .fullSync (clusterId , allStates );
21752190 }
21762191
21772192 // initiate the cron job
2178- ClusterSyncCommand syncCmd = new ClusterSyncCommand (Integer .parseInt (Config .ClusterDeltaSyncInterval .getDefaultValue ()),
2179- Integer .parseInt (Config .ClusterFullSyncSkipSteps .getDefaultValue ()), clusterId );
2193+ ClusterSyncCommand syncCmd = new ClusterSyncCommand (Integer .parseInt (Config .ClusterDeltaSyncInterval .getDefaultValue ()), clusterId );
21802194 try {
21812195 long seq_no = _agentMgr .send (agentId , new Commands (syncCmd ), this );
21822196 s_logger .debug ("Cluster VM sync started with jobid " + seq_no );
0 commit comments