diff --git a/engine/orchestration/src/com/cloud/agent/manager/AgentManagerImpl.java b/engine/orchestration/src/com/cloud/agent/manager/AgentManagerImpl.java index d51df220195..251f3380281 100755 --- a/engine/orchestration/src/com/cloud/agent/manager/AgentManagerImpl.java +++ b/engine/orchestration/src/com/cloud/agent/manager/AgentManagerImpl.java @@ -118,6 +118,12 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl protected static final Logger s_logger = Logger.getLogger(AgentManagerImpl.class); protected static final Logger status_logger = Logger.getLogger(Status.class); + /** + * _agents is a ConcurrentHashMap, but it is used from within a synchronized block. + * This will be reported by findbugs as JLM_JSR166_UTILCONCURRENT_MONITORENTER. + * Maybe a ConcurrentHashMap is not the right thing to use here, but i'm not sure + * so i leave it alone. + */ protected ConcurrentHashMap _agents = new ConcurrentHashMap(10007); protected List> _hostMonitors = new ArrayList>(17); protected List> _cmdMonitors = new ArrayList>(17); @@ -167,20 +173,20 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl ResourceManager _resourceMgr; protected final ConfigKey Workers = new ConfigKey(Integer.class, "workers", "Advanced", "5", - "Number of worker threads handling remote agent connections.", false); + "Number of worker threads handling remote agent connections.", false); protected final ConfigKey Port = new ConfigKey(Integer.class, "port", "Advanced", "8250", "Port to listen on for remote agent connections.", false); protected final ConfigKey PingInterval = new ConfigKey(Integer.class, "ping.interval", "Advanced", "60", - "Interval to send application level pings to make sure the connection is still working", false); + "Interval to send application level pings to make sure the connection is still working", false); protected final ConfigKey PingTimeout = new ConfigKey(Float.class, "ping.timeout", "Advanced", "2.5", - "Multiplier to ping.interval before announcing an agent has timed out", true); + "Multiplier to ping.interval before announcing an agent has timed out", true); protected final ConfigKey AlertWait = new ConfigKey(Integer.class, "alert.wait", "Advanced", "1800", - "Seconds to wait before alerting on a disconnected agent", true); + "Seconds to wait before alerting on a disconnected agent", true); protected final ConfigKey DirectAgentLoadSize = new ConfigKey(Integer.class, "direct.agent.load.size", "Advanced", "16", - "The number of direct agents to load each time", false); + "The number of direct agents to load each time", false); protected final ConfigKey DirectAgentPoolSize = new ConfigKey(Integer.class, "direct.agent.pool.size", "Advanced", "500", - "Default size for DirectAgentPool", false); + "Default size for DirectAgentPool", false); protected final ConfigKey DirectAgentThreadCap = new ConfigKey(Float.class, "direct.agent.thread.cap", "Advanced", "0.1", - "Percentage (as a value between 0 and 1) of direct.agent.pool.size to be used as upper thread cap for a single direct agent to process requests", false); + "Percentage (as a value between 0 and 1) of direct.agent.pool.size to be used as upper thread cap for a single direct agent to process requests", false); @Override public boolean configure(final String name, final Map params) throws ConfigurationException { @@ -495,12 +501,12 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl ConnectionException ce = (ConnectionException)e; if (ce.isSetupError()) { s_logger.warn("Monitor " + monitor.second().getClass().getSimpleName() + " says there is an error in the connect process for " + hostId + - " due to " + e.getMessage()); + " due to " + e.getMessage()); handleDisconnectWithoutInvestigation(attache, Event.AgentDisconnected, true, true); throw ce; } else { s_logger.info("Monitor " + monitor.second().getClass().getSimpleName() + " says not to continue the connect process for " + hostId + - " due to " + e.getMessage()); + " due to " + e.getMessage()); handleDisconnectWithoutInvestigation(attache, Event.ShutdownRequested, true, true); return attache; } @@ -509,7 +515,7 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl throw new CloudRuntimeException("Unable to connect " + attache.getId(), e); } else { s_logger.error("Monitor " + monitor.second().getClass().getSimpleName() + " says there is an error in the connect process for " + hostId + - " due to " + e.getMessage(), e); + " due to " + e.getMessage(), e); handleDisconnectWithoutInvestigation(attache, Event.AgentDisconnected, true, true); throw new CloudRuntimeException("Unable to connect " + attache.getId(), e); } @@ -770,6 +776,7 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl protected boolean handleDisconnectWithInvestigation(AgentAttache attache, Status.Event event) { long hostId = attache.getId(); HostVO host = _hostDao.findById(hostId); + if (host != null) { Status nextStatus = null; try { @@ -819,7 +826,7 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl String hostDesc = "name: " + host.getName() + " (id:" + host.getId() + "), availability zone: " + dcVO.getName() + ", pod: " + podVO.getName(); if ((host.getType() != Host.Type.SecondaryStorage) && (host.getType() != Host.Type.ConsoleProxy)) { _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, host.getDataCenterId(), host.getPodId(), "Host disconnected, " + hostDesc, - "If the agent for host [" + hostDesc + "] is not restarted within " + AlertWait + " seconds, HA will begin on the VMs"); + "If the agent for host [" + hostDesc + "] is not restarted within " + AlertWait + " seconds, HA will begin on the VMs"); } event = Status.Event.AgentDisconnected; } @@ -829,7 +836,7 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl HostPodVO podVO = _podDao.findById(host.getPodId()); String hostDesc = "name: " + host.getName() + " (id:" + host.getId() + "), availability zone: " + dcVO.getName() + ", pod: " + podVO.getName(); _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, host.getDataCenterId(), host.getPodId(), "Host in ALERT state, " + hostDesc, - "In availability zone " + host.getDataCenterId() + "In availability zone " + host.getDataCenterId() + ", host is in alert state: " + host.getId() + "-" + host.getName()); } } else { @@ -838,8 +845,8 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl } handleDisconnectWithoutInvestigation(attache, event, true, true); - host = _hostDao.findById(host.getId()); - if (host.getStatus() == Status.Alert || host.getStatus() == Status.Down) { + host = _hostDao.findById(hostId); // Maybe the host magically reappeared? + if (host != null && (host.getStatus() == Status.Alert || host.getStatus() == Status.Down)) { _haMgr.scheduleRestartForVmsOnHost(host, true); } @@ -1093,7 +1100,7 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl for (int i = 0; i < cmds.length; i++) { cmd = cmds[i]; if ((cmd instanceof StartupRoutingCommand) || (cmd instanceof StartupProxyCommand) || (cmd instanceof StartupSecondaryStorageCommand) || - (cmd instanceof StartupStorageCommand)) { + (cmd instanceof StartupStorageCommand)) { answers[i] = new StartupAnswer((StartupCommand)cmds[i], 0, getPingInterval()); break; } @@ -1172,7 +1179,7 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl final ShutdownCommand shutdown = (ShutdownCommand)cmd; final String reason = shutdown.getReason(); s_logger.info("Host " + attache.getId() + " has informed us that it is shutting down with reason " + reason + " and detail " + - shutdown.getDetail()); + shutdown.getDetail()); if (reason.equals(ShutdownCommand.Update)) { //disconnectWithoutInvestigation(attache, Event.UpdateNeeded); throw new CloudRuntimeException("Agent update not implemented"); @@ -1200,17 +1207,17 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl DataCenterVO dcVO = _dcDao.findById(host.getDataCenterId()); HostPodVO podVO = _podDao.findById(host.getPodId()); String hostDesc = - "name: " + host.getName() + " (id:" + host.getId() + "), availability zone: " + dcVO.getName() + ", pod: " + podVO.getName(); + "name: " + host.getName() + " (id:" + host.getId() + "), availability zone: " + dcVO.getName() + ", pod: " + podVO.getName(); _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_ROUTING, host.getDataCenterId(), host.getPodId(), - "Host lost connection to gateway, " + hostDesc, "Host [" + hostDesc + + "Host lost connection to gateway, " + hostDesc, "Host [" + hostDesc + "] lost connection to gateway (default route) and is possibly having network connection issues."); } else { _alertMgr.clearAlert(AlertManager.AlertType.ALERT_TYPE_ROUTING, host.getDataCenterId(), host.getPodId()); } } else { s_logger.debug("Not processing " + PingRoutingCommand.class.getSimpleName() + " for agent id=" + cmdHostId + - "; can't find the host in the DB"); + "; can't find the host in the DB"); } } answer = new PingAnswer((PingCommand)cmd); @@ -1252,9 +1259,7 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl final AgentAttache attache = (AgentAttache)link.attachment(); if (attache == null) { s_logger.warn("Unable to process: " + response); - } - - if (!attache.processAnswers(response.getSequence(), response)) { + } else if (!attache.processAnswers(response.getSequence(), response)) { s_logger.info("Host " + attache.getId() + " - Seq " + response.getSequence() + ": Response is not processed: " + response); } } @@ -1334,9 +1339,9 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl return _statusStateMachine.transitTo(host, e, host.getId(), _hostDao); } catch (NoTransitionException e1) { status_logger.debug("Cannot transit agent status with event " + e + " for host " + host.getId() + ", name=" + host.getName() + - ", mangement server id is " + msId); + ", mangement server id is " + msId); throw new CloudRuntimeException("Cannot transit agent status with event " + e + " for host " + host.getId() + ", mangement server id is " + msId + "," + - e1.getMessage()); + e1.getMessage()); } } finally { _agentStatusLock.unlock(); diff --git a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java index 68bb4ea4e9e..9513bd7c291 100755 --- a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -321,36 +321,36 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac protected StateMachine2 _stateMachine; static final ConfigKey StartRetry = new ConfigKey("Advanced", Integer.class, "start.retry", "10", - "Number of times to retry create and start commands", true); + "Number of times to retry create and start commands", true); static final ConfigKey VmOpWaitInterval = new ConfigKey("Advanced", Integer.class, "vm.op.wait.interval", "120", - "Time (in seconds) to wait before checking if a previous operation has succeeded", true); + "Time (in seconds) to wait before checking if a previous operation has succeeded", true); static final ConfigKey VmOpLockStateRetry = new ConfigKey("Advanced", Integer.class, "vm.op.lock.state.retry", "5", - "Times to retry locking the state of a VM for operations, -1 means forever", true); + "Times to retry locking the state of a VM for operations, -1 means forever", true); static final ConfigKey VmOpCleanupInterval = new ConfigKey("Advanced", Long.class, "vm.op.cleanup.interval", "86400", - "Interval to run the thread that cleans up the vm operations (in seconds)", false); + "Interval to run the thread that cleans up the vm operations (in seconds)", false); static final ConfigKey VmOpCleanupWait = new ConfigKey("Advanced", Long.class, "vm.op.cleanup.wait", "3600", - "Time (in seconds) to wait before cleanuping up any vm work items", true); + "Time (in seconds) to wait before cleanuping up any vm work items", true); static final ConfigKey VmOpCancelInterval = new ConfigKey("Advanced", Long.class, "vm.op.cancel.interval", "3600", - "Time (in seconds) to wait before cancelling a operation", false); + "Time (in seconds) to wait before cancelling a operation", false); static final ConfigKey VmDestroyForcestop = new ConfigKey("Advanced", Boolean.class, "vm.destroy.forcestop", "false", - "On destroy, force-stop takes this value ", true); + "On destroy, force-stop takes this value ", true); static final ConfigKey ClusterDeltaSyncInterval = new ConfigKey("Advanced", Integer.class, "sync.interval", "60", - "Cluster Delta sync interval in seconds", - false); + "Cluster Delta sync interval in seconds", + false); static final ConfigKey VmJobEnabled = new ConfigKey("Advanced", - Boolean.class, "vm.job.enabled", "false", - "True to enable new VM sync model. false to use the old way", false); + Boolean.class, "vm.job.enabled", "false", + "True to enable new VM sync model. false to use the old way", false); static final ConfigKey VmJobCheckInterval = new ConfigKey("Advanced", - Long.class, "vm.job.check.interval", "3000", - "Interval in milliseconds to check if the job is complete", false); + Long.class, "vm.job.check.interval", "3000", + "Interval in milliseconds to check if the job is complete", false); static final ConfigKey VmJobTimeout = new ConfigKey("Advanced", - Long.class, "vm.job.timeout", "600000", - "Time in milliseconds to wait before attempting to cancel a job", false); + Long.class, "vm.job.timeout", "600000", + "Time in milliseconds to wait before attempting to cancel a job", false); static final ConfigKey VmJobStateReportInterval = new ConfigKey("Advanced", - Integer.class, "vm.job.report.interval", "60", - "Interval to send application level pings to make sure the connection is still working", false); + Integer.class, "vm.job.report.interval", "60", + "Interval to send application level pings to make sure the connection is still working", false); ScheduledExecutorService _executor = null; @@ -366,9 +366,9 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac @Override @DB public void allocate(String vmInstanceName, final VirtualMachineTemplate template, ServiceOffering serviceOffering, - final Pair rootDiskOffering, LinkedHashMap dataDiskOfferings, - final LinkedHashMap auxiliaryNetworks, DeploymentPlan plan, HypervisorType hyperType) - throws InsufficientCapacityException { + final Pair rootDiskOffering, LinkedHashMap dataDiskOfferings, + final LinkedHashMap auxiliaryNetworks, DeploymentPlan plan, HypervisorType hyperType) + throws InsufficientCapacityException { VMInstanceVO vm = _vmDao.findVMByInstanceName(vmInstanceName); final Account owner = _entityMgr.findById(Account.class, vm.getAccountId()); @@ -384,49 +384,49 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac assert (plan.getClusterId() == null && plan.getPoolId() == null) : "We currently don't support cluster and pool preset yet"; final VMInstanceVO vmFinal = _vmDao.persist(vm); final LinkedHashMap dataDiskOfferingsFinal = - dataDiskOfferings == null ? new LinkedHashMap() : dataDiskOfferings; + dataDiskOfferings == null ? new LinkedHashMap() : dataDiskOfferings; - final VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vmFinal, template, serviceOffering, null, null); + final VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vmFinal, template, serviceOffering, null, null); - Transaction.execute(new TransactionCallbackWithExceptionNoReturn() { - @Override - public void doInTransactionWithoutResult(TransactionStatus status) throws InsufficientCapacityException { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Allocating nics for " + vmFinal); - } + Transaction.execute(new TransactionCallbackWithExceptionNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) throws InsufficientCapacityException { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Allocating nics for " + vmFinal); + } - try { - _networkMgr.allocate(vmProfile, auxiliaryNetworks); - } catch (ConcurrentOperationException e) { - throw new CloudRuntimeException("Concurrent operation while trying to allocate resources for the VM", e); - } + try { + _networkMgr.allocate(vmProfile, auxiliaryNetworks); + } catch (ConcurrentOperationException e) { + throw new CloudRuntimeException("Concurrent operation while trying to allocate resources for the VM", e); + } + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Allocating disks for " + vmFinal); + } + + if (template.getFormat() == ImageFormat.ISO) { + volumeMgr.allocateRawVolume(Type.ROOT, "ROOT-" + vmFinal.getId(), rootDiskOffering.first(), rootDiskOffering.second(), vmFinal, template, owner); + } else if (template.getFormat() == ImageFormat.BAREMETAL) { + // Do nothing + } else { + volumeMgr.allocateTemplatedVolume(Type.ROOT, "ROOT-" + vmFinal.getId(), rootDiskOffering.first(), rootDiskOffering.second(), template, vmFinal, owner); + } + + for (Map.Entry offering : dataDiskOfferingsFinal.entrySet()) { + volumeMgr.allocateRawVolume(Type.DATADISK, "DATA-" + vmFinal.getId(), offering.getKey(), offering.getValue(), vmFinal, template, owner); + } + } + }); if (s_logger.isDebugEnabled()) { - s_logger.debug("Allocating disks for " + vmFinal); + s_logger.debug("Allocation completed for VM: " + vmFinal); } - - if (template.getFormat() == ImageFormat.ISO) { - volumeMgr.allocateRawVolume(Type.ROOT, "ROOT-" + vmFinal.getId(), rootDiskOffering.first(), rootDiskOffering.second(), vmFinal, template, owner); - } else if (template.getFormat() == ImageFormat.BAREMETAL) { - // Do nothing - } else { - volumeMgr.allocateTemplatedVolume(Type.ROOT, "ROOT-" + vmFinal.getId(), rootDiskOffering.first(), rootDiskOffering.second(), template, vmFinal, owner); - } - - for (Map.Entry offering : dataDiskOfferingsFinal.entrySet()) { - volumeMgr.allocateRawVolume(Type.DATADISK, "DATA-" + vmFinal.getId(), offering.getKey(), offering.getValue(), vmFinal, template, owner); - } - } - }); - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Allocation completed for VM: " + vmFinal); - } } @Override public void allocate(String vmInstanceName, VirtualMachineTemplate template, ServiceOffering serviceOffering, - LinkedHashMap networks, DeploymentPlan plan, HypervisorType hyperType) throws InsufficientCapacityException { + LinkedHashMap networks, DeploymentPlan plan, HypervisorType hyperType) throws InsufficientCapacityException { allocate(vmInstanceName, template, serviceOffering, new Pair(serviceOffering, null), null, networks, plan, hyperType); } @@ -645,7 +645,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac @DB protected Ternary changeToStartState(VirtualMachineGuru vmGuru, final VMInstanceVO vm, final User caller, - final Account account) throws ConcurrentOperationException { + final Account account) throws ConcurrentOperationException { long vmId = vm.getId(); ItWorkVO work = new ItWorkVO(UUID.randomUUID().toString(), _nodeId, State.Starting, vm.getType(), vm.getId()); @@ -654,23 +654,23 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac try { final ItWorkVO workFinal = work; Ternary result = - Transaction.execute(new TransactionCallbackWithException, NoTransitionException>() { - @Override - public Ternary doInTransaction(TransactionStatus status) throws NoTransitionException { - Journal journal = new Journal.LogJournal("Creating " + vm, s_logger); - ItWorkVO work = _workDao.persist(workFinal); - ReservationContextImpl context = new ReservationContextImpl(work.getId(), journal, caller, account); + Transaction.execute(new TransactionCallbackWithException, NoTransitionException>() { + @Override + public Ternary doInTransaction(TransactionStatus status) throws NoTransitionException { + Journal journal = new Journal.LogJournal("Creating " + vm, s_logger); + ItWorkVO work = _workDao.persist(workFinal); + ReservationContextImpl context = new ReservationContextImpl(work.getId(), journal, caller, account); - if (stateTransitTo(vm, Event.StartRequested, null, work.getId())) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Successfully transitioned to start state for " + vm + " reservation id = " + work.getId()); + if (stateTransitTo(vm, Event.StartRequested, null, work.getId())) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Successfully transitioned to start state for " + vm + " reservation id = " + work.getId()); + } + return new Ternary(vm, context, work); } - return new Ternary(vm, context, work); - } - return new Ternary(null, null, work); - } - }); + return new Ternary(null, null, work); + } + }); work = result.third(); if (result.first() != null) @@ -742,13 +742,13 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac @Override public void advanceStart(String vmUuid, Map params, DeploymentPlanner planner) - throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException { + throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException { advanceStart(vmUuid, params, null, planner); } @Override public void advanceStart(String vmUuid, Map params, DeploymentPlan planToDeploy, DeploymentPlanner planner) throws InsufficientCapacityException, - ConcurrentOperationException, ResourceUnavailableException { + ConcurrentOperationException, ResourceUnavailableException { AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext(); if (!VmJobEnabled.value() || jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) { @@ -768,7 +768,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac Outcome outcome = startVmThroughJobQueue(vmUuid, params, planToDeploy); try { - VirtualMachine vm = outcome.get(); + outcome.get(); } catch (InterruptedException e) { throw new RuntimeException("Operation is interrupted", e); } catch (java.util.concurrent.ExecutionException e) { @@ -818,11 +818,11 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac if (planToDeploy != null && planToDeploy.getDataCenterId() != 0) { if (s_logger.isDebugEnabled()) { s_logger.debug("advanceStart: DeploymentPlan is provided, using dcId:" + planToDeploy.getDataCenterId() + ", podId: " + planToDeploy.getPodId() + - ", clusterId: " + planToDeploy.getClusterId() + ", hostId: " + planToDeploy.getHostId() + ", poolId: " + planToDeploy.getPoolId()); + ", clusterId: " + planToDeploy.getClusterId() + ", hostId: " + planToDeploy.getHostId() + ", poolId: " + planToDeploy.getPoolId()); } plan = - new DataCenterDeployment(planToDeploy.getDataCenterId(), planToDeploy.getPodId(), planToDeploy.getClusterId(), planToDeploy.getHostId(), - planToDeploy.getPoolId(), planToDeploy.getPhysicalNetworkId(), ctx); + new DataCenterDeployment(planToDeploy.getDataCenterId(), planToDeploy.getPodId(), planToDeploy.getClusterId(), planToDeploy.getHostId(), + planToDeploy.getPoolId(), planToDeploy.getPhysicalNetworkId(), ctx); } HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vm.getHypervisorType()); @@ -880,21 +880,21 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac // 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); + 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); + "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(), null, ctx); + new DataCenterDeployment(planToDeploy.getDataCenterId(), planToDeploy.getPodId(), planToDeploy.getClusterId(), + planToDeploy.getHostId(), vol.getPoolId(), null, ctx); } else { plan = new DataCenterDeployment(rootVolDcId, rootVolPodId, rootVolClusterId, null, vol.getPoolId(), null, ctx); 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); + " , and clusterId: " + rootVolClusterId); } planChangedByVolume = true; } @@ -922,7 +922,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac continue; } throw new InsufficientServerCapacityException("Unable to create a deployment for " + vmProfile, DataCenter.class, plan.getDataCenterId(), - areAffinityGroupsAssociated(vmProfile)); + areAffinityGroupsAssociated(vmProfile)); } if (dest != null) { @@ -937,9 +937,9 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac ClusterDetailsVO cluster_detail_ram = _clusterDetailsDao.findDetail(cluster_id, "memoryOvercommitRatio"); //storing the value of overcommit in the vm_details table for doing a capacity check in case the cluster overcommit ratio is changed. if (_uservmDetailsDao.findDetail(vm.getId(), "cpuOvercommitRatio") == null && - ((Float.parseFloat(cluster_detail_cpu.getValue()) > 1f || Float.parseFloat(cluster_detail_ram.getValue()) > 1f))) { - _uservmDetailsDao.addDetail(vm.getId(), "cpuOvercommitRatio", cluster_detail_cpu.getValue(), true); - _uservmDetailsDao.addDetail(vm.getId(), "memoryOvercommitRatio", cluster_detail_ram.getValue(), true); + ((Float.parseFloat(cluster_detail_cpu.getValue()) > 1f || Float.parseFloat(cluster_detail_ram.getValue()) > 1f))) { + _uservmDetailsDao.addDetail(vm.getId(), "cpuOvercommitRatio", cluster_detail_cpu.getValue()); + _uservmDetailsDao.addDetail(vm.getId(), "memoryOvercommitRatio", cluster_detail_ram.getValue()); } else if (_uservmDetailsDao.findDetail(vm.getId(), "cpuOvercommitRatio") != null) { _uservmDetailsDao.addDetail(vm.getId(), "cpuOvercommitRatio", cluster_detail_cpu.getValue(), true); _uservmDetailsDao.addDetail(vm.getId(), "memoryOvercommitRatio", cluster_detail_ram.getValue(), true); @@ -1204,13 +1204,18 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac _userVmDao.saveDetails(userVm); } } - } - if (!answer.getResult()) { - s_logger.debug("Unable to stop VM due to " + answer.getDetails()); + + if (!answer.getResult()) { + s_logger.debug("Unable to stop VM due to " + answer.getDetails()); + return false; + } + + guru.finalizeStop(profile, answer); + } else { + s_logger.error("Invalid answer received in response to a StopCommand for " + vm.getInstanceName()); return false; } - guru.finalizeStop(profile, answer); } catch (AgentUnavailableException e) { if (!force) { return false; @@ -1311,7 +1316,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac Outcome outcome = stopVmThroughJobQueue(vmUuid, cleanUpEvenIfUnableToStop); try { - VirtualMachine vm = outcome.get(); + outcome.get(); } catch (InterruptedException e) { throw new RuntimeException("Operation is interrupted", e); } catch (java.util.concurrent.ExecutionException e) { @@ -1337,7 +1342,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } private void advanceStop(VMInstanceVO vm, boolean cleanUpEvenIfUnableToStop) throws AgentUnavailableException, OperationTimedoutException, - ConcurrentOperationException { + ConcurrentOperationException { State state = vm.getState(); if (state == State.Stopped) { if (s_logger.isDebugEnabled()) { @@ -1453,12 +1458,14 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac _userVmDao.saveDetails(userVm); } } + stopped = answer.getResult(); + if (!stopped) { + throw new CloudRuntimeException("Unable to stop the virtual machine due to " + answer.getDetails()); + } + vmGuru.finalizeStop(profile, answer); + } else { + throw new CloudRuntimeException("Invalid answer received in response to a StopCommand on " + vm.instanceName); } - stopped = answer.getResult(); - if (!stopped) { - throw new CloudRuntimeException("Unable to stop the virtual machine due to " + answer.getDetails()); - } - vmGuru.finalizeStop(profile, answer); } catch (AgentUnavailableException e) { s_logger.warn("Unable to stop vm, agent unavailable: " + e.toString()); @@ -1618,7 +1625,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac Outcome outcome = migrateVmStorageThroughJobQueue(vmUuid, destPool); try { - VirtualMachine vm = outcome.get(); + outcome.get(); } catch (InterruptedException e) { throw new RuntimeException("Operation is interrupted", e); } catch (java.util.concurrent.ExecutionException e) { @@ -1710,7 +1717,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac Outcome outcome = migrateVmThroughJobQueue(vmUuid, srcHostId, dest); try { - VirtualMachine vm = outcome.get(); + outcome.get(); } catch (InterruptedException e) { throw new RuntimeException("Operation is interrupted", e); } catch (java.util.concurrent.ExecutionException e) { @@ -1868,8 +1875,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac _networkMgr.rollbackNicForMigration(vmSrc, profile); _alertMgr.sendAlert(alertType, fromHost.getDataCenterId(), fromHost.getPodId(), - "Unable to migrate vm " + vm.getInstanceName() + " from host " + fromHost.getName() + " in zone " + dest.getDataCenter().getName() + " and pod " + - dest.getPod().getName(), "Migrate Command failed. Please check logs."); + "Unable to migrate vm " + vm.getInstanceName() + " from host " + fromHost.getName() + " in zone " + dest.getDataCenter().getName() + " and pod " + + dest.getPod().getName(), "Migrate Command failed. Please check logs."); try { _agentMgr.send(dstHostId, new Commands(cleanup(vm)), null); } catch (AgentUnavailableException ae) { @@ -1902,8 +1909,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac if (_poolHostDao.findByPoolHost(pool.getId(), host.getId()) == null || pool.isLocal() != diskOffering.getUseLocalStorage()) { // Cannot find a pool for the volume. Throw an exception. throw new CloudRuntimeException("Cannot migrate volume " + volume + " to storage pool " + pool + " while migrating vm to host " + host + - ". Either the pool is not accessible from the " + "host or because of the offering with which the volume is created it cannot be placed on " + - "the given pool."); + ". Either the pool is not accessible from the " + "host or because of the offering with which the volume is created it cannot be placed on " + + "the given pool."); } else if (pool.getId() == currentPool.getId()) { // If the pool to migrate too is the same as current pool, remove the volume from the list of // volumes to be migrated. @@ -1935,7 +1942,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac if (!currentPoolAvailable && !volumeToPool.containsKey(volume)) { // Cannot find a pool for the volume. Throw an exception. throw new CloudRuntimeException("Cannot find a storage pool which is available for volume " + volume + " while migrating virtual machine " + - profile.getVirtualMachine() + " to host " + host); + profile.getVirtualMachine() + " to host " + host); } } } @@ -1993,7 +2000,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac Outcome outcome = migrateVmWithStorageThroughJobQueue(vmUuid, srcHostId, destHostId, volumeToPool); try { - VirtualMachine vm = outcome.get(); + outcome.get(); } catch (InterruptedException e) { throw new RuntimeException("Operation is interrupted", e); } catch (java.util.concurrent.ExecutionException e) { @@ -2011,7 +2018,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } private void orchestrateMigrateWithStorage(String vmUuid, long srcHostId, long destHostId, Map volumeToPool) throws ResourceUnavailableException, - ConcurrentOperationException { + ConcurrentOperationException { VMInstanceVO vm = _vmDao.findByUuid(vmUuid); @@ -2032,7 +2039,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac // a vm and not migrating a vm with storage. if (volumeToPool.isEmpty()) { throw new InvalidParameterValueException("Migration of the vm " + vm + "from host " + srcHost + " to destination host " + destHost + - " doesn't involve migrating the volumes."); + " doesn't involve migrating the volumes."); } AlertManager.AlertType alertType = AlertManager.AlertType.ALERT_TYPE_USERVM_MIGRATE; @@ -2085,8 +2092,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac if (!migrated) { s_logger.info("Migration was unsuccessful. Cleaning up: " + vm); _alertMgr.sendAlert(alertType, srcHost.getDataCenterId(), srcHost.getPodId(), - "Unable to migrate vm " + vm.getInstanceName() + " from host " + srcHost.getName() + " in zone " + dc.getName() + " and pod " + dc.getName(), - "Migrate Command failed. Please check logs."); + "Unable to migrate vm " + vm.getInstanceName() + " from host " + srcHost.getName() + " in zone " + dc.getName() + " and pod " + dc.getName(), + "Migrate Command failed. Please check logs."); try { _agentMgr.send(destHostId, new Commands(cleanup(vm.getInstanceName())), null); stateTransitTo(vm, Event.OperationFailed, srcHostId); @@ -2286,7 +2293,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac Outcome outcome = rebootVmThroughJobQueue(vmUuid, params); try { - VirtualMachine vm = outcome.get(); + outcome.get(); } catch (InterruptedException e) { throw new RuntimeException("Operation is interrupted", e); } catch (java.util.concurrent.ExecutionException e) { @@ -2311,10 +2318,11 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac DataCenter dc = _entityMgr.findById(DataCenter.class, vm.getDataCenterId()); Host host = _hostDao.findById(vm.getHostId()); - Cluster cluster = null; - if (host != null) { - cluster = _entityMgr.findById(Cluster.class, host.getClusterId()); + if (host == null) { + // Should findById throw an Exception is the host is not found? + throw new CloudRuntimeException("Unable to retrieve host with id " + vm.getHostId()); } + Cluster cluster = _entityMgr.findById(Cluster.class, host.getClusterId()); Pod pod = _entityMgr.findById(Pod.class, host.getPodId()); DeployDestination dest = new DeployDestination(dc, pod, cluster, host); @@ -2355,7 +2363,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac // sync VM Snapshots related transient states List vmSnapshotsInTrasientStates = - _vmSnapshotDao.listByInstanceId(vm.getId(), VMSnapshot.State.Expunging, VMSnapshot.State.Reverting, VMSnapshot.State.Creating); + _vmSnapshotDao.listByInstanceId(vm.getId(), VMSnapshot.State.Expunging, VMSnapshot.State.Reverting, VMSnapshot.State.Creating); if (vmSnapshotsInTrasientStates.size() > 1) { s_logger.info("Found vm " + vm.getInstanceName() + " with VM snapshots in transient states, needs to sync VM snapshot state"); if (!_vmSnapshotMgr.syncVMSnapshot(vm, hostId)) { @@ -2478,7 +2486,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac // sync VM Snapshots related transient states List vmSnapshotsInExpungingStates = - _vmSnapshotDao.listByInstanceId(vm.getId(), VMSnapshot.State.Expunging, VMSnapshot.State.Creating, VMSnapshot.State.Reverting); + _vmSnapshotDao.listByInstanceId(vm.getId(), VMSnapshot.State.Expunging, VMSnapshot.State.Creating, VMSnapshot.State.Reverting); if (vmSnapshotsInExpungingStates.size() > 0) { s_logger.info("Found vm " + vm.getInstanceName() + " in state. " + vm.getState() + ", needs to sync VM snapshot state"); Long hostId = null; @@ -2496,9 +2504,9 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } if ((info == null && (vm.getState() == State.Running || vm.getState() == State.Starting)) || - (info != null && (info.state == State.Running && vm.getState() == State.Starting))) { + (info != null && (info.state == State.Running && vm.getState() == State.Starting))) { s_logger.info("Found vm " + vm.getInstanceName() + " in inconsistent state. " + vm.getState() + " on CS while " + (info == null ? "Stopped" : "Running") + - " on agent"); + " on agent"); info = new AgentVmInfo(vm.getInstanceName(), vm, State.Stopped); // Bug 13850- grab outstanding work item if any for this VM state so that we mark it as DONE after we change VM state, else it will remain pending @@ -2535,7 +2543,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac e.printStackTrace(); } } else if (info != null && - (vm.getState() == State.Stopped || vm.getState() == State.Stopping || vm.isRemoved() || vm.getState() == State.Destroyed || vm.getState() == State.Expunging)) { + (vm.getState() == State.Stopped || vm.getState() == State.Stopping || vm.isRemoved() || vm.getState() == State.Destroyed || vm.getState() == State.Expunging)) { Host host = _hostDao.findByGuid(info.getHostUuid()); if (host != null) { s_logger.warn("Stopping a VM which is stopped/stopping/destroyed/expunging " + info.name); @@ -2554,19 +2562,19 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } } } else - // host id can change - if (info != null && vm.getState() == State.Running) { - // check for host id changes - Host host = _hostDao.findByGuid(info.getHostUuid()); - if (host != null && (vm.getHostId() == null || host.getId() != vm.getHostId())) { - s_logger.info("Found vm " + vm.getInstanceName() + " with inconsistent host in db, new host is " + host.getId()); - try { - stateTransitTo(vm, VirtualMachine.Event.AgentReportMigrated, host.getId()); - } catch (NoTransitionException e) { - s_logger.warn(e.getMessage()); + // host id can change + if (info != null && vm.getState() == State.Running) { + // check for host id changes + Host host = _hostDao.findByGuid(info.getHostUuid()); + if (host != null && (vm.getHostId() == null || host.getId() != vm.getHostId())) { + s_logger.info("Found vm " + vm.getInstanceName() + " with inconsistent host in db, new host is " + host.getId()); + try { + stateTransitTo(vm, VirtualMachine.Event.AgentReportMigrated, host.getId()); + } catch (NoTransitionException e) { + s_logger.warn(e.getMessage()); + } } } - } /* else if(info == null && vm.getState() == State.Stopping) { //Handling CS-13376 s_logger.warn("Marking the VM as Stopped as it was still stopping on the CS" +vm.getName()); vm.setState(State.Stopped); // Setting the VM as stopped on the DB and clearing it from the host @@ -2690,8 +2698,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac String hostDesc = "name: " + hostVO.getName() + " (id:" + hostVO.getId() + "), availability zone: " + dcVO.getName() + ", pod: " + podVO.getName(); _alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodIdToDeployIn(), "VM (name: " + vm.getInstanceName() + ", id: " + vm.getId() + - ") stopped on host " + hostDesc + " due to storage failure", "Virtual Machine " + vm.getInstanceName() + " (id: " + vm.getId() + ") running on host [" + - vm.getHostId() + "] stopped due to storage failure."); + ") stopped on host " + hostDesc + " due to storage failure", "Virtual Machine " + vm.getInstanceName() + " (id: " + vm.getId() + ") running on host [" + + vm.getHostId() + "] stopped due to storage failure."); } // track platform info if (info.platform != null && !info.platform.isEmpty()) { @@ -2707,7 +2715,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac if (serverState == State.Starting) { if (vm.getHostId() != null && vm.getHostId() != hostId) { s_logger.info("CloudStack is starting VM on host " + vm.getHostId() + ", but status report comes from a different host " + hostId + - ", skip status sync for vm: " + vm.getInstanceName()); + ", skip status sync for vm: " + vm.getInstanceName()); return null; } } @@ -2732,7 +2740,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac if (serverState == State.Starting) { if (vm.getHostId() != null && vm.getHostId() != hostId) { s_logger.info("CloudStack is starting VM on host " + vm.getHostId() + ", but status report comes from a different host " + hostId + - ", skip status sync for vm: " + vm.getInstanceName()); + ", skip status sync for vm: " + vm.getInstanceName()); return null; } } @@ -2748,7 +2756,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac if (vm.getHostId() == null || hostId != vm.getHostId()) { if (s_logger.isDebugEnabled()) { s_logger.debug("detected host change when VM " + vm + " is at running state, VM could be live-migrated externally from host " + - vm.getHostId() + " to host " + hostId); + vm.getHostId() + " to host " + hostId); } stateTransitTo(vm, VirtualMachine.Event.AgentReportMigrated, hostId); @@ -2846,7 +2854,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } private void ensureVmRunningContext(long hostId, VMInstanceVO vm, Event cause) throws OperationTimedoutException, ResourceUnavailableException, - NoTransitionException, InsufficientAddressCapacityException { + NoTransitionException, InsufficientAddressCapacityException { VirtualMachineGuru vmGuru = getVmGuru(vm); s_logger.debug("VM state is starting on full sync so updating it to running"); @@ -2875,8 +2883,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac for (NicVO nic : nics) { Network network = _networkModel.getNetwork(nic.getNetworkId()); NicProfile nicProfile = - new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), null, _networkModel.isSecurityGroupSupportedInNetwork(network), - _networkModel.getNetworkTag(profile.getHypervisorType(), network)); + new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), null, _networkModel.isSecurityGroupSupportedInNetwork(network), + _networkModel.getNetworkTag(profile.getHypervisorType(), network)); profile.addNic(nicProfile); } @@ -3124,25 +3132,25 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac @Override public void checkIfCanUpgrade(VirtualMachine vmInstance, ServiceOffering newServiceOffering) { if (newServiceOffering == null) { - throw new InvalidParameterValueException("Unable to find a service offering with id " + newServiceOffering.getId()); + throw new InvalidParameterValueException("Invalid parameter, newServiceOffering can't be null"); } // Check that the VM is stopped / running if (!(vmInstance.getState().equals(State.Stopped) || vmInstance.getState().equals(State.Running))) { s_logger.warn("Unable to upgrade virtual machine " + vmInstance.toString() + " in state " + vmInstance.getState()); throw new InvalidParameterValueException("Unable to upgrade virtual machine " + vmInstance.toString() + " " + " in state " + vmInstance.getState() + - "; make sure the virtual machine is stopped/running"); + "; make sure the virtual machine is stopped/running"); } // Check if the service offering being upgraded to is what the VM is already running with if (!newServiceOffering.isDynamic() && vmInstance.getServiceOfferingId() == newServiceOffering.getId()) { if (s_logger.isInfoEnabled()) { s_logger.info("Not upgrading vm " + vmInstance.toString() + " since it already has the requested " + "service offering (" + newServiceOffering.getName() + - ")"); + ")"); } throw new InvalidParameterValueException("Not upgrading vm " + vmInstance.toString() + " since it already " + "has the requested service offering (" + - newServiceOffering.getName() + ")"); + newServiceOffering.getName() + ")"); } ServiceOfferingVO currentServiceOffering = _offeringDao.findByIdIncludingRemoved(vmInstance.getId(), vmInstance.getServiceOfferingId()); @@ -3160,8 +3168,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac // offering if (currentServiceOffering.getUseLocalStorage() != newServiceOffering.getUseLocalStorage()) { throw new InvalidParameterValueException("Unable to upgrade virtual machine " + vmInstance.toString() + - ", cannot switch between local storage and shared storage service offerings. Current offering " + "useLocalStorage=" + - currentServiceOffering.getUseLocalStorage() + ", target offering useLocalStorage=" + newServiceOffering.getUseLocalStorage()); + ", cannot switch between local storage and shared storage service offerings. Current offering " + "useLocalStorage=" + + currentServiceOffering.getUseLocalStorage() + ", target offering useLocalStorage=" + newServiceOffering.getUseLocalStorage()); } // if vm is a system vm, check if it is a system service offering, if yes return with error as it cannot be used for user vms @@ -3172,7 +3180,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac // Check that there are enough resources to upgrade the service offering if (!isVirtualMachineUpgradable(vmInstance, newServiceOffering)) { throw new InvalidParameterValueException("Unable to upgrade virtual machine, not enough resources available " + "for an offering of " + - newServiceOffering.getCpu() + " cpu(s) at " + newServiceOffering.getSpeed() + " Mhz, and " + newServiceOffering.getRamSize() + " MB of memory"); + newServiceOffering.getCpu() + " cpu(s) at " + newServiceOffering.getSpeed() + " Mhz, and " + newServiceOffering.getRamSize() + " MB of memory"); } // Check that the service offering being upgraded to has all the tags of the current service offering @@ -3180,7 +3188,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac List newTags = StringUtils.csvTagsToList(newServiceOffering.getTags()); if (!newTags.containsAll(currentTags)) { throw new InvalidParameterValueException("Unable to upgrade virtual machine; the new service offering " + "does not have all the tags of the " + - "current service offering. Current service offering tags: " + currentTags + "; " + "new service " + "offering tags: " + newTags); + "current service offering. Current service offering tags: " + currentTags + "; " + "new service " + "offering tags: " + newTags); } } @@ -3278,7 +3286,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac long isDefault = (nic.isDefaultNic()) ? 1 : 0; // insert nic's Id into DB as resource_name UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_ASSIGN, vmVO.getAccountId(), vmVO.getDataCenterId(), vmVO.getId(), - Long.toString(nic.getId()), network.getNetworkOfferingId(), null, isDefault, VirtualMachine.class.getName(), vmVO.getUuid()); + Long.toString(nic.getId()), network.getNetworkOfferingId(), null, isDefault, VirtualMachine.class.getName(), vmVO.getUuid()); return nic; } else { s_logger.warn("Failed to plug nic to the vm " + vm + " in network " + network); @@ -3375,12 +3383,12 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac // if specified nic is associated with PF/LB/Static NAT if (rulesMgr.listAssociatedRulesForGuestNic(nic).size() > 0) { throw new CloudRuntimeException("Failed to remove nic from " + vm + " in " + network + - ", nic has associated Port forwarding or Load balancer or Static NAT rules."); + ", nic has associated Port forwarding or Load balancer or Static NAT rules."); } NicProfile nicProfile = - new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), _networkModel.getNetworkRate(network.getId(), vm.getId()), - _networkModel.isSecurityGroupSupportedInNetwork(network), _networkModel.getNetworkTag(vmProfile.getVirtualMachine().getHypervisorType(), network)); + new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), _networkModel.getNetworkRate(network.getId(), vm.getId()), + _networkModel.isSecurityGroupSupportedInNetwork(network), _networkModel.getNetworkTag(vmProfile.getVirtualMachine().getHypervisorType(), network)); //1) Unplug the nic if (vm.getState() == State.Running) { @@ -3391,7 +3399,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac s_logger.debug("Nic is unplugged successfully for vm " + vm + " in network " + network); long isDefault = (nic.isDefaultNic()) ? 1 : 0; UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_REMOVE, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), - Long.toString(nic.getId()), network.getNetworkOfferingId(), null, isDefault, VirtualMachine.class.getName(), vm.getUuid()); + Long.toString(nic.getId()), network.getNetworkOfferingId(), null, isDefault, VirtualMachine.class.getName(), vm.getUuid()); } else { s_logger.warn("Failed to unplug nic for the vm " + vm + " from network " + network); return false; @@ -3469,8 +3477,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac try { NicProfile nicProfile = - new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), _networkModel.getNetworkRate(network.getId(), vm.getId()), - _networkModel.isSecurityGroupSupportedInNetwork(network), _networkModel.getNetworkTag(vmProfile.getVirtualMachine().getHypervisorType(), network)); + new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), _networkModel.getNetworkRate(network.getId(), vm.getId()), + _networkModel.isSecurityGroupSupportedInNetwork(network), _networkModel.getNetworkTag(vmProfile.getVirtualMachine().getHypervisorType(), network)); //1) Unplug the nic if (vm.getState() == State.Running) { @@ -3507,7 +3515,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac @Override public void findHostAndMigrate(String vmUuid, Long newSvcOfferingId, ExcludeList excludes) throws InsufficientCapacityException, ConcurrentOperationException, - ResourceUnavailableException { + ResourceUnavailableException { VMInstanceVO vm = _vmDao.findByUuid(vmUuid); if (vm == null) { @@ -3578,7 +3586,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac Outcome outcome = migrateVmForScaleThroughJobQueue(vmUuid, srcHostId, dest, oldSvcOfferingId); try { - VirtualMachine vm = outcome.get(); + outcome.get(); } catch (InterruptedException e) { throw new RuntimeException("Operation is interrupted", e); } catch (java.util.concurrent.ExecutionException e) { @@ -3731,8 +3739,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac s_logger.info("Migration was unsuccessful. Cleaning up: " + vm); _alertMgr.sendAlert(alertType, fromHost.getDataCenterId(), fromHost.getPodId(), - "Unable to migrate vm " + vm.getInstanceName() + " from host " + fromHost.getName() + " in zone " + dest.getDataCenter().getName() + " and pod " + - dest.getPod().getName(), "Migrate Command failed. Please check logs."); + "Unable to migrate vm " + vm.getInstanceName() + " from host " + fromHost.getName() + " in zone " + dest.getDataCenter().getName() + " and pod " + + dest.getPod().getName(), "Migrate Command failed. Please check logs."); try { _agentMgr.send(dstHostId, new Commands(cleanup(vm.getInstanceName())), null); } catch (AgentUnavailableException ae) { @@ -3752,7 +3760,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } public boolean plugNic(Network network, NicTO nic, VirtualMachineTO vm, ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, - ResourceUnavailableException, InsufficientCapacityException { + ResourceUnavailableException, InsufficientCapacityException { boolean result = true; VMInstanceVO router = _vmDao.findById(vm.getId()); @@ -3775,14 +3783,14 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac s_logger.warn("Unable to apply PlugNic, vm " + router + " is not in the right state " + router.getState()); throw new ResourceUnavailableException("Unable to apply PlugNic on the backend," + " vm " + vm + " is not in the right state", DataCenter.class, - router.getDataCenterId()); + router.getDataCenterId()); } return result; } public boolean unplugNic(Network network, NicTO nic, VirtualMachineTO vm, ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, - ResourceUnavailableException { + ResourceUnavailableException { boolean result = true; VMInstanceVO router = _vmDao.findById(vm.getId()); @@ -3808,7 +3816,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac s_logger.warn("Unable to apply unplug nic, Vm " + router + " is not in the right state " + router.getState()); throw new ResourceUnavailableException("Unable to apply unplug nic on the backend," + " vm " + router + " is not in the right state", DataCenter.class, - router.getDataCenterId()); + router.getDataCenterId()); } return result; @@ -3817,7 +3825,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac @Override public VMInstanceVO reConfigureVm(String vmUuid, ServiceOffering oldServiceOffering, boolean reconfiguringOnExistingHost) - throws ResourceUnavailableException, InsufficientServerCapacityException, ConcurrentOperationException { + throws ResourceUnavailableException, InsufficientServerCapacityException, ConcurrentOperationException { AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext(); if (!VmJobEnabled.value() || jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) { @@ -3875,8 +3883,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac Float cpuOvercommitRatio = CapacityManager.CpuOverprovisioningFactor.valueIn(hostVo.getClusterId()); long minMemory = (long)(newServiceOffering.getRamSize() / memoryOvercommitRatio); ScaleVmCommand reconfigureCmd = - new ScaleVmCommand(vm.getInstanceName(), newServiceOffering.getCpu(), (int)(newServiceOffering.getSpeed() / cpuOvercommitRatio), - newServiceOffering.getSpeed(), minMemory * 1024L * 1024L, newServiceOffering.getRamSize() * 1024L * 1024L, newServiceOffering.getLimitCpuUse()); + new ScaleVmCommand(vm.getInstanceName(), newServiceOffering.getCpu(), (int)(newServiceOffering.getSpeed() / cpuOvercommitRatio), + newServiceOffering.getSpeed(), minMemory * 1024L * 1024L, newServiceOffering.getRamSize() * 1024L * 1024L, newServiceOffering.getLimitCpuUse()); Long dstHostId = vm.getHostId(); ItWorkVO work = new ItWorkVO(UUID.randomUUID().toString(), _nodeId, State.Running, vm.getType(), vm.getId()); @@ -3926,8 +3934,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac @Override public ConfigKey[] getConfigKeys() { return new ConfigKey[] {ClusterDeltaSyncInterval, StartRetry, VmDestroyForcestop, VmOpCancelInterval, VmOpCleanupInterval, VmOpCleanupWait, - VmOpLockStateRetry, - VmOpWaitInterval, ExecuteInSequence, VmJobCheckInterval, VmJobTimeout, VmJobStateReportInterval}; + VmOpLockStateRetry, + VmOpWaitInterval, ExecuteInSequence, VmJobCheckInterval, VmJobTimeout, VmJobStateReportInterval}; } public List getStoragePoolAllocators() { @@ -3963,8 +3971,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac handlePowerOffReportWithNoPendingJobsOnVM(vm); break; - // PowerUnknown shouldn't be reported, it is a derived - // VM power state from host state (host un-reachable) + // PowerUnknown shouldn't be reported, it is a derived + // VM power state from host state (host un-reachable) case PowerUnknown: default: assert (false); @@ -3998,7 +4006,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac // we need to alert admin or user about this risky state transition _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_SYNC, vm.getDataCenterId(), vm.getPodIdToDeployIn(), VM_SYNC_ALERT_SUBJECT, "VM " + vm.getHostName() + "(" + vm.getInstanceName() - + ") state is sync-ed (Starting -> Running) from out-of-context transition. VM network environment may need to be reset"); + + ") state is sync-ed (Starting -> Running) from out-of-context transition. VM network environment may need to be reset"); break; case Running: @@ -4020,7 +4028,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_SYNC, vm.getDataCenterId(), vm.getPodIdToDeployIn(), VM_SYNC_ALERT_SUBJECT, "VM " + vm.getHostName() + "(" + vm.getInstanceName() + ") state is sync-ed (" + vm.getState() - + " -> Running) from out-of-context transition. VM network environment may need to be reset"); + + " -> Running) from out-of-context transition. VM network environment may need to be reset"); break; case Destroyed: @@ -4063,7 +4071,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_SYNC, vm.getDataCenterId(), vm.getPodIdToDeployIn(), VM_SYNC_ALERT_SUBJECT, "VM " + vm.getHostName() + "(" + vm.getInstanceName() + ") state is sync-ed (" + vm.getState() - + " -> Stopped) from out-of-context transition."); + + " -> Stopped) from out-of-context transition."); // TODO: we need to forcely release all resource allocation break; @@ -4123,7 +4131,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac // We now only alert administrator about this situation _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_SYNC, vm.getDataCenterId(), vm.getPodIdToDeployIn(), VM_SYNC_ALERT_SUBJECT, "VM " + vm.getHostName() + "(" + vm.getInstanceName() + ") is stuck in " + vm.getState() - + " state and its host is unreachable for too long"); + + " state and its host is unreachable for too long"); } } diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java index 047e10a0c92..d3eda8a3721 100644 --- a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java +++ b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java @@ -693,11 +693,14 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati vol = copyVolume(rootDiskPool, volume, vm, rootDiskTmplt, dcVO, pod, diskVO, svo, rootDiskHyperType); if (vol != null) { // Moving of Volume is successful, decrement the volume resource count from secondary for an account and increment it into primary storage under same account. - _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.secondary_storage, new Long(volume.getSize())); - _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, new Long(volume.getSize())); + _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.secondary_storage, volume.getSize()); + _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, volume.getSize()); } } + if (vol == null) { + throw new CloudRuntimeException("Volume shouldn't be null " + volume.getId()); + } VolumeVO volVO = _volsDao.findById(vol.getId()); volVO.setFormat(getSupportedImageFormatForCluster(rootDiskHyperType)); _volsDao.update(volVO.getId(), volVO); diff --git a/engine/orchestration/test/com/cloud/vm/VirtualMachineManagerImplTest.java b/engine/orchestration/test/com/cloud/vm/VirtualMachineManagerImplTest.java index 997855d2b24..49b2fc5fb11 100644 --- a/engine/orchestration/test/com/cloud/vm/VirtualMachineManagerImplTest.java +++ b/engine/orchestration/test/com/cloud/vm/VirtualMachineManagerImplTest.java @@ -30,6 +30,8 @@ import java.util.Iterator; import java.util.List; import java.util.Map; +import junit.framework.Assert; + import org.junit.Before; import org.junit.Test; import org.mockito.Matchers; @@ -46,9 +48,9 @@ import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import com.cloud.agent.AgentManager; -import com.cloud.agent.api.Answer; import com.cloud.agent.api.CheckVirtualMachineAnswer; import com.cloud.agent.api.CheckVirtualMachineCommand; +import com.cloud.agent.api.Command; import com.cloud.agent.api.MigrateWithStorageAnswer; import com.cloud.agent.api.MigrateWithStorageCommand; import com.cloud.agent.api.MigrateWithStorageCompleteAnswer; @@ -61,6 +63,8 @@ import com.cloud.agent.api.PrepareForMigrationAnswer; import com.cloud.agent.api.PrepareForMigrationCommand; import com.cloud.agent.api.ScaleVmAnswer; import com.cloud.agent.api.ScaleVmCommand; +import com.cloud.agent.api.StopAnswer; +import com.cloud.agent.api.StopCommand; import com.cloud.capacity.CapacityManager; import com.cloud.dc.dao.ClusterDao; import com.cloud.dc.dao.DataCenterDao; @@ -257,9 +261,7 @@ public class VirtualMachineManagerImplTest { @Test(expected = CloudRuntimeException.class) public void testScaleVM2() throws Exception { - DeployDestination dest = new DeployDestination(null, null, null, _host); - long l = 1L; - + new DeployDestination(null, null, null, _host); doReturn(3L).when(_vmInstance).getId(); when(_vmInstanceDao.findById(anyLong())).thenReturn(_vmInstance); ServiceOfferingVO newServiceOffering = getSvcoffering(512); @@ -269,9 +271,9 @@ public class VirtualMachineManagerImplTest { doReturn(1L).when(hostVO).getClusterId(); when(CapacityManager.CpuOverprovisioningFactor.valueIn(1L)).thenReturn(1.0f); ScaleVmCommand reconfigureCmd = - new ScaleVmCommand("myVmName", newServiceOffering.getCpu(), newServiceOffering.getSpeed(), newServiceOffering.getSpeed(), newServiceOffering.getRamSize(), - newServiceOffering.getRamSize(), newServiceOffering.getLimitCpuUse()); - Answer answer = new ScaleVmAnswer(reconfigureCmd, true, "details"); + new ScaleVmCommand("myVmName", newServiceOffering.getCpu(), newServiceOffering.getSpeed(), newServiceOffering.getSpeed(), newServiceOffering.getRamSize(), + newServiceOffering.getRamSize(), newServiceOffering.getLimitCpuUse()); + new ScaleVmAnswer(reconfigureCmd, true, "details"); when(_agentMgr.send(2l, reconfigureCmd)).thenReturn(null); _vmMgr.reConfigureVm(_vmInstance.getUuid(), getSvcoffering(256), false); @@ -298,7 +300,6 @@ public class VirtualMachineManagerImplTest { private ServiceOfferingVO getSvcoffering(int ramSize) { - long id = 4L; String name = "name"; String displayText = "displayText"; int cpu = 1; @@ -309,7 +310,7 @@ public class VirtualMachineManagerImplTest { boolean useLocalStorage = false; ServiceOfferingVO serviceOffering = - new ServiceOfferingVO(name, cpu, ramSize, speed, null, null, ha, displayText, useLocalStorage, false, null, false, null, false); + new ServiceOfferingVO(name, cpu, ramSize, speed, null, null, ha, displayText, useLocalStorage, false, null, false, null, false); return serviceOffering; } @@ -408,7 +409,7 @@ public class VirtualMachineManagerImplTest { // Check migration of a vm with its volumes within a cluster. @Test public void testMigrateWithVolumeWithinCluster() throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException, - VirtualMachineMigrationException, OperationTimedoutException { + VirtualMachineMigrationException, OperationTimedoutException { initializeMockConfigForMigratingVmWithVolumes(); when(_srcHostMock.getClusterId()).thenReturn(3L); @@ -420,7 +421,7 @@ public class VirtualMachineManagerImplTest { // Check migration of a vm with its volumes across a cluster. @Test public void testMigrateWithVolumeAcrossCluster() throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException, - VirtualMachineMigrationException, OperationTimedoutException { + VirtualMachineMigrationException, OperationTimedoutException { initializeMockConfigForMigratingVmWithVolumes(); when(_srcHostMock.getClusterId()).thenReturn(3L); @@ -433,7 +434,7 @@ public class VirtualMachineManagerImplTest { // other is local. @Test(expected = CloudRuntimeException.class) public void testMigrateWithVolumeFail1() throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException, - VirtualMachineMigrationException, OperationTimedoutException { + VirtualMachineMigrationException, OperationTimedoutException { initializeMockConfigForMigratingVmWithVolumes(); when(_srcHostMock.getClusterId()).thenReturn(3L); @@ -448,7 +449,7 @@ public class VirtualMachineManagerImplTest { // Check migration of a vm fails when vm is not in Running state. @Test(expected = ConcurrentOperationException.class) public void testMigrateWithVolumeFail2() throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException, - VirtualMachineMigrationException, OperationTimedoutException { + VirtualMachineMigrationException, OperationTimedoutException { initializeMockConfigForMigratingVmWithVolumes(); when(_srcHostMock.getClusterId()).thenReturn(3L); @@ -458,4 +459,48 @@ public class VirtualMachineManagerImplTest { _vmMgr.migrateWithStorage(_vmInstance.getUuid(), _srcHostMock.getId(), _destHostMock.getId(), _volumeToPoolMock); } + + @Test + public void testSendStopWithOkAnswer() throws Exception { + VirtualMachineGuru guru = mock(VirtualMachineGuru.class); + VirtualMachine vm = mock(VirtualMachine.class); + VirtualMachineProfile profile = mock(VirtualMachineProfile.class); + StopAnswer answer = new StopAnswer(new StopCommand(vm, false), "ok", true); + when(profile.getVirtualMachine()).thenReturn(vm); + when(vm.getHostId()).thenReturn(1L); + when(_agentMgr.send(anyLong(), (Command)any())).thenReturn(answer); + + boolean actual = _vmMgr.sendStop(guru, profile, false); + + Assert.assertTrue(actual); + } + + @Test + public void testSendStopWithFailAnswer() throws Exception { + VirtualMachineGuru guru = mock(VirtualMachineGuru.class); + VirtualMachine vm = mock(VirtualMachine.class); + VirtualMachineProfile profile = mock(VirtualMachineProfile.class); + StopAnswer answer = new StopAnswer(new StopCommand(vm, false), "fail", false); + when(profile.getVirtualMachine()).thenReturn(vm); + when(vm.getHostId()).thenReturn(1L); + when(_agentMgr.send(anyLong(), (Command)any())).thenReturn(answer); + + boolean actual = _vmMgr.sendStop(guru, profile, false); + + Assert.assertFalse(actual); + } + + @Test + public void testSendStopWithNullAnswer() throws Exception { + VirtualMachineGuru guru = mock(VirtualMachineGuru.class); + VirtualMachine vm = mock(VirtualMachine.class); + VirtualMachineProfile profile = mock(VirtualMachineProfile.class); + when(profile.getVirtualMachine()).thenReturn(vm); + when(vm.getHostId()).thenReturn(1L); + when(_agentMgr.send(anyLong(), (Command)any())).thenReturn(null); + + boolean actual = _vmMgr.sendStop(guru, profile, false); + + Assert.assertFalse(actual); + } }