CLOUDSTACK-7742:

root cause:
when vmsync reports system VM is down, CCP doesn't release the VM resource before starting it.
fix:
make sure cleanup is called for a VM when it is reported as Stopped
This commit is contained in:
Anthony Xu 2014-11-19 16:27:51 -08:00
parent 4140811549
commit 02e22dba7d
4 changed files with 40 additions and 21 deletions

View File

@ -1283,13 +1283,27 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
s_logger.debug("Cleaning up resources for the vm " + vm + " in " + state + " state");
try {
if (state == State.Starting) {
Step step = work.getStep();
if (step == Step.Starting && !cleanUpEvenIfUnableToStop) {
s_logger.warn("Unable to cleanup vm " + vm + "; work state is incorrect: " + step);
return false;
}
if (work != null) {
Step step = work.getStep();
if (step == Step.Starting && !cleanUpEvenIfUnableToStop) {
s_logger.warn("Unable to cleanup vm " + vm + "; work state is incorrect: " + step);
return false;
}
if (step == Step.Started || step == Step.Starting || step == Step.Release) {
if (step == Step.Started || step == Step.Starting || step == Step.Release) {
if (vm.getHostId() != null) {
if (!sendStop(guru, profile, cleanUpEvenIfUnableToStop, false)) {
s_logger.warn("Failed to stop vm " + vm + " in " + State.Starting + " state as a part of cleanup process");
return false;
}
}
}
if (step != Step.Release && step != Step.Prepare && step != Step.Started && step != Step.Starting) {
s_logger.debug("Cleanup is not needed for vm " + vm + "; work state is incorrect: " + step);
return true;
}
} else {
if (vm.getHostId() != null) {
if (!sendStop(guru, profile, cleanUpEvenIfUnableToStop, false)) {
s_logger.warn("Failed to stop vm " + vm + " in " + State.Starting + " state as a part of cleanup process");
@ -1298,10 +1312,6 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
}
}
if (step != Step.Release && step != Step.Prepare && step != Step.Started && step != Step.Starting) {
s_logger.debug("Cleanup is not needed for vm " + vm + "; work state is incorrect: " + step);
return true;
}
} else if (state == State.Stopping) {
if (vm.getHostId() != null) {
if (!sendStop(guru, profile, cleanUpEvenIfUnableToStop, false)) {
@ -1453,20 +1463,10 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
if (!cleanUpEvenIfUnableToStop) {
throw new CloudRuntimeException("We cannot stop " + vm + " when it is in state " + vm.getState());
}
boolean doCleanup = false;
boolean doCleanup = true;
if (s_logger.isDebugEnabled()) {
s_logger.debug("Unable to transition the state but we're moving on because it's forced stop");
}
if ((state == State.Starting) || (state == State.Migrating) || (state == State.Stopping)) {
if (work != null) {
doCleanup = true;
} else {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Unable to cleanup VM: " + vm + " ,since outstanding work item is not found");
}
throw new CloudRuntimeException("Work item not found, We cannot stop " + vm + " when it is in state " + vm.getState());
}
}
if (doCleanup) {
if (cleanup(vmGuru, new VirtualMachineProfileImpl(vm), work, Event.StopRequested, cleanUpEvenIfUnableToStop)) {

View File

@ -250,6 +250,7 @@ public class DataCenterDaoImpl extends GenericDaoBase<DataCenterVO, Long> implem
@Override
public Pair<String, Long> allocatePrivateIpAddress(long dcId, long podId, long instanceId, String reservationId) {
_ipAllocDao.releaseIpAddress(instanceId);
DataCenterIpAddressVO vo = _ipAllocDao.takeIpAddress(dcId, podId, instanceId, reservationId);
if (vo == null) {
return null;

View File

@ -33,6 +33,8 @@ public interface DataCenterIpAddressDao extends GenericDao<DataCenterIpAddressVO
public void releaseIpAddress(long nicId, String reservationId);
public void releaseIpAddress(long nicId);
boolean mark(long dcId, long podId, String ip);
List<DataCenterIpAddressVO> listByPodIdDcIdIpAddress(long podId, long dcId, String ipAddress);

View File

@ -177,6 +177,22 @@ public class DataCenterIpAddressDaoImpl extends GenericDaoBase<DataCenterIpAddre
update(vo, sc);
}
@Override
public void releaseIpAddress(long nicId) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Releasing ip address for instance=" + nicId);
}
SearchCriteria<DataCenterIpAddressVO> sc = AllFieldsSearch.create();
sc.setParameters("instance", nicId);
DataCenterIpAddressVO vo = createForUpdate();
vo.setTakenAt(null);
vo.setInstanceId(null);
vo.setReservationId(null);
update(vo, sc);
}
@Override
public List<DataCenterIpAddressVO> listByPodIdDcId(long podId, long dcId) {
SearchCriteria<DataCenterIpAddressVO> sc = AllFieldsSearch.create();