added cluster awareness to vm start/stop

This commit is contained in:
Alex Huang 2011-02-09 09:34:18 -08:00
parent b8767bad93
commit db7bc893b9
6 changed files with 68 additions and 1 deletions

View File

@ -192,6 +192,6 @@ public class HaWorkVO {
@Override
public String toString() {
return new StringBuilder("[HA-Work:id=").append(id).append(":type=").append(workType.toString()).append(":vm=").append(instanceId).append(":state=").append(previousState.toString()).append("]").toString();
return new StringBuilder("HAWork[").append(id).append("-").append(workType).append("-").append(instanceId).append("-").append(previousState).append("-").append(step).append("]").toString();
}
}

View File

@ -39,6 +39,9 @@ public class ClusteredVirtualMachineManagerImpl extends VirtualMachineManagerImp
@Override
public void onManagementNodeLeft(List<ManagementServerHostVO> nodeList, long selfNodeId) {
for (ManagementServerHostVO node : nodeList) {
cancelWorkItems(node.getMsid());
}
}
@Override

View File

@ -17,6 +17,8 @@
*/
package com.cloud.vm;
import java.util.List;
import com.cloud.utils.db.GenericDao;
import com.cloud.vm.ItWorkVO.Step;
import com.cloud.vm.VirtualMachine.State;
@ -38,4 +40,6 @@ public interface ItWorkDao extends GenericDao<ItWorkVO, String> {
void cleanup(long wait);
boolean updateStep(ItWorkVO work, Step step);
List<ItWorkVO> listWorkInProgressFor(long nodeId);
}

View File

@ -17,6 +17,8 @@
*/
package com.cloud.vm;
import java.util.List;
import javax.ejb.Local;
import com.cloud.utils.db.GenericDaoBase;
@ -32,6 +34,7 @@ public class ItWorkDaoImpl extends GenericDaoBase<ItWorkVO, String> implements I
protected final SearchBuilder<ItWorkVO> AllFieldsSearch;
protected final SearchBuilder<ItWorkVO> CleanupSearch;
protected final SearchBuilder<ItWorkVO> OutstandingWorkSearch;
protected final SearchBuilder<ItWorkVO> WorkInProgressSearch;
protected ItWorkDaoImpl() {
super();
@ -52,6 +55,11 @@ public class ItWorkDaoImpl extends GenericDaoBase<ItWorkVO, String> implements I
OutstandingWorkSearch.and("op", OutstandingWorkSearch.entity().getType(), Op.EQ);
OutstandingWorkSearch.and("step", OutstandingWorkSearch.entity().getStep(), Op.NEQ);
OutstandingWorkSearch.done();
WorkInProgressSearch = createSearchBuilder();
WorkInProgressSearch.and("server", WorkInProgressSearch.entity().getManagementServerId(), Op.EQ);
WorkInProgressSearch.and("step", WorkInProgressSearch.entity().getStep(), Op.NIN);
WorkInProgressSearch.done();
}
@Override
@ -85,4 +93,14 @@ public class ItWorkDaoImpl extends GenericDaoBase<ItWorkVO, String> implements I
work.setStep(step);
return update(work.getId(), work);
}
@Override
public List<ItWorkVO> listWorkInProgressFor(long nodeId) {
SearchCriteria<ItWorkVO> sc = WorkInProgressSearch.create();
sc.setParameters("server", nodeId);
sc.setParameters("step", Step.Done);
return search(sc, null);
}
}

View File

@ -155,4 +155,9 @@ public class ItWorkVO {
public long getSecondsTaskHasBeenCreated() {
return InaccurateClock.getTimeInSeconds() - this.createdAt;
}
@Override
public String toString() {
return new StringBuilder("ItWork[").append(id).append("-").append(type.toString()).append("-").append(instanceId).append("-").append(step.toString()).append("]").toString();
}
}

View File

@ -409,6 +409,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene
@Override
public boolean start() {
_executor.scheduleAtFixedRate(new CleanupTask(), _cleanupInterval, _cleanupInterval, TimeUnit.SECONDS);
cancelWorkItems(_nodeId);
return true;
}
@ -446,6 +447,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene
_nodeId = _clusterMgr.getId();
_agentMgr.registerForHostEvents(this, true, true, true);
return true;
}
@ -1050,6 +1052,41 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene
}
}
protected void cancelWorkItems(long nodeId) {
GlobalLock scanLock = GlobalLock.getInternLock(this.getClass().getName());
try {
if (scanLock.lock(3)) {
try {
List<ItWorkVO> works = _workDao.listWorkInProgressFor(nodeId);
for (ItWorkVO work : works) {
s_logger.info("Handling unfinished work item: " + work);
try {
VMInstanceVO vm = _vmDao.findById(work.getInstanceId());
if (vm != null) {
if (work.getType() == State.Starting) {
_haMgr.scheduleRestart(vm, true);
} else if (work.getType() == State.Stopping) {
_haMgr.scheduleStop(vm, vm.getHostId(), WorkType.CheckStop);
} else if (work.getType() == State.Migrating) {
_haMgr.scheduleMigration(vm);
}
}
work.setStep(Step.Done);
_workDao.update(work.getId(), work);
} catch (Exception e) {
s_logger.error("Error while handling " + work, e);
}
}
} finally {
scanLock.unlock();
}
}
} finally {
scanLock.releaseRef();
}
}
@Override
public boolean migrateAway(VirtualMachine.Type vmType, long vmId, long srcHostId) throws InsufficientServerCapacityException {
VirtualMachineGuru<? extends VMInstanceVO> vmGuru = _vmGurus.get(vmType);