From 25196871b936aec6ae3366afe562bc68d6489359 Mon Sep 17 00:00:00 2001 From: prachi Date: Wed, 5 Oct 2011 18:30:38 -0700 Subject: [PATCH] Bug 11169 - Couldn't deploy a router because the host it existed on is in Maintenance. Changes: - VirtualMachineMgr puts the constraint that if Root volume is already READY, we provide the clusterId in the plan to the deploymentPlanner. Planner then searches for resources only under that cluster. - If no deployment could be found, deploying VM fails. - Fixed this, such that incase the root volume is recreatable, we call the planner again by removing the cluster constraint. Planner will then search for resources in other clusters. - Works for system VMs(SSVM, consoleproxy, virual routers). --- .../cloud/vm/VirtualMachineManagerImpl.java | 92 +++++++++++-------- 1 file changed, 54 insertions(+), 38 deletions(-) diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java index 9640758ffb0..50cf3a1ed17 100755 --- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -611,6 +611,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene } plan = (DataCenterDeployment)planToDeploy; } + HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vm.getHypervisorType()); boolean canRetry = true; @@ -629,51 +630,59 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene + ", clusters: " + avoids.getClustersToAvoid() + ", hosts: " + avoids.getHostsToAvoid()); } - int retry = _retry; - while (retry-- != 0) { // It's != so that it can match -1. - // edit plan if this vm's ROOT volume is in READY state already - // edit plan if this vm's ROOT volume is in READY state already - List vols = _volsDao.findReadyRootVolumesByInstance(vm.getId()); - - for (VolumeVO vol : vols) { - // make sure if the templateId is unchanged. If it is changed, let planner - // reassign pool for the volume even if it ready. - Long volTemplateId = vol.getTemplateId(); - if (volTemplateId != null && volTemplateId.longValue() != template.getId()) { - if (s_logger.isDebugEnabled()) { - s_logger.debug(vol + " of " + vm + " is READY, but template ids don't match, let the planner reassign a new pool"); - } - continue; + + // edit plan if this vm's ROOT volume is in READY state already + List vols = _volsDao.findReadyRootVolumesByInstance(vm.getId()); + boolean planChangedByVolume = false; + boolean rootVolumeisRecreatable = false; + DataCenterDeployment originalPlan = plan; + for (VolumeVO vol : vols) { + // make sure if the templateId is unchanged. If it is changed, let planner + // reassign pool for the volume even if it ready. + Long volTemplateId = vol.getTemplateId(); + if (volTemplateId != null && volTemplateId.longValue() != template.getId()) { + if (s_logger.isDebugEnabled()) { + s_logger.debug(vol + " of " + vm + " is READY, but template ids don't match, let the planner reassign a new pool"); } + continue; + } - StoragePoolVO pool = _storagePoolDao.findById(vol.getPoolId()); - if (!pool.isInMaintenance()) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Root volume is ready, need to place VM in volume's cluster"); - } - long rootVolDcId = pool.getDataCenterId(); - Long rootVolPodId = pool.getPodId(); - Long rootVolClusterId = pool.getClusterId(); - if(planToDeploy != null && planToDeploy.getDataCenterId() != 0){ - Long clusterIdSpecified = planToDeploy.getClusterId(); - if(clusterIdSpecified != null && rootVolClusterId != null){ - if(rootVolClusterId.longValue() != clusterIdSpecified.longValue()){ - //cannot satisfy the plan passed in to the planner - if (s_logger.isDebugEnabled()) { - s_logger.debug("Cannot satisfy the deployment plan passed in since the ready Root volume is in different cluster. volume's cluster: "+rootVolClusterId + ", cluster specified: "+clusterIdSpecified); - } - throw new ResourceUnavailableException("Root volume is ready in different cluster, Deployment plan provided cannot be satisfied, unable to create a deployment for " + vm, Cluster.class, clusterIdSpecified); + StoragePoolVO pool = _storagePoolDao.findById(vol.getPoolId()); + if (!pool.isInMaintenance()) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Root volume is ready, need to place VM in volume's cluster"); + } + long rootVolDcId = pool.getDataCenterId(); + Long rootVolPodId = pool.getPodId(); + Long rootVolClusterId = pool.getClusterId(); + if(planToDeploy != null && planToDeploy.getDataCenterId() != 0){ + Long clusterIdSpecified = planToDeploy.getClusterId(); + if(clusterIdSpecified != null && rootVolClusterId != null){ + if(rootVolClusterId.longValue() != clusterIdSpecified.longValue()){ + //cannot satisfy the plan passed in to the planner + if (s_logger.isDebugEnabled()) { + s_logger.debug("Cannot satisfy the deployment plan passed in since the ready Root volume is in different cluster. volume's cluster: "+rootVolClusterId + ", cluster specified: "+clusterIdSpecified); } - } - plan = new DataCenterDeployment(planToDeploy.getDataCenterId(), planToDeploy.getPodId(), planToDeploy.getClusterId(), planToDeploy.getHostId(), vol.getPoolId()); - }else{ - plan = new DataCenterDeployment(rootVolDcId, rootVolPodId, rootVolClusterId, null, vol.getPoolId()); - if (s_logger.isDebugEnabled()) { - s_logger.debug(vol + " is READY, changing deployment plan to use this pool's dcId: " + rootVolDcId + " , podId: " + rootVolPodId + " , and clusterId: " + rootVolClusterId); + throw new ResourceUnavailableException("Root volume is ready in different cluster, Deployment plan provided cannot be satisfied, unable to create a deployment for " + vm, Cluster.class, clusterIdSpecified); } } + plan = new DataCenterDeployment(planToDeploy.getDataCenterId(), planToDeploy.getPodId(), planToDeploy.getClusterId(), planToDeploy.getHostId(), vol.getPoolId()); + }else{ + plan = new DataCenterDeployment(rootVolDcId, rootVolPodId, rootVolClusterId, null, vol.getPoolId()); + if (s_logger.isDebugEnabled()) { + s_logger.debug(vol + " is READY, changing deployment plan to use this pool's dcId: " + rootVolDcId + " , podId: " + rootVolPodId + " , and clusterId: " + rootVolClusterId); + } + planChangedByVolume = true; + if(vol.isRecreatable()){ + rootVolumeisRecreatable = true; + } + } } + } + + int retry = _retry; + while (retry-- != 0) { // It's != so that it can match -1. VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vm, template, offering, account, params); DeployDestination dest = null; @@ -691,6 +700,13 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene } if (dest == null) { + if(planChangedByVolume){ + if(rootVolumeisRecreatable){ + plan = originalPlan; + planChangedByVolume = false; + continue; + } + } throw new InsufficientServerCapacityException("Unable to create a deployment for " + vmProfile, DataCenter.class, plan.getDataCenterId()); }