From 19edfdfcdbfe486b396ea7c03d8b7efb24c98b43 Mon Sep 17 00:00:00 2001 From: Alex Huang Date: Fri, 14 Jan 2011 08:55:43 -0800 Subject: [PATCH] migration code --- .../com/cloud/deploy/DeployDestination.java | 5 + .../AgentBasedConsoleProxyManager.java | 21 -- .../consoleproxy/ConsoleProxyManagerImpl.java | 200 ++++++------ .../StaticConsoleProxyManager.java | 6 - .../cloud/ha/HighAvailabilityManagerImpl.java | 294 +++++++++--------- .../VirtualNetworkApplianceManagerImpl.java | 214 ++++++------- .../SecondaryStorageManagerImpl.java | 199 ++++++------ .../src/com/cloud/vm/UserVmManagerImpl.java | 244 +++++++-------- .../src/com/cloud/vm/VirtualMachineGuru.java | 24 +- .../com/cloud/vm/VirtualMachineManager.java | 6 + .../cloud/vm/VirtualMachineManagerImpl.java | 178 ++++++++++- 11 files changed, 748 insertions(+), 643 deletions(-) diff --git a/api/src/com/cloud/deploy/DeployDestination.java b/api/src/com/cloud/deploy/DeployDestination.java index c3f91880327..01edf31ee16 100644 --- a/api/src/com/cloud/deploy/DeployDestination.java +++ b/api/src/com/cloud/deploy/DeployDestination.java @@ -81,4 +81,9 @@ public class DeployDestination { } return this._host.getId() == that._host.getId(); } + + @Override + public String toString() { + return new StringBuilder("Dest[").append(_dc.getId()).append("-").append(_pod.getId()).append("-").append(_cluster.getId()).append("-").append(_host.getId()).append("]").toString(); + } } diff --git a/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java b/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java index e77fec8d2e4..70ee22c8aeb 100644 --- a/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java +++ b/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java @@ -43,7 +43,6 @@ import com.cloud.deploy.DeployDestination; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; -import com.cloud.exception.OperationTimedoutException; import com.cloud.exception.StorageUnavailableException; import com.cloud.ha.HighAvailabilityManager; import com.cloud.host.HostVO; @@ -283,11 +282,6 @@ public class AgentBasedConsoleProxyManager implements ConsoleProxyManager, Virtu return new StopCommand(vm, vmName, null); } - @Override - public boolean completeMigration(ConsoleProxyVO vm, HostVO host) throws AgentUnavailableException, OperationTimedoutException { - return false; - } - @Override public void completeStartCommand(ConsoleProxyVO vm) { } @@ -304,21 +298,6 @@ public class AgentBasedConsoleProxyManager implements ConsoleProxyManager, Virtu return VirtualMachineName.getConsoleProxyId(vmName); } - @Override - public ConsoleProxyVO get(long id) { - return null; - } - - @Override - public boolean migrate(ConsoleProxyVO vm, HostVO host) throws AgentUnavailableException, OperationTimedoutException { - return false; - } - - @Override - public HostVO prepareForMigration(ConsoleProxyVO vm) throws InsufficientCapacityException, StorageUnavailableException { - return null; - } - @Override public ConsoleProxyVO start(long vmId) throws InsufficientCapacityException, StorageUnavailableException, ConcurrentOperationException { diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java index 4dd16cf5886..43bd535e03b 100644 --- a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java +++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java @@ -26,7 +26,6 @@ import java.util.ArrayList; import java.util.Date; import java.util.Enumeration; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.concurrent.ExecutorService; @@ -42,14 +41,10 @@ import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; import com.cloud.agent.api.AgentControlAnswer; 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.ConsoleAccessAuthenticationAnswer; import com.cloud.agent.api.ConsoleAccessAuthenticationCommand; import com.cloud.agent.api.ConsoleProxyLoadReportCommand; -import com.cloud.agent.api.MigrateCommand; -import com.cloud.agent.api.PrepareForMigrationCommand; import com.cloud.agent.api.RebootCommand; import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupProxyCommand; @@ -91,7 +86,6 @@ import com.cloud.exception.OperationTimedoutException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.exception.StorageUnavailableException; import com.cloud.ha.HighAvailabilityManager; -import com.cloud.host.Host; import com.cloud.host.Host.Type; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; @@ -115,7 +109,6 @@ import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.servlet.ConsoleProxyServlet; import com.cloud.storage.StorageManager; -import com.cloud.storage.StoragePoolVO; import com.cloud.storage.VMTemplateHostVO; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.VMTemplateVO; @@ -1464,11 +1457,6 @@ public class ConsoleProxyManagerImpl implements ConsoleProxyManager, ConsoleProx } } - @Override - public ConsoleProxyVO get(long id) { - return _consoleProxyDao.findById(id); - } - @Override public Long convertToId(String vmName) { if (!VirtualMachineName.isValidConsoleProxyName(vmName, _instance)) { @@ -1649,100 +1637,100 @@ public class ConsoleProxyManagerImpl implements ConsoleProxyManager, ConsoleProx } } - @Override - public boolean migrate(ConsoleProxyVO proxy, HostVO host) { - HostVO fromHost = _hostDao.findById(proxy.getId()); - - if (! _itMgr.stateTransitTo(proxy, VirtualMachine.Event.MigrationRequested, proxy.getHostId())) { - s_logger.debug("State for " + proxy.toString() + " has changed so migration can not take place."); - return false; - } - - MigrateCommand cmd = new MigrateCommand(proxy.getInstanceName(), host.getPrivateIpAddress(), false); - Answer answer = _agentMgr.easySend(fromHost.getId(), cmd); - if (answer == null || !answer.getResult()) { - return false; - } - - _storageMgr.unshare(proxy, fromHost); - - return true; - } - - @Override - public boolean completeMigration(ConsoleProxyVO proxy, HostVO host) throws AgentUnavailableException, OperationTimedoutException { - - CheckVirtualMachineCommand cvm = new CheckVirtualMachineCommand(proxy.getInstanceName()); - CheckVirtualMachineAnswer answer = (CheckVirtualMachineAnswer) _agentMgr.send(host.getId(), cvm); - if (!answer.getResult()) { - s_logger.debug("Unable to complete migration for " + proxy.getId()); - _itMgr.stateTransitTo(proxy, VirtualMachine.Event.AgentReportStopped, null); - return false; - } - - State state = answer.getState(); - if (state == State.Stopped) { - s_logger.warn("Unable to complete migration as we can not detect it on " + host.getId()); - _itMgr.stateTransitTo(proxy, VirtualMachine.Event.AgentReportStopped, null); - return false; - } - - _itMgr.stateTransitTo(proxy, VirtualMachine.Event.OperationSucceeded, host.getId()); - return true; - } - - @Override - public HostVO prepareForMigration(ConsoleProxyVO proxy) throws StorageUnavailableException { - - VMTemplateVO template = _templateDao.findById(proxy.getTemplateId()); - long routerId = proxy.getId(); - boolean mirroredVols = proxy.isMirroredVols(); - DataCenterVO dc = _dcDao.findById(proxy.getDataCenterId()); - HostPodVO pod = _podDao.findById(proxy.getPodId()); - StoragePoolVO sp = _storageMgr.getStoragePoolForVm(proxy.getId()); - - List vols = _volsDao.findCreatedByInstance(routerId); - - String[] storageIps = new String[2]; - VolumeVO vol = vols.get(0); - storageIps[0] = vol.getHostIp(); - if (mirroredVols && (vols.size() == 2)) { - storageIps[1] = vols.get(1).getHostIp(); - } - - PrepareForMigrationCommand cmd = new PrepareForMigrationCommand(proxy.getName(), null, storageIps, vols, mirroredVols); - - HostVO routingHost = null; - HashSet avoid = new HashSet(); - - HostVO fromHost = _hostDao.findById(proxy.getHostId()); - if (fromHost.getClusterId() == null) { - s_logger.debug("The host is not in a cluster"); - return null; - } - avoid.add(fromHost); - - while ((routingHost = (HostVO) _agentMgr.findHost(Host.Type.Routing, dc, pod, sp, _serviceOffering, template, proxy, fromHost, avoid)) != null) { - avoid.add(routingHost); - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Trying to migrate router to host " + routingHost.getName()); - } - - if (!_storageMgr.share(proxy, vols, routingHost, false)) { - s_logger.warn("Can not share " + proxy.getName()); - throw new StorageUnavailableException("Can not share " + proxy.getName(), vol.getPoolId()); - } - - Answer answer = _agentMgr.easySend(routingHost.getId(), cmd); - if (answer != null && answer.getResult()) { - return routingHost; - } - _storageMgr.unshare(proxy, vols, routingHost); - } - - return null; - } +// @Override +// public boolean migrate(ConsoleProxyVO proxy, HostVO host) { +// HostVO fromHost = _hostDao.findById(proxy.getId()); +// +// if (! _itMgr.stateTransitTo(proxy, VirtualMachine.Event.MigrationRequested, proxy.getHostId())) { +// s_logger.debug("State for " + proxy.toString() + " has changed so migration can not take place."); +// return false; +// } +// +// MigrateCommand cmd = new MigrateCommand(proxy.getInstanceName(), host.getPrivateIpAddress(), false); +// Answer answer = _agentMgr.easySend(fromHost.getId(), cmd); +// if (answer == null || !answer.getResult()) { +// return false; +// } +// +// _storageMgr.unshare(proxy, fromHost); +// +// return true; +// } +// +// @Override +// public boolean completeMigration(ConsoleProxyVO proxy, HostVO host) throws AgentUnavailableException, OperationTimedoutException { +// +// CheckVirtualMachineCommand cvm = new CheckVirtualMachineCommand(proxy.getInstanceName()); +// CheckVirtualMachineAnswer answer = (CheckVirtualMachineAnswer) _agentMgr.send(host.getId(), cvm); +// if (!answer.getResult()) { +// s_logger.debug("Unable to complete migration for " + proxy.getId()); +// _itMgr.stateTransitTo(proxy, VirtualMachine.Event.AgentReportStopped, null); +// return false; +// } +// +// State state = answer.getState(); +// if (state == State.Stopped) { +// s_logger.warn("Unable to complete migration as we can not detect it on " + host.getId()); +// _itMgr.stateTransitTo(proxy, VirtualMachine.Event.AgentReportStopped, null); +// return false; +// } +// +// _itMgr.stateTransitTo(proxy, VirtualMachine.Event.OperationSucceeded, host.getId()); +// return true; +// } +// +// @Override +// public HostVO prepareForMigration(ConsoleProxyVO proxy) throws StorageUnavailableException { +// +// VMTemplateVO template = _templateDao.findById(proxy.getTemplateId()); +// long routerId = proxy.getId(); +// boolean mirroredVols = proxy.isMirroredVols(); +// DataCenterVO dc = _dcDao.findById(proxy.getDataCenterId()); +// HostPodVO pod = _podDao.findById(proxy.getPodId()); +// StoragePoolVO sp = _storageMgr.getStoragePoolForVm(proxy.getId()); +// +// List vols = _volsDao.findCreatedByInstance(routerId); +// +// String[] storageIps = new String[2]; +// VolumeVO vol = vols.get(0); +// storageIps[0] = vol.getHostIp(); +// if (mirroredVols && (vols.size() == 2)) { +// storageIps[1] = vols.get(1).getHostIp(); +// } +// +// PrepareForMigrationCommand cmd = new PrepareForMigrationCommand(proxy.getName(), null, storageIps, vols, mirroredVols); +// +// HostVO routingHost = null; +// HashSet avoid = new HashSet(); +// +// HostVO fromHost = _hostDao.findById(proxy.getHostId()); +// if (fromHost.getClusterId() == null) { +// s_logger.debug("The host is not in a cluster"); +// return null; +// } +// avoid.add(fromHost); +// +// while ((routingHost = (HostVO) _agentMgr.findHost(Host.Type.Routing, dc, pod, sp, _serviceOffering, template, proxy, fromHost, avoid)) != null) { +// avoid.add(routingHost); +// +// if (s_logger.isDebugEnabled()) { +// s_logger.debug("Trying to migrate router to host " + routingHost.getName()); +// } +// +// if (!_storageMgr.share(proxy, vols, routingHost, false)) { +// s_logger.warn("Can not share " + proxy.getName()); +// throw new StorageUnavailableException("Can not share " + proxy.getName(), vol.getPoolId()); +// } +// +// Answer answer = _agentMgr.easySend(routingHost.getId(), cmd); +// if (answer != null && answer.getResult()) { +// return routingHost; +// } +// _storageMgr.unshare(proxy, vols, routingHost); +// } +// +// return null; +// } private String getCapacityScanLockName() { // to improve security, it may be better to return a unique mashed diff --git a/server/src/com/cloud/consoleproxy/StaticConsoleProxyManager.java b/server/src/com/cloud/consoleproxy/StaticConsoleProxyManager.java index c73f886b461..89d0f43f04f 100644 --- a/server/src/com/cloud/consoleproxy/StaticConsoleProxyManager.java +++ b/server/src/com/cloud/consoleproxy/StaticConsoleProxyManager.java @@ -29,7 +29,6 @@ import com.cloud.host.HostVO; import com.cloud.info.ConsoleProxyInfo; import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.component.Inject; -import com.cloud.vm.ConsoleProxyVO; import com.cloud.vm.VMInstanceVO; import com.cloud.vm.dao.ConsoleProxyDao; @@ -67,9 +66,4 @@ public class StaticConsoleProxyManager extends AgentBasedConsoleProxyManager imp return true; } - - @Override - public ConsoleProxyVO get(long id) { - return _proxyDao.findById(id); - } } diff --git a/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java b/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java index 436a14ae988..dd6306506fb 100644 --- a/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java +++ b/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java @@ -36,7 +36,6 @@ import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; -import com.cloud.agent.api.MigrateCommand; import com.cloud.alert.AlertManager; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.dc.DataCenterVO; @@ -46,9 +45,9 @@ import com.cloud.dc.dao.HostPodDao; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InsufficientServerCapacityException; import com.cloud.exception.OperationTimedoutException; import com.cloud.exception.ResourceUnavailableException; -import com.cloud.exception.StorageUnavailableException; import com.cloud.ha.HaWorkVO.WorkType; import com.cloud.ha.dao.HighAvailabilityDao; import com.cloud.host.Host; @@ -272,7 +271,7 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager { public void scheduleRestart(VMInstanceVO vm, final boolean investigate) { Long hostId = vm.getHostId(); VirtualMachineGuru mgr = findManager(vm.getType()); - vm = mgr.get(vm.getId()); + vm = mgr.findById(vm.getId()); if (!investigate) { if (s_logger.isDebugEnabled()) { s_logger.debug("VM does not require investigation so I'm marking it as Stopped: " + vm.toString()); @@ -334,7 +333,7 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager { return null; } - VMInstanceVO vm = mgr.get(vmId); + VMInstanceVO vm = mgr.findById(vmId); if (vm == null) { s_logger.info("Unable to find vm: " + vmId); return null; @@ -422,7 +421,7 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager { + hostDesc, "Virtual Machine " + vm.getName() + " (id: " + vm.getId() + ") running on host [" + hostDesc + "] stopped unexpectedly."); - vm = mgr.get(vm.getId()); + vm = mgr.findById(vm.getId()); if (!_forceHA && !vm.isHaEnabled()) { if (s_logger.isDebugEnabled()) { @@ -453,7 +452,7 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager { if (s_logger.isDebugEnabled()) { s_logger.debug("Rescheduling VM " + vm.toString() + " to try again in " + _restartRetryInterval); } - vm = mgr.get(vm.getId()); + vm = mgr.findById(vm.getId()); work.setUpdateTime(vm.getUpdated()); work.setPreviousState(vm.getState()); return (System.currentTimeMillis() >> 10) + _restartRetryInterval; @@ -540,13 +539,13 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager { // to ensure there's cleanup. if (serverState == State.Running ) { // Our records showed that it should be running so let's restart it. - vm = info.mgr.get(vm.getId()); + vm = info.mgr.findById(vm.getId()); scheduleRestart(vm, false); command = info.mgr.cleanup(vm, agentName); } else if (serverState == State.Stopping) { if (fullSync) { s_logger.debug("VM is in stopping state on full sync. Updating the status to stopped"); - vm = info.mgr.get(vm.getId()); + vm = info.mgr.findById(vm.getId()); info.mgr.completeStopCommand(vm); command = info.mgr.cleanup(vm, agentName); } else { @@ -563,13 +562,13 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager { if (serverState == State.Starting) { if (fullSync) { s_logger.debug("VM state is starting on full sync so updating it to running"); - vm = info.mgr.get(vm.getId()); + vm = info.mgr.findById(vm.getId()); info.mgr.completeStartCommand(vm); } } else if (serverState == State.Stopping) { if (fullSync) { s_logger.debug("VM state is in stopping on fullsync so resend stop."); - vm = info.mgr.get(vm.getId()); + vm = info.mgr.findById(vm.getId()); info.mgr.completeStopCommand(vm); command = info.mgr.cleanup(vm, agentName); } else { @@ -577,7 +576,7 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager { } } else if (serverState == State.Destroyed || serverState == State.Stopped || serverState == State.Expunging) { s_logger.debug("VM state is in stopped so stopping it on the agent"); - vm = info.mgr.get(vm.getId()); + vm = info.mgr.findById(vm.getId()); command = info.mgr.cleanup(vm, agentName); } else { _itMgr.stateTransitTo(vm, VirtualMachine.Event.AgentReportRunning, vm.getHostId()); @@ -619,7 +618,7 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager { assert info.mgr != null : "How can the manager be null for " + vm.getType(); - VMInstanceVO vmCasted = info.mgr.get(vm.getId()); + VMInstanceVO vmCasted = info.mgr.findById(vm.getId()); final Command command = compareState(vmCasted, info, true); if (command != null) { commands.add(command); @@ -666,7 +665,7 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager { for (final Map.Entry entry : states.entrySet()) { final AgentVmInfo info = entry.getValue(); - final VMInstanceVO vm = info.mgr.get(entry.getKey()); + final VMInstanceVO vm = info.mgr.findById(entry.getKey()); Command command = null; if (vm != null && vm.getHostId() != null && vm.getHostId() == hostId) { @@ -685,136 +684,151 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager { } public Long migrate(final HaWorkVO work) { - final long vmId = work.getInstanceId(); - - final VirtualMachineGuru mgr = findManager(work.getType()); - - VMInstanceVO vm = mgr.get(vmId); - if (vm == null || vm.getRemoved() != null) { - s_logger.debug("Unable to find the vm " + vmId); - return null; - } - - s_logger.info("Migrating vm: " + vm.toString()); - if (vm.getHostId() == null || vm.getHostId() != work.getHostId()) { - s_logger.info("VM is not longer running on the current hostId"); - return null; - } - - short alertType = AlertManager.ALERT_TYPE_USERVM_MIGRATE; - if (VirtualMachine.Type.DomainRouter.equals(vm.getType())) { - alertType = AlertManager.ALERT_TYPE_DOMAIN_ROUTER_MIGRATE; - } else if (VirtualMachine.Type.ConsoleProxy.equals(vm.getType())) { - alertType = AlertManager.ALERT_TYPE_CONSOLE_PROXY_MIGRATE; - } - - HostVO fromHost = _hostDao.findById(vm.getHostId()); - String fromHostName = ((fromHost == null) ? "unknown" : fromHost.getName()); - HostVO toHost = null; - if (work.getStep() == Step.Scheduled) { - if (vm.getState() != State.Running) { - s_logger.info("VM's state is not ready for migration. " + vm.toString() + " State is " + vm.getState().toString()); - return (System.currentTimeMillis() >> 10) + _migrateRetryInterval; - } - - DataCenterVO dcVO = _dcDao.findById(fromHost.getDataCenterId()); - HostPodVO podVO = _podDao.findById(fromHost.getPodId()); - - try { - toHost = mgr.prepareForMigration(vm); - if (toHost == null) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Unable to find a host for migrating vm " + vmId); - } - _alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodId(), "Unable to migrate vm " + vm.getName() + " from host " + fromHostName + " in zone " + dcVO.getName() + " and pod " + podVO.getName(), "Unable to find a suitable host"); - } - } catch(final InsufficientCapacityException e) { - s_logger.warn("Unable to mgirate due to insufficient capacity " + vm.toString()); - _alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodId(), "Unable to migrate vm " + vm.getName() + " from host " + fromHostName + " in zone " + dcVO.getName() + " and pod " + podVO.getName(), "Insufficient capacity"); - } catch(final StorageUnavailableException e) { - s_logger.warn("Storage is unavailable: " + vm.toString()); - _alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodId(), "Unable to migrate vm " + vm.getName() + " from host " + fromHostName + " in zone " + dcVO.getName() + " and pod " + podVO.getName(), "Storage is gone."); - } - - if (toHost == null) { - _agentMgr.maintenanceFailed(vm.getHostId()); - return null; - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Migrating from " + work.getHostId() + " to " + toHost.getId()); - } - work.setStep(Step.Migrating); - work.setHostId(toHost.getId()); - _haDao.update(work.getId(), work); - } - - if (work.getStep() == Step.Migrating) { - vm = mgr.get(vmId); // let's see if anything has changed. - boolean migrated = false; - if (vm == null || vm.getRemoved() != null || vm.getHostId() == null || !_itMgr.stateTransitTo(vm, Event.MigrationRequested, vm.getHostId())) { - s_logger.info("Migration cancelled because state has changed: " + vm.toString()); - } else { - try { - boolean isWindows = _guestOSCategoryDao.findById(_guestOSDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows"); - MigrateCommand cmd = new MigrateCommand(vm.getInstanceName(), toHost.getPrivateIpAddress(), isWindows); - Answer answer = _agentMgr.send(fromHost.getId(), cmd); - if (answer != null && answer.getResult()) { - migrated = true; - _storageMgr.unshare(vm, fromHost); - work.setStep(Step.Investigating); - _haDao.update(work.getId(), work); - } - } catch (final AgentUnavailableException e) { - s_logger.debug("host became unavailable"); - } catch (final OperationTimedoutException e) { - s_logger.debug("operation timed out"); - if (e.isActive()) { - scheduleRestart(vm, true); - } - } - } - - if (!migrated) { - s_logger.info("Migration was unsuccessful. Cleaning up: " + vm.toString()); - - DataCenterVO dcVO = _dcDao.findById(vm.getDataCenterId()); - HostPodVO podVO = _podDao.findById(vm.getPodId()); - _alertMgr.sendAlert(alertType, fromHost.getDataCenterId(), fromHost.getPodId(), "Unable to migrate vm " + vm.getName() + " from host " + fromHost.getName() + " in zone " + dcVO.getName() + " and pod " + podVO.getName(), "Migrate Command failed. Please check logs."); - - _itMgr.stateTransitTo(vm, Event.MigrationFailedOnSource, toHost.getId()); - _agentMgr.maintenanceFailed(vm.getHostId()); - - Command cleanup = mgr.cleanup(vm, null); - _agentMgr.easySend(toHost.getId(), cleanup); - _storageMgr.unshare(vm, toHost); - - return null; - } - } - - if (toHost == null) { - toHost = _hostDao.findById(work.getHostId()); - } - DataCenterVO dcVO = _dcDao.findById(toHost.getDataCenterId()); - HostPodVO podVO = _podDao.findById(toHost.getPodId()); - + long vmId = work.getInstanceId(); + long srcHostId = work.getHostId(); try { - if (!mgr.completeMigration(vm, toHost)) { - _alertMgr.sendAlert(alertType, toHost.getDataCenterId(), toHost.getPodId(), "Unable to migrate " + vmId + " to host " + toHost.getName() + " in zone " + dcVO.getName() + " and pod " + podVO.getName(), "Migration not completed"); - s_logger.warn("Unable to complete migration: " + vm.toString()); - } else { - s_logger.info("Migration is complete: " + vm.toString()); + if (!_itMgr.migrate(work.getType(), vmId, srcHostId)) { + s_logger.warn("Unable to migrate vm from " + srcHostId); + _agentMgr.maintenanceFailed(srcHostId); } return null; - } catch (final AgentUnavailableException e) { - s_logger.warn("Agent is unavailable for " + vm.toString()); - } catch (final OperationTimedoutException e) { - s_logger.warn("Operation timed outfor " + vm.toString()); + } catch (InsufficientServerCapacityException e) { + s_logger.warn("Insufficient capacity for migrating a VM."); + _agentMgr.maintenanceFailed(srcHostId); + return (System.currentTimeMillis() >> 10) + _migrateRetryInterval; } - _itMgr.stateTransitTo(vm, Event.MigrationFailedOnDest, toHost.getId()); - return (System.currentTimeMillis() >> 10) + _migrateRetryInterval; } +// public Long migrate(final HaWorkVO work) { +// final long vmId = work.getInstanceId(); +// +// final VirtualMachineGuru mgr = findManager(work.getType()); +// +// VMInstanceVO vm = mgr.findById(vmId); +// if (vm == null || vm.getRemoved() != null) { +// s_logger.debug("Unable to find the vm " + vmId); +// return null; +// } +// +// s_logger.info("Migrating vm: " + vm.toString()); +// if (vm.getHostId() == null || vm.getHostId() != work.getHostId()) { +// s_logger.info("VM is not longer running on the current hostId"); +// return null; +// } +// +// short alertType = AlertManager.ALERT_TYPE_USERVM_MIGRATE; +// if (VirtualMachine.Type.DomainRouter.equals(vm.getType())) { +// alertType = AlertManager.ALERT_TYPE_DOMAIN_ROUTER_MIGRATE; +// } else if (VirtualMachine.Type.ConsoleProxy.equals(vm.getType())) { +// alertType = AlertManager.ALERT_TYPE_CONSOLE_PROXY_MIGRATE; +// } +// +// HostVO fromHost = _hostDao.findById(vm.getHostId()); +// String fromHostName = ((fromHost == null) ? "unknown" : fromHost.getName()); +// HostVO toHost = null; +// if (work.getStep() == Step.Scheduled) { +// if (vm.getState() != State.Running) { +// s_logger.info("VM's state is not ready for migration. " + vm.toString() + " State is " + vm.getState().toString()); +// return (System.currentTimeMillis() >> 10) + _migrateRetryInterval; +// } +// +// DataCenterVO dcVO = _dcDao.findById(fromHost.getDataCenterId()); +// HostPodVO podVO = _podDao.findById(fromHost.getPodId()); +// +// try { +// toHost = mgr.prepareForMigration(vm); +// if (toHost == null) { +// if (s_logger.isDebugEnabled()) { +// s_logger.debug("Unable to find a host for migrating vm " + vmId); +// } +// _alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodId(), "Unable to migrate vm " + vm.getName() + " from host " + fromHostName + " in zone " + dcVO.getName() + " and pod " + podVO.getName(), "Unable to find a suitable host"); +// } +// } catch(final InsufficientCapacityException e) { +// s_logger.warn("Unable to mgirate due to insufficient capacity " + vm.toString()); +// _alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodId(), "Unable to migrate vm " + vm.getName() + " from host " + fromHostName + " in zone " + dcVO.getName() + " and pod " + podVO.getName(), "Insufficient capacity"); +// } catch(final StorageUnavailableException e) { +// s_logger.warn("Storage is unavailable: " + vm.toString()); +// _alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodId(), "Unable to migrate vm " + vm.getName() + " from host " + fromHostName + " in zone " + dcVO.getName() + " and pod " + podVO.getName(), "Storage is gone."); +// } +// +// if (toHost == null) { +// _agentMgr.maintenanceFailed(vm.getHostId()); +// return null; +// } +// +// if (s_logger.isDebugEnabled()) { +// s_logger.debug("Migrating from " + work.getHostId() + " to " + toHost.getId()); +// } +// work.setStep(Step.Migrating); +// work.setHostId(toHost.getId()); +// _haDao.update(work.getId(), work); +// } +// +// if (work.getStep() == Step.Migrating) { +// vm = mgr.findById(vmId); // let's see if anything has changed. +// boolean migrated = false; +// if (vm == null || vm.getRemoved() != null || vm.getHostId() == null || !_itMgr.stateTransitTo(vm, Event.MigrationRequested, vm.getHostId())) { +// s_logger.info("Migration cancelled because state has changed: " + vm.toString()); +// } else { +// try { +// boolean isWindows = _guestOSCategoryDao.findById(_guestOSDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows"); +// MigrateCommand cmd = new MigrateCommand(vm.getInstanceName(), toHost.getPrivateIpAddress(), isWindows); +// Answer answer = _agentMgr.send(fromHost.getId(), cmd); +// if (answer != null && answer.getResult()) { +// migrated = true; +// _storageMgr.unshare(vm, fromHost); +// work.setStep(Step.Investigating); +// _haDao.update(work.getId(), work); +// } +// } catch (final AgentUnavailableException e) { +// s_logger.debug("host became unavailable"); +// } catch (final OperationTimedoutException e) { +// s_logger.debug("operation timed out"); +// if (e.isActive()) { +// scheduleRestart(vm, true); +// } +// } +// } +// +// if (!migrated) { +// s_logger.info("Migration was unsuccessful. Cleaning up: " + vm.toString()); +// +// DataCenterVO dcVO = _dcDao.findById(vm.getDataCenterId()); +// HostPodVO podVO = _podDao.findById(vm.getPodId()); +// _alertMgr.sendAlert(alertType, fromHost.getDataCenterId(), fromHost.getPodId(), "Unable to migrate vm " + vm.getName() + " from host " + fromHost.getName() + " in zone " + dcVO.getName() + " and pod " + podVO.getName(), "Migrate Command failed. Please check logs."); +// +// _itMgr.stateTransitTo(vm, Event.MigrationFailedOnSource, toHost.getId()); +// _agentMgr.maintenanceFailed(vm.getHostId()); +// +// Command cleanup = mgr.cleanup(vm, null); +// _agentMgr.easySend(toHost.getId(), cleanup); +// _storageMgr.unshare(vm, toHost); +// +// return null; +// } +// } +// +// if (toHost == null) { +// toHost = _hostDao.findById(work.getHostId()); +// } +// DataCenterVO dcVO = _dcDao.findById(toHost.getDataCenterId()); +// HostPodVO podVO = _podDao.findById(toHost.getPodId()); +// +// try { +// if (!mgr.completeMigration(vm, toHost)) { +// _alertMgr.sendAlert(alertType, toHost.getDataCenterId(), toHost.getPodId(), "Unable to migrate " + vmId + " to host " + toHost.getName() + " in zone " + dcVO.getName() + " and pod " + podVO.getName(), "Migration not completed"); +// s_logger.warn("Unable to complete migration: " + vm.toString()); +// } else { +// s_logger.info("Migration is complete: " + vm.toString()); +// } +// return null; +// } catch (final AgentUnavailableException e) { +// s_logger.warn("Agent is unavailable for " + vm.toString()); +// } catch (final OperationTimedoutException e) { +// s_logger.warn("Operation timed outfor " + vm.toString()); +// } +// _itMgr.stateTransitTo(vm, Event.MigrationFailedOnDest, toHost.getId()); +// return (System.currentTimeMillis() >> 10) + _migrateRetryInterval; +// } @Override public void scheduleDestroy(VMInstanceVO vm, long hostId) { @@ -833,7 +847,7 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager { protected Long destroyVM(HaWorkVO work) { final VirtualMachineGuru mgr = findManager(work.getType()); - final VMInstanceVO vm = mgr.get(work.getInstanceId()); + final VMInstanceVO vm = mgr.findById(work.getInstanceId()); s_logger.info("Destroying " + vm.toString()); try { if (vm.getState() != State.Destroyed) { @@ -867,7 +881,7 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager { protected Long stopVM(final HaWorkVO work) { final VirtualMachineGuru mgr = findManager(work.getType()); - final VMInstanceVO vm = mgr.get(work.getInstanceId()); + final VMInstanceVO vm = mgr.findById(work.getInstanceId()); s_logger.info("Stopping " + vm.toString()); try { if (work.getWorkType() == WorkType.Stop) { diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index e01f417daa1..6657a8de302 100644 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -21,7 +21,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.concurrent.Executors; @@ -36,14 +35,10 @@ import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; import com.cloud.agent.AgentManager.OnError; 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.MigrateCommand; import com.cloud.agent.api.ModifySshKeysCommand; import com.cloud.agent.api.NetworkUsageAnswer; import com.cloud.agent.api.NetworkUsageCommand; -import com.cloud.agent.api.PrepareForMigrationCommand; import com.cloud.agent.api.RebootAnswer; import com.cloud.agent.api.StopCommand; import com.cloud.agent.api.check.CheckSshAnswer; @@ -73,8 +68,6 @@ import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.configuration.dao.ResourceLimitDao; import com.cloud.dc.DataCenter; import com.cloud.dc.DataCenter.NetworkType; -import com.cloud.dc.DataCenterVO; -import com.cloud.dc.HostPodVO; import com.cloud.dc.dao.AccountVlanMapDao; import com.cloud.dc.dao.DataCenterDao; import com.cloud.dc.dao.HostPodDao; @@ -95,8 +88,6 @@ import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.exception.StorageUnavailableException; import com.cloud.ha.HighAvailabilityManager; -import com.cloud.host.Host; -import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor; import com.cloud.hypervisor.Hypervisor.HypervisorType; @@ -141,9 +132,7 @@ import com.cloud.offerings.dao.NetworkOfferingDao; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.StorageManager; -import com.cloud.storage.StoragePoolVO; import com.cloud.storage.VMTemplateVO; -import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.GuestOSDao; import com.cloud.storage.dao.StoragePoolDao; import com.cloud.storage.dao.VMTemplateDao; @@ -740,11 +729,6 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } } - @Override - public DomainRouterVO get(final long id) { - return findById(id); - } - @Override public Long convertToId(final String vmName) { if (!VirtualMachineName.isValidRouterName(vmName, _instance)) { @@ -754,105 +738,105 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian return VirtualMachineName.getRouterId(vmName); } - @Override - public HostVO prepareForMigration(final DomainRouterVO router) throws StorageUnavailableException { - final long routerId = router.getId(); - final boolean mirroredVols = router.isMirroredVols(); - final DataCenterVO dc = _dcDao.findById(router.getDataCenterId()); - final HostPodVO pod = _podDao.findById(router.getPodId()); - final ServiceOfferingVO offering = _serviceOfferingDao.findById(router.getServiceOfferingId()); - StoragePoolVO sp = _storageMgr.getStoragePoolForVm(router.getId()); - - final List vols = _volsDao.findCreatedByInstance(routerId); - - final String[] storageIps = new String[2]; - final VolumeVO vol = vols.get(0); - storageIps[0] = vol.getHostIp(); - if (mirroredVols && (vols.size() == 2)) { - storageIps[1] = vols.get(1).getHostIp(); - } - - final PrepareForMigrationCommand cmd = new PrepareForMigrationCommand(router.getInstanceName(), router.getVnet(), storageIps, vols, - mirroredVols); - - HostVO routingHost = null; - final HashSet avoid = new HashSet(); - - final HostVO fromHost = _hostDao.findById(router.getHostId()); - if (fromHost.getHypervisorType() != HypervisorType.KVM && fromHost.getClusterId() == null) { - s_logger.debug("The host is not in a cluster"); - return null; - } - avoid.add(fromHost); - - while ((routingHost = (HostVO) _agentMgr.findHost(Host.Type.Routing, dc, pod, sp, offering, _template, router, fromHost, avoid)) != null) { - avoid.add(routingHost); - if (s_logger.isDebugEnabled()) { - s_logger.debug("Trying to migrate router to host " + routingHost.getName()); - } - - if (!_storageMgr.share(router, vols, routingHost, false)) { - s_logger.warn("Can not share " + vol.getPath() + " to " + router.getName()); - throw new StorageUnavailableException("Can not share " + vol.getPath() + " to " + router.getName(), sp.getId()); - } - - final Answer answer = _agentMgr.easySend(routingHost.getId(), cmd); - if (answer != null && answer.getResult()) { - return routingHost; - } - - _storageMgr.unshare(router, vols, routingHost); - } - - return null; - } - - @Override - public boolean migrate(final DomainRouterVO router, final HostVO host) { - final HostVO fromHost = _hostDao.findById(router.getHostId()); - - if (!_itMgr.stateTransitTo(router, VirtualMachine.Event.MigrationRequested, router.getHostId())) { - s_logger.debug("State for " + router.toString() + " has changed so migration can not take place."); - return false; - } - - final MigrateCommand cmd = new MigrateCommand(router.getInstanceName(), host.getPrivateIpAddress(), false); - final Answer answer = _agentMgr.easySend(fromHost.getId(), cmd); - if (answer == null) { - return false; - } - - final List vols = _volsDao.findCreatedByInstance(router.getId()); - if (vols.size() == 0) { - return true; - } - - _storageMgr.unshare(router, vols, fromHost); - - return true; - } - - @Override - public boolean completeMigration(final DomainRouterVO router, final HostVO host) throws OperationTimedoutException, AgentUnavailableException { - final CheckVirtualMachineCommand cvm = new CheckVirtualMachineCommand(router.getInstanceName()); - final CheckVirtualMachineAnswer answer = (CheckVirtualMachineAnswer) _agentMgr.send(host.getId(), cvm); - if (answer == null || !answer.getResult()) { - s_logger.debug("Unable to complete migration for " + router.getId()); - _itMgr.stateTransitTo(router, VirtualMachine.Event.AgentReportStopped, null); - return false; - } - - final State state = answer.getState(); - if (state == State.Stopped) { - s_logger.warn("Unable to complete migration as we can not detect it on " + host.getId()); - _itMgr.stateTransitTo(router, VirtualMachine.Event.AgentReportStopped, null); - return false; - } - - _itMgr.stateTransitTo(router, VirtualMachine.Event.OperationSucceeded, host.getId()); - - return true; - } +// @Override +// public HostVO prepareForMigration(final DomainRouterVO router) throws StorageUnavailableException { +// final long routerId = router.getId(); +// final boolean mirroredVols = router.isMirroredVols(); +// final DataCenterVO dc = _dcDao.findById(router.getDataCenterId()); +// final HostPodVO pod = _podDao.findById(router.getPodId()); +// final ServiceOfferingVO offering = _serviceOfferingDao.findById(router.getServiceOfferingId()); +// StoragePoolVO sp = _storageMgr.getStoragePoolForVm(router.getId()); +// +// final List vols = _volsDao.findCreatedByInstance(routerId); +// +// final String[] storageIps = new String[2]; +// final VolumeVO vol = vols.get(0); +// storageIps[0] = vol.getHostIp(); +// if (mirroredVols && (vols.size() == 2)) { +// storageIps[1] = vols.get(1).getHostIp(); +// } +// +// final PrepareForMigrationCommand cmd = new PrepareForMigrationCommand(router.getInstanceName(), router.getVnet(), storageIps, vols, +// mirroredVols); +// +// HostVO routingHost = null; +// final HashSet avoid = new HashSet(); +// +// final HostVO fromHost = _hostDao.findById(router.getHostId()); +// if (fromHost.getHypervisorType() != HypervisorType.KVM && fromHost.getClusterId() == null) { +// s_logger.debug("The host is not in a cluster"); +// return null; +// } +// avoid.add(fromHost); +// +// while ((routingHost = (HostVO) _agentMgr.findHost(Host.Type.Routing, dc, pod, sp, offering, _template, router, fromHost, avoid)) != null) { +// avoid.add(routingHost); +// if (s_logger.isDebugEnabled()) { +// s_logger.debug("Trying to migrate router to host " + routingHost.getName()); +// } +// +// if (!_storageMgr.share(router, vols, routingHost, false)) { +// s_logger.warn("Can not share " + vol.getPath() + " to " + router.getName()); +// throw new StorageUnavailableException("Can not share " + vol.getPath() + " to " + router.getName(), sp.getId()); +// } +// +// final Answer answer = _agentMgr.easySend(routingHost.getId(), cmd); +// if (answer != null && answer.getResult()) { +// return routingHost; +// } +// +// _storageMgr.unshare(router, vols, routingHost); +// } +// +// return null; +// } +// +// @Override +// public boolean migrate(final DomainRouterVO router, final HostVO host) { +// final HostVO fromHost = _hostDao.findById(router.getHostId()); +// +// if (!_itMgr.stateTransitTo(router, VirtualMachine.Event.MigrationRequested, router.getHostId())) { +// s_logger.debug("State for " + router.toString() + " has changed so migration can not take place."); +// return false; +// } +// +// final MigrateCommand cmd = new MigrateCommand(router.getInstanceName(), host.getPrivateIpAddress(), false); +// final Answer answer = _agentMgr.easySend(fromHost.getId(), cmd); +// if (answer == null) { +// return false; +// } +// +// final List vols = _volsDao.findCreatedByInstance(router.getId()); +// if (vols.size() == 0) { +// return true; +// } +// +// _storageMgr.unshare(router, vols, fromHost); +// +// return true; +// } +// +// @Override +// public boolean completeMigration(final DomainRouterVO router, final HostVO host) throws OperationTimedoutException, AgentUnavailableException { +// final CheckVirtualMachineCommand cvm = new CheckVirtualMachineCommand(router.getInstanceName()); +// final CheckVirtualMachineAnswer answer = (CheckVirtualMachineAnswer) _agentMgr.send(host.getId(), cvm); +// if (answer == null || !answer.getResult()) { +// s_logger.debug("Unable to complete migration for " + router.getId()); +// _itMgr.stateTransitTo(router, VirtualMachine.Event.AgentReportStopped, null); +// return false; +// } +// +// final State state = answer.getState(); +// if (state == State.Stopped) { +// s_logger.warn("Unable to complete migration as we can not detect it on " + host.getId()); +// _itMgr.stateTransitTo(router, VirtualMachine.Event.AgentReportStopped, null); +// return false; +// } +// +// _itMgr.stateTransitTo(router, VirtualMachine.Event.OperationSucceeded, host.getId()); +// +// return true; +// } protected class RouterCleanupTask implements Runnable { diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java index 258890bc2a3..093ec84da1d 100644 --- a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java +++ b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java @@ -21,7 +21,6 @@ import java.util.ArrayList; import java.util.Date; import java.util.Enumeration; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.concurrent.Executors; @@ -35,11 +34,7 @@ import org.apache.log4j.Logger; 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.MigrateCommand; -import com.cloud.agent.api.PrepareForMigrationCommand; import com.cloud.agent.api.RebootCommand; import com.cloud.agent.api.SecStorageFirewallCfgCommand; import com.cloud.agent.api.SecStorageSetupCommand; @@ -92,7 +87,6 @@ import com.cloud.offerings.NetworkOfferingVO; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.StorageManager; -import com.cloud.storage.StoragePoolVO; import com.cloud.storage.VMTemplateHostVO; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.VMTemplateVO; @@ -1017,11 +1011,6 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V } } - @Override - public SecondaryStorageVmVO get(long id) { - return _secStorageVmDao.findById(id); - } - @Override public Long convertToId(String vmName) { if (!VirtualMachineName.isValidSystemVmName(vmName, _instance, "s")) { @@ -1210,100 +1199,100 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V return true; } - @Override - public boolean migrate(SecondaryStorageVmVO secStorageVm, HostVO host) { - HostVO fromHost = _hostDao.findById(secStorageVm.getId()); - - if (! _itMgr.stateTransitTo(secStorageVm, VirtualMachine.Event.MigrationRequested, secStorageVm.getHostId())) { - s_logger.debug("State for " + secStorageVm.toString() + " has changed so migration can not take place."); - return false; - } - - MigrateCommand cmd = new MigrateCommand(secStorageVm.getInstanceName(), host.getPrivateIpAddress(), false); - Answer answer = _agentMgr.easySend(fromHost.getId(), cmd); - if (answer == null || !answer.getResult()) { - return false; - } - - _storageMgr.unshare(secStorageVm, fromHost); - - return true; - } - - @Override - public boolean completeMigration(SecondaryStorageVmVO secStorageVm, HostVO host) - throws AgentUnavailableException, OperationTimedoutException { - CheckVirtualMachineCommand cvm = new CheckVirtualMachineCommand(secStorageVm.getInstanceName()); - CheckVirtualMachineAnswer answer = (CheckVirtualMachineAnswer) _agentMgr.send(host.getId(), cvm); - if (!answer.getResult()) { - s_logger.debug("Unable to complete migration for " + secStorageVm.getId()); - _itMgr.stateTransitTo(secStorageVm, VirtualMachine.Event.AgentReportStopped, null); - return false; - } - - State state = answer.getState(); - if (state == State.Stopped) { - s_logger.warn("Unable to complete migration as we can not detect it on " + host.getId()); - _itMgr.stateTransitTo(secStorageVm, VirtualMachine.Event.AgentReportStopped, null); - return false; - } - - _itMgr.stateTransitTo(secStorageVm, VirtualMachine.Event.OperationSucceeded, host.getId()); - return true; - } - - @Override - public HostVO prepareForMigration(SecondaryStorageVmVO secStorageVm) throws StorageUnavailableException { - - VMTemplateVO template = _templateDao.findById(secStorageVm.getTemplateId()); - long routerId = secStorageVm.getId(); - boolean mirroredVols = secStorageVm.isMirroredVols(); - DataCenterVO dc = _dcDao.findById(secStorageVm.getDataCenterId()); - HostPodVO pod = _podDao.findById(secStorageVm.getPodId()); - StoragePoolVO sp = _storageMgr.getStoragePoolForVm(secStorageVm.getId()); - - List vols = _volsDao.findCreatedByInstance(routerId); - - String[] storageIps = new String[2]; - VolumeVO vol = vols.get(0); - storageIps[0] = vol.getHostIp(); - if (mirroredVols && (vols.size() == 2)) { - storageIps[1] = vols.get(1).getHostIp(); - } - - PrepareForMigrationCommand cmd = new PrepareForMigrationCommand(secStorageVm.getName(), null, storageIps, vols, mirroredVols); - - HostVO routingHost = null; - HashSet avoid = new HashSet(); - - HostVO fromHost = _hostDao.findById(secStorageVm.getHostId()); - if (fromHost.getClusterId() == null) { - s_logger.debug("The host is not in a cluster"); - return null; - } - avoid.add(fromHost); - - while ((routingHost = (HostVO) _agentMgr.findHost(Host.Type.Routing, - dc, pod, sp, _serviceOffering, template, secStorageVm, fromHost, avoid)) != null) { - avoid.add(routingHost); - if (s_logger.isDebugEnabled()) { - s_logger.debug("Trying to migrate router to host " + routingHost.getName()); - } - - if( !_storageMgr.share(secStorageVm, vols, routingHost, false) ) { - s_logger.warn("Can not share " + vol.getPath() + " to " + secStorageVm.getName()); - throw new StorageUnavailableException("Can not share " + vol.getPath() + " to " + secStorageVm.getName(), vol.getPoolId()); - } - - Answer answer = _agentMgr.easySend(routingHost.getId(), cmd); - if (answer != null && answer.getResult()) { - return routingHost; - } - _storageMgr.unshare(secStorageVm, vols, routingHost); - } - - return null; - } +// @Override +// public boolean migrate(SecondaryStorageVmVO secStorageVm, HostVO host) { +// HostVO fromHost = _hostDao.findById(secStorageVm.getId()); +// +// if (! _itMgr.stateTransitTo(secStorageVm, VirtualMachine.Event.MigrationRequested, secStorageVm.getHostId())) { +// s_logger.debug("State for " + secStorageVm.toString() + " has changed so migration can not take place."); +// return false; +// } +// +// MigrateCommand cmd = new MigrateCommand(secStorageVm.getInstanceName(), host.getPrivateIpAddress(), false); +// Answer answer = _agentMgr.easySend(fromHost.getId(), cmd); +// if (answer == null || !answer.getResult()) { +// return false; +// } +// +// _storageMgr.unshare(secStorageVm, fromHost); +// +// return true; +// } +// +// @Override +// public boolean completeMigration(SecondaryStorageVmVO secStorageVm, HostVO host) +// throws AgentUnavailableException, OperationTimedoutException { +// CheckVirtualMachineCommand cvm = new CheckVirtualMachineCommand(secStorageVm.getInstanceName()); +// CheckVirtualMachineAnswer answer = (CheckVirtualMachineAnswer) _agentMgr.send(host.getId(), cvm); +// if (!answer.getResult()) { +// s_logger.debug("Unable to complete migration for " + secStorageVm.getId()); +// _itMgr.stateTransitTo(secStorageVm, VirtualMachine.Event.AgentReportStopped, null); +// return false; +// } +// +// State state = answer.getState(); +// if (state == State.Stopped) { +// s_logger.warn("Unable to complete migration as we can not detect it on " + host.getId()); +// _itMgr.stateTransitTo(secStorageVm, VirtualMachine.Event.AgentReportStopped, null); +// return false; +// } +// +// _itMgr.stateTransitTo(secStorageVm, VirtualMachine.Event.OperationSucceeded, host.getId()); +// return true; +// } +// +// @Override +// public HostVO prepareForMigration(SecondaryStorageVmVO secStorageVm) throws StorageUnavailableException { +// +// VMTemplateVO template = _templateDao.findById(secStorageVm.getTemplateId()); +// long routerId = secStorageVm.getId(); +// boolean mirroredVols = secStorageVm.isMirroredVols(); +// DataCenterVO dc = _dcDao.findById(secStorageVm.getDataCenterId()); +// HostPodVO pod = _podDao.findById(secStorageVm.getPodId()); +// StoragePoolVO sp = _storageMgr.getStoragePoolForVm(secStorageVm.getId()); +// +// List vols = _volsDao.findCreatedByInstance(routerId); +// +// String[] storageIps = new String[2]; +// VolumeVO vol = vols.get(0); +// storageIps[0] = vol.getHostIp(); +// if (mirroredVols && (vols.size() == 2)) { +// storageIps[1] = vols.get(1).getHostIp(); +// } +// +// PrepareForMigrationCommand cmd = new PrepareForMigrationCommand(secStorageVm.getName(), null, storageIps, vols, mirroredVols); +// +// HostVO routingHost = null; +// HashSet avoid = new HashSet(); +// +// HostVO fromHost = _hostDao.findById(secStorageVm.getHostId()); +// if (fromHost.getClusterId() == null) { +// s_logger.debug("The host is not in a cluster"); +// return null; +// } +// avoid.add(fromHost); +// +// while ((routingHost = (HostVO) _agentMgr.findHost(Host.Type.Routing, +// dc, pod, sp, _serviceOffering, template, secStorageVm, fromHost, avoid)) != null) { +// avoid.add(routingHost); +// if (s_logger.isDebugEnabled()) { +// s_logger.debug("Trying to migrate router to host " + routingHost.getName()); +// } +// +// if( !_storageMgr.share(secStorageVm, vols, routingHost, false) ) { +// s_logger.warn("Can not share " + vol.getPath() + " to " + secStorageVm.getName()); +// throw new StorageUnavailableException("Can not share " + vol.getPath() + " to " + secStorageVm.getName(), vol.getPoolId()); +// } +// +// Answer answer = _agentMgr.easySend(routingHost.getId(), cmd); +// if (answer != null && answer.getResult()) { +// return routingHost; +// } +// _storageMgr.unshare(secStorageVm, vols, routingHost); +// } +// +// return null; +// } @Override public void onAgentConnect(Long dcId, StartupCommand cmd){ diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index ac1dd8170aa..9144dce6b46 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -22,7 +22,6 @@ import java.util.Date; import java.util.Enumeration; import java.util.Formatter; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.UUID; @@ -41,15 +40,11 @@ import com.cloud.agent.api.Answer; import com.cloud.agent.api.AttachIsoCommand; import com.cloud.agent.api.AttachVolumeAnswer; import com.cloud.agent.api.AttachVolumeCommand; -import com.cloud.agent.api.CheckVirtualMachineAnswer; -import com.cloud.agent.api.CheckVirtualMachineCommand; import com.cloud.agent.api.Command; import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand; import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand; import com.cloud.agent.api.GetVmStatsAnswer; import com.cloud.agent.api.GetVmStatsCommand; -import com.cloud.agent.api.MigrateCommand; -import com.cloud.agent.api.PrepareForMigrationCommand; import com.cloud.agent.api.RebootAnswer; import com.cloud.agent.api.RebootCommand; import com.cloud.agent.api.SnapshotCommand; @@ -113,7 +108,6 @@ import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.exception.StorageUnavailableException; import com.cloud.ha.HighAvailabilityManager; -import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.dao.DetailsDao; import com.cloud.host.dao.HostDao; @@ -1177,11 +1171,6 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager } } - @Override - public UserVmVO get(long id) { - return getVirtualMachine(id); - } - public String getRandomPrivateTemplateName() { return UUID.randomUUID().toString(); } @@ -1260,82 +1249,82 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager return stopped; } - @Override - public HostVO prepareForMigration(UserVmVO vm) throws StorageUnavailableException { - long vmId = vm.getId(); - boolean mirroredVols = vm.isMirroredVols(); - DataCenterVO dc = _dcDao.findById(vm.getDataCenterId()); - HostPodVO pod = _podDao.findById(vm.getPodId()); - ServiceOfferingVO offering = _offeringDao.findById(vm.getServiceOfferingId()); - VMTemplateVO template = _templateDao.findById(vm.getTemplateId()); - StoragePoolVO sp = _storageMgr.getStoragePoolForVm(vm.getId()); - - List vols = _volsDao.findCreatedByInstance(vmId); - - String [] storageIps = new String[2]; - VolumeVO vol = vols.get(0); - storageIps[0] = vol.getHostIp(); - if (mirroredVols && (vols.size() == 2)) { - storageIps[1] = vols.get(1).getHostIp(); - } - - PrepareForMigrationCommand cmd = new PrepareForMigrationCommand(vm.getInstanceName(), vm.getVnet(), storageIps, vols, mirroredVols); - - HostVO vmHost = null; - HashSet avoid = new HashSet(); - - HostVO fromHost = _hostDao.findById(vm.getHostId()); - if (fromHost.getClusterId() == null) { - s_logger.debug("The host is not in a cluster"); - return null; - } - avoid.add(fromHost); - - while ((vmHost = (HostVO)_agentMgr.findHost(Host.Type.Routing, dc, pod, sp, offering, template, vm, null, avoid)) != null) { - avoid.add(vmHost); - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Trying to migrate router to host " + vmHost.getName()); - } - - _storageMgr.share(vm, vols, vmHost, false); - - Answer answer = _agentMgr.easySend(vmHost.getId(), cmd); - if (answer != null && answer.getResult()) { - return vmHost; - } - - _storageMgr.unshare(vm, vols, vmHost); - - } - - return null; - } - - @Override - public boolean migrate(UserVmVO vm, HostVO host) throws AgentUnavailableException, OperationTimedoutException { - HostVO fromHost = _hostDao.findById(vm.getHostId()); - - if (!_itMgr.stateTransitTo(vm, VirtualMachine.Event.MigrationRequested, vm.getHostId())) { - s_logger.debug("State for " + vm.toString() + " has changed so migration can not take place."); - return false; - } - boolean isWindows = _guestOSCategoryDao.findById(_guestOSDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows"); - MigrateCommand cmd = new MigrateCommand(vm.getInstanceName(), host.getPrivateIpAddress(), isWindows); - Answer answer = _agentMgr.send(fromHost.getId(), cmd); - if (answer == null) { - return false; - } - - List vols = _volsDao.findCreatedByInstance(vm.getId()); - if (vols.size() == 0) { - return true; - } - - _storageMgr.unshare(vm, vols, fromHost); - - return true; - } +// @Override +// public HostVO prepareForMigration(UserVmVO vm) throws StorageUnavailableException { +// long vmId = vm.getId(); +// boolean mirroredVols = vm.isMirroredVols(); +// DataCenterVO dc = _dcDao.findById(vm.getDataCenterId()); +// HostPodVO pod = _podDao.findById(vm.getPodId()); +// ServiceOfferingVO offering = _offeringDao.findById(vm.getServiceOfferingId()); +// VMTemplateVO template = _templateDao.findById(vm.getTemplateId()); +// StoragePoolVO sp = _storageMgr.getStoragePoolForVm(vm.getId()); +// +// List vols = _volsDao.findCreatedByInstance(vmId); +// +// String [] storageIps = new String[2]; +// VolumeVO vol = vols.get(0); +// storageIps[0] = vol.getHostIp(); +// if (mirroredVols && (vols.size() == 2)) { +// storageIps[1] = vols.get(1).getHostIp(); +// } +// +// PrepareForMigrationCommand cmd = new PrepareForMigrationCommand(vm.getInstanceName(), vm.getVnet(), storageIps, vols, mirroredVols); +// +// HostVO vmHost = null; +// HashSet avoid = new HashSet(); +// +// HostVO fromHost = _hostDao.findById(vm.getHostId()); +// if (fromHost.getClusterId() == null) { +// s_logger.debug("The host is not in a cluster"); +// return null; +// } +// avoid.add(fromHost); +// +// while ((vmHost = (HostVO)_agentMgr.findHost(Host.Type.Routing, dc, pod, sp, offering, template, vm, null, avoid)) != null) { +// avoid.add(vmHost); +// +// if (s_logger.isDebugEnabled()) { +// s_logger.debug("Trying to migrate router to host " + vmHost.getName()); +// } +// +// _storageMgr.share(vm, vols, vmHost, false); +// +// Answer answer = _agentMgr.easySend(vmHost.getId(), cmd); +// if (answer != null && answer.getResult()) { +// return vmHost; +// } +// +// _storageMgr.unshare(vm, vols, vmHost); +// +// } +// +// return null; +// } +// +// @Override +// public boolean migrate(UserVmVO vm, HostVO host) throws AgentUnavailableException, OperationTimedoutException { +// HostVO fromHost = _hostDao.findById(vm.getHostId()); +// +// if (!_itMgr.stateTransitTo(vm, VirtualMachine.Event.MigrationRequested, vm.getHostId())) { +// s_logger.debug("State for " + vm.toString() + " has changed so migration can not take place."); +// return false; +// } +// boolean isWindows = _guestOSCategoryDao.findById(_guestOSDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows"); +// MigrateCommand cmd = new MigrateCommand(vm.getInstanceName(), host.getPrivateIpAddress(), isWindows); +// Answer answer = _agentMgr.send(fromHost.getId(), cmd); +// if (answer == null) { +// return false; +// } +// +// List vols = _volsDao.findCreatedByInstance(vm.getId()); +// if (vols.size() == 0) { +// return true; +// } +// +// _storageMgr.unshare(vm, vols, fromHost); +// +// return true; +// } @Override public boolean expunge(UserVmVO vm, long callerUserId, Account caller) { @@ -1413,39 +1402,39 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager // _storageMgr.destroy(null, destroyedVolumes); } - @Override @DB - public boolean completeMigration(UserVmVO vm, HostVO host) throws AgentUnavailableException, OperationTimedoutException { - CheckVirtualMachineCommand cvm = new CheckVirtualMachineCommand(vm.getInstanceName()); - CheckVirtualMachineAnswer answer = (CheckVirtualMachineAnswer)_agentMgr.send(host.getId(), cvm); - if (!answer.getResult()) { - s_logger.debug("Unable to complete migration for " + vm.toString()); - _itMgr.stateTransitTo(vm, VirtualMachine.Event.AgentReportStopped, null); - return false; - } - - State state = answer.getState(); - if (state == State.Stopped) { - s_logger.warn("Unable to complete migration as we can not detect it on " + host.toString()); - _itMgr.stateTransitTo(vm, VirtualMachine.Event.AgentReportStopped, null); - return false; - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Marking port " + answer.getVncPort() + " on " + host.getId()); - } - - Transaction txn = Transaction.currentTxn(); - try { - txn.start(); - _itMgr.stateTransitTo(vm, VirtualMachine.Event.OperationSucceeded, host.getId()); - txn.commit(); - _networkGroupMgr.handleVmStateTransition(vm, State.Running); - return true; - } catch(Exception e) { - s_logger.warn("Exception during completion of migration process " + vm.toString()); - return false; - } - } +// @Override @DB +// public boolean completeMigration(UserVmVO vm, HostVO host) throws AgentUnavailableException, OperationTimedoutException { +// CheckVirtualMachineCommand cvm = new CheckVirtualMachineCommand(vm.getInstanceName()); +// CheckVirtualMachineAnswer answer = (CheckVirtualMachineAnswer)_agentMgr.send(host.getId(), cvm); +// if (!answer.getResult()) { +// s_logger.debug("Unable to complete migration for " + vm.toString()); +// _itMgr.stateTransitTo(vm, VirtualMachine.Event.AgentReportStopped, null); +// return false; +// } +// +// State state = answer.getState(); +// if (state == State.Stopped) { +// s_logger.warn("Unable to complete migration as we can not detect it on " + host.toString()); +// _itMgr.stateTransitTo(vm, VirtualMachine.Event.AgentReportStopped, null); +// return false; +// } +// +// if (s_logger.isDebugEnabled()) { +// s_logger.debug("Marking port " + answer.getVncPort() + " on " + host.getId()); +// } +// +// Transaction txn = Transaction.currentTxn(); +// try { +// txn.start(); +// _itMgr.stateTransitTo(vm, VirtualMachine.Event.OperationSucceeded, host.getId()); +// txn.commit(); +// _networkGroupMgr.handleVmStateTransition(vm, State.Running); +// return true; +// } catch(Exception e) { +// s_logger.warn("Exception during completion of migration process " + vm.toString()); +// return false; +// } +// } @Override public void deletePrivateTemplateRecord(Long templateId){ @@ -2240,8 +2229,9 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager if (cmd.getSSHKeyPairName() != null && !cmd.getSSHKeyPairName().equals("")) { Account account = UserContext.current().getCaller(); SSHKeyPair pair = _sshKeyPairDao.findByName(account.getAccountId(), account.getDomainId(), cmd.getSSHKeyPairName()); - if (pair == null) - throw new InvalidParameterValueException("A key pair with name '" + cmd.getSSHKeyPairName() + "' was not found."); + if (pair == null) { + throw new InvalidParameterValueException("A key pair with name '" + cmd.getSSHKeyPairName() + "' was not found."); + } sshPublicKey = pair.getPublicKey(); } @@ -2323,8 +2313,9 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager UserVmVO vm = new UserVmVO(id, instanceName, cmd.getDisplayName(), template.getId(), hypervisorType, template.getGuestOSId(), offering.getOfferHA(), domainId, owner.getId(), offering.getId(), userData, hostName); - if (sshPublicKey != null) - vm.setDetail("SSH.PublicKey", sshPublicKey); + if (sshPublicKey != null) { + vm.setDetail("SSH.PublicKey", sshPublicKey); + } if (_itMgr.allocate(vm, template, offering, rootDiskOffering, dataDiskOfferings, networks, null, plan, cmd.getHypervisor(), owner) == null) { return null; @@ -2378,8 +2369,9 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager String sshPublicKey = vm.getDetail("SSH.PublicKey"); if (sshPublicKey != null && !sshPublicKey.equals("") && password != null && !password.equals("saved_password") ) { String encryptedPasswd = RSAHelper.encryptWithSSHPublicKey(sshPublicKey, password); - if (encryptedPasswd == null) - throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Error encrypting password"); + if (encryptedPasswd == null) { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Error encrypting password"); + } vm.setDetail("Encrypted.Password", encryptedPasswd); _vmDao.saveDetails(vm); diff --git a/server/src/com/cloud/vm/VirtualMachineGuru.java b/server/src/com/cloud/vm/VirtualMachineGuru.java index 4a037f479d1..b8ce7d5ab4d 100644 --- a/server/src/com/cloud/vm/VirtualMachineGuru.java +++ b/server/src/com/cloud/vm/VirtualMachineGuru.java @@ -24,10 +24,8 @@ import com.cloud.deploy.DeployDestination; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; -import com.cloud.exception.OperationTimedoutException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.exception.StorageUnavailableException; -import com.cloud.host.HostVO; import com.cloud.utils.exception.ExecutionException; /** @@ -77,14 +75,6 @@ public interface VirtualMachineGuru { */ Long convertToId(String vmName); - /** - * Retrieves the vm based on the id given. - * - * @param id id of the vm. - * @return VMInstanceVO - */ - T get(long id); - /** * Complete the start command. HA calls this when it determines that * a vm was starting but the state was not complete. @@ -138,12 +128,12 @@ public interface VirtualMachineGuru { * @param vm vm to migrate. * @return HostVO if a host is found. */ - HostVO prepareForMigration(T vm) throws InsufficientCapacityException, StorageUnavailableException; +// HostVO prepareForMigration(T vm) throws InsufficientCapacityException, StorageUnavailableException; - /** - * Migrate the vm. - */ - boolean migrate(T vm, HostVO host) throws AgentUnavailableException, OperationTimedoutException; - - boolean completeMigration(T vm, HostVO host) throws AgentUnavailableException, OperationTimedoutException; +// /** +// * Migrate the vm. +// */ +// boolean migrate(T vm, HostVO host) throws AgentUnavailableException, OperationTimedoutException; +// +// boolean completeMigration(T vm, HostVO host) throws AgentUnavailableException, OperationTimedoutException; } diff --git a/server/src/com/cloud/vm/VirtualMachineManager.java b/server/src/com/cloud/vm/VirtualMachineManager.java index c3020e1311b..7150604714d 100644 --- a/server/src/com/cloud/vm/VirtualMachineManager.java +++ b/server/src/com/cloud/vm/VirtualMachineManager.java @@ -20,10 +20,12 @@ package com.cloud.vm; import java.util.List; import java.util.Map; +import com.cloud.deploy.DeployDestination; import com.cloud.deploy.DeploymentPlan; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InsufficientServerCapacityException; import com.cloud.exception.OperationTimedoutException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.hypervisor.Hypervisor.HypervisorType; @@ -89,4 +91,8 @@ public interface VirtualMachineManager extends Manager { boolean remove(T vm, User caller, Account account); boolean destroy(T vm, User caller, Account account) throws AgentUnavailableException, OperationTimedoutException, ConcurrentOperationException; + + boolean migrate(VirtualMachine.Type type, long vmid, long hostId) throws InsufficientServerCapacityException; + + T migrate(T vm, long srcHostId, DeployDestination dest) throws ResourceUnavailableException; } diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java index 23e53a520d4..caf0df7e2a2 100644 --- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -34,12 +34,20 @@ import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; import com.cloud.agent.AgentManager.OnError; 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.MigrateAnswer; +import com.cloud.agent.api.MigrateCommand; +import com.cloud.agent.api.PrepareForMigrationAnswer; +import com.cloud.agent.api.PrepareForMigrationCommand; import com.cloud.agent.api.StartAnswer; import com.cloud.agent.api.StartCommand; import com.cloud.agent.api.StopAnswer; import com.cloud.agent.api.StopCommand; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.agent.manager.Commands; +import com.cloud.alert.AlertManager; import com.cloud.cluster.ClusterManager; import com.cloud.configuration.Config; import com.cloud.configuration.dao.ConfigurationDao; @@ -59,6 +67,8 @@ import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.InsufficientServerCapacityException; import com.cloud.exception.OperationTimedoutException; import com.cloud.exception.ResourceUnavailableException; +import com.cloud.host.Host; +import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.hypervisor.HypervisorGuru; import com.cloud.network.NetworkManager; @@ -71,6 +81,8 @@ import com.cloud.storage.StorageManager; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.Volume; import com.cloud.storage.Volume.VolumeType; +import com.cloud.storage.dao.GuestOSCategoryDao; +import com.cloud.storage.dao.GuestOSDao; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.user.Account; import com.cloud.user.AccountManager; @@ -123,6 +135,10 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager { @Inject protected UsageEventDao _usageEventDao; @Inject protected NicDao _nicsDao; @Inject protected AccountManager _accountMgr; + @Inject protected HostDao _hostDao; + @Inject protected AlertManager _alertMgr; + @Inject protected GuestOSCategoryDao _guestOsCategoryDao; + @Inject protected GuestOSDao _guestOsDao; @Inject(adapter=DeploymentPlanner.class) protected Adapters _planners; @@ -349,6 +365,8 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager { //Clean up volumes based on the vm's instance id _storageMgr.cleanupVolumes(vm.getId()); + _vmDao.remove(vm.getId()); + if (s_logger.isDebugEnabled()) { s_logger.debug("Expunged " + vm); } @@ -744,12 +762,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager { private void setStateMachine() { _stateMachine = new StateMachine2(); - _stateMachine.addTransition(null, VirtualMachine.Event.CreateRequested, State.Creating); - _stateMachine.addTransition(State.Creating, VirtualMachine.Event.OperationSucceeded, State.Stopped); - _stateMachine.addTransition(State.Creating, VirtualMachine.Event.OperationFailed, State.Error); _stateMachine.addTransition(State.Stopped, VirtualMachine.Event.StartRequested, State.Starting); - _stateMachine.addTransition(State.Error, VirtualMachine.Event.DestroyRequested, State.Expunging); - _stateMachine.addTransition(State.Error, VirtualMachine.Event.ExpungeOperation, State.Expunging); _stateMachine.addTransition(State.Stopped, VirtualMachine.Event.DestroyRequested, State.Destroyed); _stateMachine.addTransition(State.Stopped, VirtualMachine.Event.StopRequested, State.Stopped); _stateMachine.addTransition(State.Stopped, VirtualMachine.Event.AgentReportStopped, State.Stopped); @@ -764,7 +777,6 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager { _stateMachine.addTransition(State.Starting, VirtualMachine.Event.AgentReportShutdowned, State.Stopped); _stateMachine.addTransition(State.Destroyed, VirtualMachine.Event.RecoveryRequested, State.Stopped); _stateMachine.addTransition(State.Destroyed, VirtualMachine.Event.ExpungeOperation, State.Expunging); - _stateMachine.addTransition(State.Creating, VirtualMachine.Event.MigrationRequested, State.Destroyed); _stateMachine.addTransition(State.Running, VirtualMachine.Event.MigrationRequested, State.Migrating); _stateMachine.addTransition(State.Running, VirtualMachine.Event.AgentReportRunning, State.Running); _stateMachine.addTransition(State.Running, VirtualMachine.Event.AgentReportStopped, State.Stopped); @@ -777,8 +789,8 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager { _stateMachine.addTransition(State.Migrating, VirtualMachine.Event.MigrationFailedOnDest, State.Running); _stateMachine.addTransition(State.Migrating, VirtualMachine.Event.AgentReportRunning, State.Running); _stateMachine.addTransition(State.Migrating, VirtualMachine.Event.AgentReportStopped, State.Stopped); + _stateMachine.addTransition(State.Migrating, VirtualMachine.Event.AgentReportShutdowned, State.Stopped); _stateMachine.addTransition(State.Stopping, VirtualMachine.Event.OperationSucceeded, State.Stopped); - _stateMachine.addTransition(State.Migrating, VirtualMachine.Event.AgentReportShutdowned, State.Stopped); _stateMachine.addTransition(State.Stopping, VirtualMachine.Event.OperationFailed, State.Running); _stateMachine.addTransition(State.Stopping, VirtualMachine.Event.AgentReportRunning, State.Running); _stateMachine.addTransition(State.Stopping, VirtualMachine.Event.AgentReportStopped, State.Stopped); @@ -786,6 +798,8 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager { _stateMachine.addTransition(State.Stopping, VirtualMachine.Event.AgentReportShutdowned, State.Stopped); _stateMachine.addTransition(State.Expunging, VirtualMachine.Event.OperationFailed, State.Expunging); _stateMachine.addTransition(State.Expunging, VirtualMachine.Event.ExpungeOperation, State.Expunging); + _stateMachine.addTransition(State.Error, VirtualMachine.Event.DestroyRequested, State.Expunging); + _stateMachine.addTransition(State.Error, VirtualMachine.Event.ExpungeOperation, State.Expunging); _stateMachine.registerListeners(_stateListner); } @@ -850,6 +864,156 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager { return true; } + @Override + public T migrate(T vm, long srcHostId, DeployDestination dest) throws ResourceUnavailableException { + s_logger.info("Migrating " + vm + " to " + dest); + + long dstHostId = dest.getHost().getId(); + Host fromHost = _hostDao.findById(srcHostId); + if (fromHost == null) { + s_logger.info("Unable to find the host to migrate from: " + srcHostId); + return null; + } + VirtualMachineGuru vmGuru = getVmGuru(vm); + + vm = vmGuru.findById(vm.getId()); + if (vm == null || vm.getRemoved() != null) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Unable to find the vm " + vm); + } + return null; + } + + short alertType = AlertManager.ALERT_TYPE_USERVM_MIGRATE; + if (VirtualMachine.Type.DomainRouter.equals(vm.getType())) { + alertType = AlertManager.ALERT_TYPE_DOMAIN_ROUTER_MIGRATE; + } else if (VirtualMachine.Type.ConsoleProxy.equals(vm.getType())) { + alertType = AlertManager.ALERT_TYPE_CONSOLE_PROXY_MIGRATE; + } + + VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm); + HypervisorGuru hvGuru = _hvGurus.get(vm.getHypervisorType()); + VirtualMachineTO to = hvGuru.implement(profile); + PrepareForMigrationCommand pfmc = new PrepareForMigrationCommand(to); + + PrepareForMigrationAnswer pfma; + try { + pfma = (PrepareForMigrationAnswer)_agentMgr.send(dstHostId, pfmc); + } catch (OperationTimedoutException e1) { + throw new AgentUnavailableException("Operation timed out", dstHostId); + } + if (!pfma.getResult()) { + throw new AgentUnavailableException(pfma.getDetails(), dstHostId); + } + + boolean migrated = false; + try { + vm.setLastHostId(srcHostId); + if (vm == null || vm.getRemoved() != null || vm.getHostId() == null || vm.getHostId() != srcHostId || !stateTransitTo(vm, Event.MigrationRequested, dstHostId)) { + s_logger.info("Migration cancelled because state has changed: " + vm); + return null; + } + + boolean isWindows = _guestOsCategoryDao.findById(_guestOsDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows"); + MigrateCommand mc = new MigrateCommand(vm.getInstanceName(), dest.getHost().getPrivateIpAddress(), isWindows); + MigrateAnswer ma = (MigrateAnswer)_agentMgr.send(vm.getHostId(), mc); + if (!ma.getResult()) { + return null; + } + + CheckVirtualMachineCommand cvm = new CheckVirtualMachineCommand(vm.getInstanceName()); + CheckVirtualMachineAnswer answer = (CheckVirtualMachineAnswer)_agentMgr.send(dstHostId, cvm); + if (!answer.getResult()) { + s_logger.debug("Unable to complete migration for " + vm.toString()); + stateTransitTo(vm, VirtualMachine.Event.AgentReportStopped, null); + return null; + } + + State state = answer.getState(); + if (state == State.Stopped) { + s_logger.warn("Unable to complete migration as we can not detect it on " + dest.getHost()); + stateTransitTo(vm, VirtualMachine.Event.AgentReportStopped, null); + return null; + } + + // FIXME: _networkGroupMgr.handleVmStateTransition(vm, State.Running); + stateTransitTo(vm, VirtualMachine.Event.OperationSucceeded, dstHostId); + migrated = true; + return vm; + } catch (final OperationTimedoutException e) { + s_logger.debug("operation timed out"); + if (e.isActive()) { + // FIXME: scheduleRestart(vm, true); + } + throw new AgentUnavailableException("Operation timed out: ", dstHostId); + } finally { + if (!migrated) { + s_logger.info("Migration was unsuccessful. Cleaning up: " + vm.toString()); + + _alertMgr.sendAlert(alertType, fromHost.getDataCenterId(), fromHost.getPodId(), "Unable to migrate vm " + vm.getName() + " from host " + fromHost.getName() + " in zone " + dest.getDataCenter().getName() + " and pod " + dest.getPod().getName(), "Migrate Command failed. Please check logs."); + + stateTransitTo(vm, Event.MigrationFailedOnSource, srcHostId); + + Command cleanup = vmGuru.cleanup(vm, null); + _agentMgr.easySend(dstHostId, cleanup); + } + } + } + + @Override + public boolean migrate(VirtualMachine.Type vmType, long vmId, long srcHostId) throws InsufficientServerCapacityException { + VirtualMachineGuru vmGuru = _vmGurus.get(vmType); + VMInstanceVO vm = vmGuru.findById(vmId); + if (vm == null) { + s_logger.debug("Unable to find a VM for " + vmId); + return true; + } + + VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm); + + Long hostId = vm.getHostId(); + if (hostId == null) { + s_logger.debug("Unable to migrate because the VM doesn't have a host id: " + vm); + } + + Host host = _hostDao.findById(hostId); + + DataCenterDeployment plan = new DataCenterDeployment(host.getDataCenterId(), host.getPodId(), host.getClusterId(), null); + ExcludeList excludes = new ExcludeList(); + excludes.addHost(hostId); + + DeployDestination dest = null; + while (true) { + for (DeploymentPlanner planner : _planners) { + dest = planner.plan(profile, plan, excludes); + if (dest != null) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Planner " + planner + " found " + dest + " for migrating to."); + } + break; + } + if (s_logger.isDebugEnabled()) { + s_logger.debug("Planner " + planner + " was unable to find anything."); + } + } + + if (dest == null) { + throw new InsufficientServerCapacityException("Unable to find a server to migrate to.", host.getClusterId()); + } + + excludes.addHost(dest.getHost().getId()); + + try { + vm = migrate(vm, srcHostId, dest); + } catch (ResourceUnavailableException e) { + s_logger.debug("Unable to migrate to unavailable " + dest); + } + if (vm != null) { + return true; + } + } + } + protected class CleanupTask implements Runnable { @Override