CLOUDSTACK-2107

If the scaling up fails on the host the vm is running on try to migrate it to other hosts in the cluster and try scaling.
CLOUDSTACK-3349
For deciding the host in the cluster try the new deployment manager now
Signed off by : nitin mehta<nitin.mehta@citrix.com>
This commit is contained in:
Nitin Mehta 2013-07-03 18:38:07 +05:30
parent 4e823e3a3e
commit 90a15bfff6
5 changed files with 40 additions and 43 deletions

View File

@ -1180,11 +1180,16 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
boolean success = false; boolean success = false;
if(vmInstance.getState().equals(State.Running)){ if(vmInstance.getState().equals(State.Running)){
int retry = _scaleRetry; int retry = _scaleRetry;
ExcludeList excludes = new ExcludeList();
boolean enableDynamicallyScaleVm = Boolean.parseBoolean(_configServer.getConfigValue(Config.EnableDynamicallyScaleVm.key(), Config.ConfigurationParameterScope.zone.toString(), vmInstance.getDataCenterId())); boolean enableDynamicallyScaleVm = Boolean.parseBoolean(_configServer.getConfigValue(Config.EnableDynamicallyScaleVm.key(), Config.ConfigurationParameterScope.zone.toString(), vmInstance.getDataCenterId()));
if(!enableDynamicallyScaleVm){ if(!enableDynamicallyScaleVm){
throw new PermissionDeniedException("Dynamically scaling virtual machines is disabled for this zone, please contact your admin"); throw new PermissionDeniedException("Dynamically scaling virtual machines is disabled for this zone, please contact your admin");
} }
while (retry-- != 0) { // It's != so that it can match -1.
try{
boolean existingHostHasCapacity = false;
// Increment CPU and Memory count accordingly. // Increment CPU and Memory count accordingly.
if (newCpu > currentCpu) { if (newCpu > currentCpu) {
_resourceLimitMgr.incrementResourceCount(caller.getAccountId(), ResourceType.cpu, new Long (newCpu - currentCpu)); _resourceLimitMgr.incrementResourceCount(caller.getAccountId(), ResourceType.cpu, new Long (newCpu - currentCpu));
@ -1193,15 +1198,16 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
_resourceLimitMgr.incrementResourceCount(caller.getAccountId(), ResourceType.memory, new Long (newMemory - currentMemory)); _resourceLimitMgr.incrementResourceCount(caller.getAccountId(), ResourceType.memory, new Long (newMemory - currentMemory));
} }
while (retry-- != 0) { // It's != so that it can match -1.
try{
// #1 Check existing host has capacity // #1 Check existing host has capacity
boolean existingHostHasCapacity = _capacityMgr.checkIfHostHasCapacity(vmInstance.getHostId(), newServiceOffering.getSpeed() - currentServiceOffering.getSpeed(), if( !excludes.shouldAvoid(ApiDBUtils.findHostById(vmInstance.getHostId())) ){
existingHostHasCapacity = _capacityMgr.checkIfHostHasCapacity(vmInstance.getHostId(), newServiceOffering.getSpeed() - currentServiceOffering.getSpeed(),
(newServiceOffering.getRamSize() - currentServiceOffering.getRamSize()) * 1024L * 1024L, false, ApiDBUtils.getCpuOverprovisioningFactor(), 1f, false); // TO DO fill it with mem. (newServiceOffering.getRamSize() - currentServiceOffering.getRamSize()) * 1024L * 1024L, false, ApiDBUtils.getCpuOverprovisioningFactor(), 1f, false); // TO DO fill it with mem.
excludes.addHost(vmInstance.getHostId());
}
// #2 migrate the vm if host doesn't have capacity // #2 migrate the vm if host doesn't have capacity or is in avoid set
if (!existingHostHasCapacity){ if (!existingHostHasCapacity){
vmInstance = _itMgr.findHostAndMigrate(vmInstance.getType(), vmInstance, newServiceOfferingId); vmInstance = _itMgr.findHostAndMigrate(vmInstance.getType(), vmInstance, newServiceOfferingId, excludes);
} }
// #3 scale the vm now // #3 scale the vm now
@ -1220,7 +1226,10 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
s_logger.warn("Received exception while scaling ",e); s_logger.warn("Received exception while scaling ",e);
} catch (ManagementServerException e) { } catch (ManagementServerException e) {
s_logger.warn("Received exception while scaling ",e); s_logger.warn("Received exception while scaling ",e);
}finally{ } catch (Exception e) {
s_logger.warn("Received exception while scaling ",e);
}
finally{
if(!success){ if(!success){
_itMgr.upgradeVmDb(vmId, currentServiceOffering.getId()); // rollback _itMgr.upgradeVmDb(vmId, currentServiceOffering.getId()); // rollback
// Decrement CPU and Memory count accordingly. // Decrement CPU and Memory count accordingly.

View File

@ -20,6 +20,7 @@ import java.net.URI;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import com.cloud.deploy.DeploymentPlanner;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.NicTO;
@ -194,7 +195,7 @@ public interface VirtualMachineManager extends Manager {
VMInstanceVO reConfigureVm(VMInstanceVO vm, ServiceOffering newServiceOffering, boolean sameHost) VMInstanceVO reConfigureVm(VMInstanceVO vm, ServiceOffering newServiceOffering, boolean sameHost)
throws ResourceUnavailableException, ConcurrentOperationException; throws ResourceUnavailableException, ConcurrentOperationException;
VMInstanceVO findHostAndMigrate(VirtualMachine.Type vmType, VMInstanceVO vm, Long newSvcOfferingId) throws InsufficientCapacityException, VMInstanceVO findHostAndMigrate(VirtualMachine.Type vmType, VMInstanceVO vm, Long newSvcOfferingId, DeploymentPlanner.ExcludeList excludeHostList) throws InsufficientCapacityException,
ConcurrentOperationException, ResourceUnavailableException, ConcurrentOperationException, ResourceUnavailableException,
VirtualMachineMigrationException, ManagementServerException; VirtualMachineMigrationException, ManagementServerException;

View File

@ -3007,7 +3007,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
} }
@Override @Override
public VMInstanceVO findHostAndMigrate(VirtualMachine.Type vmType, VMInstanceVO vm, Long newSvcOfferingId) public VMInstanceVO findHostAndMigrate(VirtualMachine.Type vmType, VMInstanceVO vm, Long newSvcOfferingId, ExcludeList excludes)
throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, VirtualMachineMigrationException, ManagementServerException { throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, VirtualMachineMigrationException, ManagementServerException {
VirtualMachineProfile<VMInstanceVO> profile = new VirtualMachineProfileImpl<VMInstanceVO>(vm); VirtualMachineProfile<VMInstanceVO> profile = new VirtualMachineProfileImpl<VMInstanceVO>(vm);
@ -3019,27 +3019,22 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
} }
Host host = _hostDao.findById(srcHostId); Host host = _hostDao.findById(srcHostId);
DataCenterDeployment plan = new DataCenterDeployment(host.getDataCenterId(), host.getPodId(), host.getClusterId(), null, null, null); DataCenterDeployment plan = new DataCenterDeployment(host.getDataCenterId(), host.getPodId(), host.getClusterId(), null, null, null);
ExcludeList excludes = new ExcludeList();
excludes.addHost(vm.getHostId()); excludes.addHost(vm.getHostId());
vm.setServiceOfferingId(newSvcOfferingId); // Need to find the destination host based on new svc offering vm.setServiceOfferingId(newSvcOfferingId); // Need to find the destination host based on new svc offering
DeployDestination dest = null; DeployDestination dest = null;
for (DeploymentPlanner planner : _planners) { try {
if (planner.canHandle(profile, plan, excludes)) { dest = _dpMgr.planDeployment(profile, plan, excludes);
dest = planner.plan(profile, plan, excludes); } catch (AffinityConflictException e2) {
} else { s_logger.warn("Unable to create deployment, affinity rules associted to the VM conflict", e2);
continue; throw new CloudRuntimeException(
"Unable to create deployment, affinity rules associted to the VM conflict");
} }
if (dest != null) { if (dest != null) {
if (s_logger.isDebugEnabled()) { if (s_logger.isDebugEnabled()) {
s_logger.debug("Planner " + planner + " found " + dest + " for scaling the vm to."); s_logger.debug(" Found " + dest + " for scaling the vm to.");
}
break;
}
if (s_logger.isDebugEnabled()) {
s_logger.debug("Planner " + planner + " was unable to find anything.");
} }
} }

View File

@ -23,6 +23,7 @@ import java.util.Map;
import javax.ejb.Local; import javax.ejb.Local;
import javax.naming.ConfigurationException; import javax.naming.ConfigurationException;
import com.cloud.deploy.DeploymentPlanner;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -281,7 +282,7 @@ public class MockVirtualMachineManagerImpl extends ManagerBase implements Virtua
} }
@Override @Override
public VMInstanceVO findHostAndMigrate(VirtualMachine.Type vmType, VMInstanceVO vm, Long newSvcOfferingId) throws InsufficientCapacityException, public VMInstanceVO findHostAndMigrate(Type vmType, VMInstanceVO vm, Long newSvcOfferingId, DeploymentPlanner.ExcludeList excludeHostList) throws InsufficientCapacityException,
ConcurrentOperationException, ResourceUnavailableException, ConcurrentOperationException, ResourceUnavailableException,
VirtualMachineMigrationException, ManagementServerException{ VirtualMachineMigrationException, ManagementServerException{
return null; return null;

View File

@ -26,6 +26,7 @@ import com.cloud.configuration.Config;
import com.cloud.configuration.ConfigurationManager; import com.cloud.configuration.ConfigurationManager;
import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.deploy.DeployDestination; import com.cloud.deploy.DeployDestination;
import com.cloud.deploy.DeploymentPlanner;
import com.cloud.host.HostVO; import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao; import com.cloud.host.dao.HostDao;
import com.cloud.server.ConfigurationServer; import com.cloud.server.ConfigurationServer;
@ -45,9 +46,6 @@ import com.cloud.agent.api.MigrateWithStorageCompleteAnswer;
import com.cloud.agent.api.MigrateWithStorageCompleteCommand; import com.cloud.agent.api.MigrateWithStorageCompleteCommand;
import com.cloud.agent.api.CheckVirtualMachineAnswer; import com.cloud.agent.api.CheckVirtualMachineAnswer;
import com.cloud.agent.api.CheckVirtualMachineCommand; import com.cloud.agent.api.CheckVirtualMachineCommand;
import com.cloud.capacity.CapacityManager;
import com.cloud.configuration.ConfigurationManager;
import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.dc.dao.ClusterDao; import com.cloud.dc.dao.ClusterDao;
import com.cloud.dc.dao.DataCenterDao; import com.cloud.dc.dao.DataCenterDao;
import com.cloud.dc.dao.HostPodDao; import com.cloud.dc.dao.HostPodDao;
@ -56,16 +54,12 @@ import com.cloud.exception.ManagementServerException;
import com.cloud.exception.ResourceUnavailableException; import com.cloud.exception.ResourceUnavailableException;
import com.cloud.exception.VirtualMachineMigrationException; import com.cloud.exception.VirtualMachineMigrationException;
import com.cloud.exception.OperationTimedoutException; import com.cloud.exception.OperationTimedoutException;
import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao;
import com.cloud.hypervisor.HypervisorGuru; import com.cloud.hypervisor.HypervisorGuru;
import com.cloud.hypervisor.HypervisorGuruManager; import com.cloud.hypervisor.HypervisorGuruManager;
import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.network.NetworkManager; import com.cloud.network.NetworkManager;
import com.cloud.storage.DiskOfferingVO; import com.cloud.storage.DiskOfferingVO;
import com.cloud.storage.StoragePoolHostVO; import com.cloud.storage.StoragePoolHostVO;
import com.cloud.storage.VolumeManager;
import com.cloud.storage.VolumeVO;
import com.cloud.storage.dao.DiskOfferingDao; import com.cloud.storage.dao.DiskOfferingDao;
import com.cloud.storage.dao.StoragePoolHostDao; import com.cloud.storage.dao.StoragePoolHostDao;
import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplateDao;
@ -77,10 +71,7 @@ import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.dao.UserVmDao; import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.UserVmDetailsDao; import com.cloud.vm.dao.UserVmDetailsDao;
import org.apache.cloudstack.api.command.user.vm.RestoreVMCmd; import org.apache.cloudstack.api.command.user.vm.RestoreVMCmd;
import org.apache.cloudstack.api.command.user.vm.ScaleVMCmd;
import com.cloud.utils.Pair; import com.cloud.utils.Pair;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.VMInstanceDao; import com.cloud.vm.dao.VMInstanceDao;
import com.cloud.vm.snapshot.VMSnapshotManager; import com.cloud.vm.snapshot.VMSnapshotManager;
import com.cloud.vm.VirtualMachine.Event; import com.cloud.vm.VirtualMachine.Event;
@ -97,7 +88,6 @@ import org.mockito.Spy;
import static org.mockito.Matchers.anyLong; import static org.mockito.Matchers.anyLong;
import static org.mockito.Mockito.*; import static org.mockito.Mockito.*;
import java.lang.reflect.Field;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.HashMap; import java.util.HashMap;
@ -281,7 +271,8 @@ public class VirtualMachineManagerImplTest {
when(_vmInstance.getHostId()).thenReturn(null); when(_vmInstance.getHostId()).thenReturn(null);
when(_vmInstanceDao.findById(anyLong())).thenReturn(_vmInstance); when(_vmInstanceDao.findById(anyLong())).thenReturn(_vmInstance);
_vmMgr.findHostAndMigrate(VirtualMachine.Type.User, _vmInstance, 2l); DeploymentPlanner.ExcludeList excludeHostList = new DeploymentPlanner.ExcludeList();
_vmMgr.findHostAndMigrate(VirtualMachine.Type.User, _vmInstance, 2l, excludeHostList);
} }