@@ -457,12 +457,12 @@ public void advanceExpunge(String vmUuid) throws ResourceUnavailableException, O
457457 _vmDao .remove (vm .getId ());
458458 }
459459
460-
461-
462460 @ Override
463461 public boolean start () {
464462 _executor .scheduleAtFixedRate (new TransitionTask (), _pingInterval .value (), _pingInterval .value (), TimeUnit .SECONDS );
465463 _executor .scheduleAtFixedRate (new CleanupTask (), _pingInterval .value ()*2 , _pingInterval .value ()*2 , TimeUnit .SECONDS );
464+
465+ // cancel jobs left-over from last run
466466 cancelWorkItems (_nodeId );
467467
468468 return true ;
@@ -1801,42 +1801,42 @@ public VirtualMachineTO toVmTO(VirtualMachineProfile profile) {
18011801
18021802 protected void cancelWorkItems (long nodeId ) {
18031803 /*
1804- GlobalLock scanLock = GlobalLock.getInternLock("vmmgr.cancel.workitem");
1804+ GlobalLock scanLock = GlobalLock.getInternLock("vmmgr.cancel.workitem");
18051805
1806- try {
1807- if (scanLock.lock(3)) {
1808- try {
1809- List<VmWorkJobVO> works = _workDao.listWorkInProgressFor(nodeId);
1810- for (VmWorkJobVO work : works) {
1811- s_logger.info("Handling unfinished work item: " + work);
1812- try {
1813- VMInstanceVO vm = _vmDao.findById(work.getInstanceId());
1814- if (vm != null) {
1815- if (work.getType() == State.Starting) {
1816- _haMgr.scheduleRestart(vm, true);
1817- work.setManagementServerId(_nodeId);
1818- _workDao.update(work.getId(), work);
1819- } else if (work.getType() == State.Stopping) {
1820- _haMgr.scheduleStop(vm, vm.getHostId(), WorkType.CheckStop);
1821- work.setManagementServerId(_nodeId);
1822- _workDao.update(work.getId(), work);
1823- } else if (work.getType() == State.Migrating) {
1824- _haMgr.scheduleMigration(vm);
1825- work.setStep(Step.Done);
1826- _workDao.update(work.getId(), work);
1827- }
1806+ try {
1807+ if (scanLock.lock(3)) {
1808+ try {
1809+ List<VmWorkJobVO> works = _workDao.listWorkInProgressFor(nodeId);
1810+ for (VmWorkJobVO work : works) {
1811+ s_logger.info("Handling unfinished work item: " + work);
1812+ try {
1813+ VMInstanceVO vm = _vmDao.findById(work.getInstanceId());
1814+ if (vm != null) {
1815+ if (work.getType() == State.Starting) {
1816+ _haMgr.scheduleRestart(vm, true);
1817+ work.setManagementServerId(_nodeId);
1818+ _workDao.update(work.getId(), work);
1819+ } else if (work.getType() == State.Stopping) {
1820+ _haMgr.scheduleStop(vm, vm.getHostId(), WorkType.CheckStop);
1821+ work.setManagementServerId(_nodeId);
1822+ _workDao.update(work.getId(), work);
1823+ } else if (work.getType() == State.Migrating) {
1824+ _haMgr.scheduleMigration(vm);
1825+ work.setStep(Step.Done);
1826+ _workDao.update(work.getId(), work);
18281827 }
1829- } catch (Exception e) {
1830- s_logger.error("Error while handling " + work, e);
18311828 }
1829+ } catch (Exception e) {
1830+ s_logger.error("Error while handling " + work, e);
18321831 }
1833- } finally {
1834- scanLock.unlock();
18351832 }
1833+ } finally {
1834+ scanLock.unlock();
18361835 }
1837- } finally {
1838- scanLock.releaseRef();
18391836 }
1837+ } finally {
1838+ scanLock.releaseRef();
1839+ }
18401840 */
18411841 }
18421842
@@ -3475,7 +3475,7 @@ private void handlePowerOnReportWithNoPendingJobsOnVM(VMInstanceVO vm) {
34753475 }
34763476 _alertMgr .sendAlert (AlertManager .ALERT_TYPE_SYNC , vm .getDataCenterId (), vm .getPodIdToDeployIn (),
34773477 VM_SYNC_ALERT_SUBJECT , "VM " + vm .getHostName () + "(" + vm .getInstanceName () + ") state is sync-ed (" + vm .getState () + " -> Running) from out-of-context transition. VM network environment may need to be reset" );
3478- break ;
3478+ break ;
34793479
34803480 case Destroyed :
34813481 case Expunging :
@@ -3501,30 +3501,29 @@ private void handlePowerOnReportWithNoPendingJobsOnVM(VMInstanceVO vm) {
35013501
35023502 private void handlePowerOffReportWithNoPendingJobsOnVM (VMInstanceVO vm ) {
35033503
3504- // TODO :
35053504 // 1) handle left-over transitional VM states
35063505 // 2) handle out of sync stationary states, schedule force-stop to release resources
35073506 //
35083507 switch (vm .getState ()) {
35093508 case Starting :
3510- break ;
3511-
3512- case Running :
3513- break ;
3514-
35153509 case Stopping :
3516- break ;
3517-
35183510 case Stopped :
3519- break ;
3511+ case Migrating :
3512+ try {
3513+ stateTransitTo (vm , VirtualMachine .Event .FollowAgentPowerOffReport , vm .getPowerHostId ());
3514+ } catch (NoTransitionException e ) {
3515+ s_logger .warn ("Unexpected VM state transition exception, race-condition?" , e );
3516+ }
3517+ _alertMgr .sendAlert (AlertManager .ALERT_TYPE_SYNC , vm .getDataCenterId (), vm .getPodIdToDeployIn (),
3518+ VM_SYNC_ALERT_SUBJECT , "VM " + vm .getHostName () + "(" + vm .getInstanceName () + ") state is sync-ed (" + vm .getState () + " -> Stopped) from out-of-context transition." );
3519+ // TODO: we need to forcely release all resource allocation
3520+ break ;
35203521
3522+ case Running :
35213523 case Destroyed :
35223524 case Expunging :
35233525 break ;
35243526
3525- case Migrating :
3526- break ;
3527-
35283527 case Error :
35293528 default :
35303529 break ;
@@ -3582,79 +3581,99 @@ private void scanStalledVMInTransitionStateOnDisconnectedHosts() {
35823581
35833582
35843583 // VMs that in transitional state without recent power state report
3585- @ DB
35863584 private List <Long > listStalledVMInTransitionStateOnUpHost (long hostId , Date cutTime ) {
35873585 String sql = "SELECT i.* FROM vm_instance as i, host as h WHERE h.status = 'UP' " +
35883586 "AND h.id = ? AND i.power_state_update_time < ? AND i.host_id = h.id " +
35893587 "AND (i.state ='Starting' OR i.state='Stopping' OR i.state='Migrating') " +
3590- "AND i.id NOT IN (SELECT vm_instance_id FROM vm_work_job)" ;
3588+ "AND i.id NOT IN (SELECT w. vm_instance_id FROM vm_work_job AS w JOIN async_job AS j ON w.id = j.id WHERE j.job_status = ? )" ;
35913589
35923590 List <Long > l = new ArrayList <Long >();
3593- Transaction txn = Transaction .currentTxn ();;
3594- PreparedStatement pstmt = null ;
3595- try {
3596- pstmt = txn .prepareAutoCloseStatement (sql );
3597-
3598- pstmt .setLong (1 , hostId );
3599- pstmt .setString (2 , DateUtil .getDateDisplayString (TimeZone .getTimeZone ("GMT" ), cutTime ));
3600- ResultSet rs = pstmt .executeQuery ();
3601- while (rs .next ()) {
3602- l .add (rs .getLong (1 ));
3603- }
3604- } catch (SQLException e ) {
3605- } catch (Throwable e ) {
3606- }
3591+ Transaction txn = null ;
3592+ try {
3593+ txn = Transaction .open (Transaction .CLOUD_DB );
3594+
3595+ PreparedStatement pstmt = null ;
3596+ try {
3597+ pstmt = txn .prepareAutoCloseStatement (sql );
3598+
3599+ pstmt .setLong (1 , hostId );
3600+ pstmt .setString (2 , DateUtil .getDateDisplayString (TimeZone .getTimeZone ("GMT" ), cutTime ));
3601+ pstmt .setInt (3 , JobInfo .Status .IN_PROGRESS .ordinal ());
3602+ ResultSet rs = pstmt .executeQuery ();
3603+ while (rs .next ()) {
3604+ l .add (rs .getLong (1 ));
3605+ }
3606+ } catch (SQLException e ) {
3607+ } catch (Throwable e ) {
3608+ }
3609+
3610+ } finally {
3611+ if (txn != null )
3612+ txn .close ();
3613+ }
36073614 return l ;
36083615 }
36093616
36103617 // VMs that in transitional state and recently have power state update
3611- @ DB
36123618 private List <Long > listVMInTransitionStateWithRecentReportOnUpHost (long hostId , Date cutTime ) {
36133619 String sql = "SELECT i.* FROM vm_instance as i, host as h WHERE h.status = 'UP' " +
36143620 "AND h.id = ? AND i.power_state_update_time > ? AND i.host_id = h.id " +
36153621 "AND (i.state ='Starting' OR i.state='Stopping' OR i.state='Migrating') " +
3616- "AND i.id NOT IN (SELECT vm_instance_id FROM vm_work_job)" ;
3622+ "AND i.id NOT IN (SELECT w. vm_instance_id FROM vm_work_job AS w JOIN async_job AS j ON w.id = j.id WHERE j.job_status = ? )" ;
36173623
36183624 List <Long > l = new ArrayList <Long >();
3619- Transaction txn = Transaction .currentTxn ();;
3620- PreparedStatement pstmt = null ;
3621- try {
3622- pstmt = txn .prepareAutoCloseStatement (sql );
3623-
3624- pstmt .setLong (1 , hostId );
3625- pstmt .setString (2 , DateUtil .getDateDisplayString (TimeZone .getTimeZone ("GMT" ), cutTime ));
3626- ResultSet rs = pstmt .executeQuery ();
3627- while (rs .next ()) {
3628- l .add (rs .getLong (1 ));
3629- }
3630- } catch (SQLException e ) {
3631- } catch (Throwable e ) {
3632- }
3633- return l ;
3625+ Transaction txn = null ;
3626+ try {
3627+ txn = Transaction .open (Transaction .CLOUD_DB );
3628+ PreparedStatement pstmt = null ;
3629+ try {
3630+ pstmt = txn .prepareAutoCloseStatement (sql );
3631+
3632+ pstmt .setLong (1 , hostId );
3633+ pstmt .setString (2 , DateUtil .getDateDisplayString (TimeZone .getTimeZone ("GMT" ), cutTime ));
3634+ pstmt .setInt (3 , JobInfo .Status .IN_PROGRESS .ordinal ());
3635+ ResultSet rs = pstmt .executeQuery ();
3636+ while (rs .next ()) {
3637+ l .add (rs .getLong (1 ));
3638+ }
3639+ } catch (SQLException e ) {
3640+ } catch (Throwable e ) {
3641+ }
3642+ return l ;
3643+ } finally {
3644+ if (txn != null )
3645+ txn .close ();
3646+ }
36343647 }
36353648
3636- @ DB
36373649 private List <Long > listStalledVMInTransitionStateOnDisconnectedHosts (Date cutTime ) {
36383650 String sql = "SELECT i.* FROM vm_instance as i, host as h WHERE h.status != 'UP' " +
36393651 "AND i.power_state_update_time < ? AND i.host_id = h.id " +
36403652 "AND (i.state ='Starting' OR i.state='Stopping' OR i.state='Migrating') " +
3641- "AND i.id NOT IN (SELECT vm_instance_id FROM vm_work_job)" ;
3653+ "AND i.id NOT IN (SELECT w. vm_instance_id FROM vm_work_job AS w JOIN async_job AS j ON w.id = j.id WHERE j.job_status = ? )" ;
36423654
36433655 List <Long > l = new ArrayList <Long >();
3644- Transaction txn = Transaction .currentTxn ();;
3645- PreparedStatement pstmt = null ;
3656+ Transaction txn = null ;
36463657 try {
3647- pstmt = txn .prepareAutoCloseStatement (sql );
3648-
3649- pstmt .setString (1 , DateUtil .getDateDisplayString (TimeZone .getTimeZone ("GMT" ), cutTime ));
3650- ResultSet rs = pstmt .executeQuery ();
3651- while (rs .next ()) {
3652- l .add (rs .getLong (1 ));
3653- }
3654- } catch (SQLException e ) {
3655- } catch (Throwable e ) {
3658+ txn = Transaction .open (Transaction .CLOUD_DB );
3659+ PreparedStatement pstmt = null ;
3660+ try {
3661+ pstmt = txn .prepareAutoCloseStatement (sql );
3662+
3663+ pstmt .setString (1 , DateUtil .getDateDisplayString (TimeZone .getTimeZone ("GMT" ), cutTime ));
3664+ pstmt .setInt (2 , JobInfo .Status .IN_PROGRESS .ordinal ());
3665+ ResultSet rs = pstmt .executeQuery ();
3666+ while (rs .next ()) {
3667+ l .add (rs .getLong (1 ));
3668+ }
3669+ } catch (SQLException e ) {
3670+ } catch (Throwable e ) {
3671+ }
3672+ return l ;
3673+ } finally {
3674+ if (txn != null )
3675+ txn .close ();
36563676 }
3657- return l ;
36583677 }
36593678
36603679 @ Override
0 commit comments