diff --git a/core/src/com/cloud/hypervisor/xen/resource/XenServer56Resource.java b/core/src/com/cloud/hypervisor/xen/resource/XenServer56Resource.java index 9595d53096e..cd2ca921bba 100644 --- a/core/src/com/cloud/hypervisor/xen/resource/XenServer56Resource.java +++ b/core/src/com/cloud/hypervisor/xen/resource/XenServer56Resource.java @@ -20,11 +20,11 @@ package com.cloud.hypervisor.xen.resource; import java.io.File; import java.util.ArrayList; -import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; + import javax.ejb.Local; import javax.naming.ConfigurationException; @@ -43,7 +43,6 @@ import com.cloud.agent.api.PoolEjectCommand; import com.cloud.agent.api.SetupAnswer; import com.cloud.agent.api.SetupCommand; import com.cloud.agent.api.StartupCommand; -import com.cloud.agent.api.to.StorageFilerTO; import com.cloud.resource.ServerResource; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; @@ -55,7 +54,6 @@ import com.xensource.xenapi.Host; import com.xensource.xenapi.Network; import com.xensource.xenapi.PBD; import com.xensource.xenapi.PIF; -import com.xensource.xenapi.Pool; import com.xensource.xenapi.SR; import com.xensource.xenapi.Types; import com.xensource.xenapi.Types.IpConfigurationMode; @@ -131,7 +129,7 @@ public class XenServer56Resource extends CitrixResourceBase { host.forgetDataSourceArchives(conn, "pif_" + device + "." + vlannum + "_tx"); host.forgetDataSourceArchives(conn, "pif_" + device + "." + vlannum + "_rx"); } catch (XenAPIException e) { - s_logger.debug("Catch Exception: " + e.getClass().getName() + ": failed to destory VLAN " + device + " on host " + _host.uuid + s_logger.debug("Catch " + e.getClass().getName() + ": failed to destory VLAN " + device + " on host " + _host.uuid + " due to " + e.toString()); } } diff --git a/server/src/com/cloud/deploy/FirstFitPlanner.java b/server/src/com/cloud/deploy/FirstFitPlanner.java index f10f08d5071..9a66195af85 100644 --- a/server/src/com/cloud/deploy/FirstFitPlanner.java +++ b/server/src/com/cloud/deploy/FirstFitPlanner.java @@ -158,12 +158,12 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentPlanner { }else{ if (host.getStatus() == Status.Up && host.getHostAllocationState() == Host.HostAllocationState.Enabled) { //check zone/pod/cluster are enabled - if(isEnabledForAllocation(vm.getDataCenterId(), vm.getPodId(), host.getClusterId())){ + if(isEnabledForAllocation(host.getDataCenterId(), host.getPodId(), host.getClusterId())){ if(_capacityMgr.checkIfHostHasCapacity(host.getId(), cpu_requested, ram_requested, true, cpuOverprovisioningFactor)){ s_logger.debug("The last host of this VM is UP and has enough capacity"); - s_logger.debug("Now checking for suitable pools under zone: "+vm.getDataCenterId() +", pod: "+ vm.getPodId()+", cluster: "+ host.getClusterId()); + s_logger.debug("Now checking for suitable pools under zone: "+host.getDataCenterId() +", pod: "+ host.getPodId()+", cluster: "+ host.getClusterId()); //search for storage under the zone, pod, cluster of the last host. - DataCenterDeployment lastPlan = new DataCenterDeployment(vm.getDataCenterId(), vm.getPodId(), host.getClusterId(), host.getId(), plan.getPoolId()); + DataCenterDeployment lastPlan = new DataCenterDeployment(host.getDataCenterId(), host.getPodId(), host.getClusterId(), host.getId(), plan.getPoolId()); Pair>, List> result = findSuitablePoolsForVolumes(vmProfile, lastPlan, avoid, RETURN_UPTO_ALL); Map> suitableVolumeStoragePools = result.first(); List readyAndReusedVolumes = result.second(); diff --git a/server/src/com/cloud/storage/dao/VolumeDaoImpl.java b/server/src/com/cloud/storage/dao/VolumeDaoImpl.java index c0b4e85ff8d..9ca6708f9d6 100755 --- a/server/src/com/cloud/storage/dao/VolumeDaoImpl.java +++ b/server/src/com/cloud/storage/dao/VolumeDaoImpl.java @@ -139,7 +139,7 @@ public class VolumeDaoImpl extends GenericDaoBase implements Vol SearchCriteria sc = AllFieldsSearch.create(); sc.setParameters("instanceId", instanceId); sc.setParameters("state", Volume.State.Ready); - sc.setParameters("vType", Volume.Type.ROOT.toString()); + sc.setParameters("vType", Volume.Type.ROOT); return listBy(sc); } diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java index 16e575f3640..29626985b2c 100755 --- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -132,6 +132,7 @@ import com.cloud.utils.db.DB; import com.cloud.utils.db.GlobalLock; import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.exception.ExecutionException; import com.cloud.utils.fsm.StateMachine2; import com.cloud.vm.ItWorkVO.Step; import com.cloud.vm.VirtualMachine.Event; @@ -549,7 +550,6 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene public T advanceStart(T vm, Map params, User caller, Account account) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException { long vmId = vm.getId(); - Long hostIdSpecified = vm.getHostId(); VirtualMachineGuru vmGuru; if (vm.getHypervisorType() == HypervisorType.BareMetal) { vmGuru = getBareMetalVmGuru(vm); @@ -571,14 +571,10 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene ServiceOfferingVO offering = _offeringDao.findById(vm.getServiceOfferingId()); VMTemplateVO template = _templateDao.findById(vm.getTemplateId()); - Long clusterSpecified = null; - if (hostIdSpecified != null) { - Host destinationHost = _hostDao.findById(hostIdSpecified); - clusterSpecified = destinationHost.getClusterId(); - } - DataCenterDeployment plan = new DataCenterDeployment(vm.getDataCenterId(), vm.getPodId(), clusterSpecified, hostIdSpecified, null); + DataCenterDeployment plan = new DataCenterDeployment(vm.getDataCenterId(), vm.getPodId(), null, null, null); HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vm.getHypervisorType()); + boolean canRetry = true; try { Journal journal = start.second().getJournal(); @@ -586,31 +582,24 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene List vols = _volsDao.findReadyRootVolumesByInstance(vm.getId()); for (VolumeVO vol : vols) { - Volume.State state = vol.getState(); - if (state == Volume.State.Ready) { - // 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 && template != null) { - if (volTemplateId.longValue() != template.getId()) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Root Volume " + vol + " of " + vm.getType().toString() - + " VM is READY, but volume's templateId does not match the VM's Template, let the planner reassign a new pool"); - } - continue; - } + // 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()) { - long rootVolDcId = pool.getDataCenterId(); - Long rootVolPodId = pool.getPodId(); - Long rootVolClusterId = pool.getClusterId(); - plan = new DataCenterDeployment(rootVolDcId, rootVolPodId, rootVolClusterId, null, vol.getPoolId()); - if (s_logger.isDebugEnabled()) { - s_logger.debug("Root Volume " + vol + " is ready, changing deployment plan to use this pool's datacenterId: " + rootVolDcId + " , podId: " + rootVolPodId - + " , and clusterId: " + rootVolClusterId); - } + StoragePoolVO pool = _storagePoolDao.findById(vol.getPoolId()); + if (!pool.isInMaintenance()) { + long rootVolDcId = pool.getDataCenterId(); + Long rootVolPodId = pool.getPodId(); + Long rootVolClusterId = pool.getClusterId(); + 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); } } } @@ -658,7 +647,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene cmds.addCommand(new StartCommand(vmTO)); vmGuru.finalizeDeployment(cmds, vmProfile, dest, ctx); - vm.setPodId(dest.getPod().getId()); +// vm.setPodId(dest.getPod().getId()); work = _workDao.findById(work.getId()); if (work == null || work.getStep() != Step.Prepare) { @@ -676,19 +665,31 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene } startedVm = vm; if (s_logger.isDebugEnabled()) { - s_logger.debug("Creation complete for VM " + vm); + s_logger.debug("Start completed for VM " + vm); } return startedVm; + } else { + if (s_logger.isDebugEnabled()) { + s_logger.info("The guru did not like the answers so stopping " + vm); + } + StopCommand cmd = new StopCommand(vm.getInstanceName()); + StopAnswer answer = (StopAnswer)_agentMgr.easySend(destHostId, cmd); + if (answer == null || !answer.getResult()) { + s_logger.warn("Unable to stop " + vm + " due to " + (answer != null ? answer.getDetails() : "no answers")); + canRetry = false; + _haMgr.scheduleStop(vm, destHostId, WorkType.ForceStop); + throw new ExecutionException("Unable to stop " + vm + " so we are unable to retry the start operation"); + } } - } + } s_logger.info("Unable to start VM on " + dest.getHost() + " due to " + (startAnswer == null ? " no start answer" : startAnswer.getDetails())); } catch (OperationTimedoutException e) { s_logger.debug("Unable to send the start command to host " + dest.getHost()); if (e.isActive()) { - // TODO: This one is different as we're not sure if the VM is actually started. + _haMgr.scheduleStop(vm, destHostId, WorkType.ForceStop); } - avoids.addHost(destHostId); - continue; + canRetry = false; + throw new AgentUnavailableException("Unable to start " + vm.getHostName(), destHostId, e); } catch (ResourceUnavailableException e) { s_logger.info("Unable to contact resource.", e); if (!avoids.add(e)) { @@ -699,7 +700,6 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene throw e; } } - continue; } catch (InsufficientCapacityException e) { s_logger.info("Insufficient capacity ", e); if (!avoids.add(e)) { @@ -709,19 +709,18 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene s_logger.warn("unexpected InsufficientCapacityException : " + e.getScope().getName(), e); } } - continue; - } catch (RuntimeException e) { - s_logger.warn("Failed to start instance " + vm, e); - throw e; + } catch (Exception e) { + s_logger.error("Failed to start instance " + vm, e); + throw new AgentUnavailableException("Unable to start instance", destHostId, e); } finally { - if (startedVm == null) { + if (startedVm == null && canRetry) { _workDao.updateStep(work, Step.Release); cleanup(vmGuru, vmProfile, work, Event.OperationFailed, false, caller, account); } } } } finally { - if (startedVm == null) { + if (startedVm == null && canRetry) { // decrement only for user VM's and newly created VM if (vm.getType().equals(VirtualMachine.Type.User) && (vm.getLastHostId() == null)) { _accountMgr.decrementResourceCount(vm.getAccountId(), ResourceType.user_vm);