diff --git a/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java b/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java index dd6306506fb..ac4827aa967 100644 --- a/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java +++ b/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java @@ -687,7 +687,7 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager { long vmId = work.getInstanceId(); long srcHostId = work.getHostId(); try { - if (!_itMgr.migrate(work.getType(), vmId, srcHostId)) { + if (!_itMgr.migrateAway(work.getType(), vmId, srcHostId)) { s_logger.warn("Unable to migrate vm from " + srcHostId); _agentMgr.maintenanceFailed(srcHostId); } diff --git a/server/src/com/cloud/network/NetworkManager.java b/server/src/com/cloud/network/NetworkManager.java index 37b1562a2be..465268360be 100644 --- a/server/src/com/cloud/network/NetworkManager.java +++ b/server/src/com/cloud/network/NetworkManager.java @@ -144,4 +144,6 @@ public interface NetworkManager extends NetworkService { Pair implementNetwork(long networkId, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException; List listNetworksUsedByVm(long vmId, boolean isSystem); + void prepareNicForMigration(VirtualMachineProfile vm, DeployDestination dest); + } diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index 6b0717b8c55..5654399d410 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -1097,6 +1097,19 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag _networksDao.changeActiveNicsBy(network.getId(), 1); } } + + @Override + public void prepareNicForMigration(VirtualMachineProfile vm, DeployDestination dest) { + List nics = _nicDao.listBy(vm.getId()); + for (NicVO nic : nics) { + Network network = _networksDao.findById(nic.getNetworkId()); + + NicProfile profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri()); + + vm.addNic(profile); + } + } + @Override public void release(VirtualMachineProfile vmProfile, boolean forced) { diff --git a/server/src/com/cloud/storage/StorageManager.java b/server/src/com/cloud/storage/StorageManager.java index a269546790d..bfc975c8dd7 100755 --- a/server/src/com/cloud/storage/StorageManager.java +++ b/server/src/com/cloud/storage/StorageManager.java @@ -275,4 +275,6 @@ public interface StorageManager extends Manager { void release(VirtualMachineProfile profile); void cleanupVolumes(long vmId) throws ConcurrentOperationException; + + void prepareForMigration(VirtualMachineProfile vm, DeployDestination dest); } diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index b19cdbf969e..c888e0e3722 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -2558,6 +2558,19 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag return null; } + @Override + public void prepareForMigration(VirtualMachineProfile vm, DeployDestination dest) { + List vols = _volsDao.findUsableVolumesForInstance(vm.getId()); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Preparing " + vols.size() + " volumes for " + vm); + } + + for (VolumeVO vol : vols) { + StoragePool pool = _storagePoolDao.findById(vol.getPoolId()); + vm.addDisk(new VolumeTO(vol, pool)); + } + } + @Override public void prepare(VirtualMachineProfile vm, DeployDestination dest) throws StorageUnavailableException, InsufficientStorageCapacityException { List vols = _volsDao.findUsableVolumesForInstance(vm.getId()); diff --git a/server/src/com/cloud/vm/VirtualMachineManager.java b/server/src/com/cloud/vm/VirtualMachineManager.java index 7150604714d..172e61c58ed 100644 --- a/server/src/com/cloud/vm/VirtualMachineManager.java +++ b/server/src/com/cloud/vm/VirtualMachineManager.java @@ -92,7 +92,7 @@ public interface VirtualMachineManager extends Manager { boolean destroy(T vm, User caller, Account account) throws AgentUnavailableException, OperationTimedoutException, ConcurrentOperationException; - boolean migrate(VirtualMachine.Type type, long vmid, long hostId) throws InsufficientServerCapacityException; + boolean migrateAway(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 1677ece0a80..3e72a1c0104 100644 --- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -84,6 +84,7 @@ 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.storage.dao.VolumeDao; import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.User; @@ -139,6 +140,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager { @Inject protected AlertManager _alertMgr; @Inject protected GuestOSCategoryDao _guestOsCategoryDao; @Inject protected GuestOSDao _guestOsDao; + @Inject protected VolumeDao _volsDao; @Inject(adapter=DeploymentPlanner.class) protected Adapters _planners; @@ -364,8 +366,6 @@ 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); } @@ -863,6 +863,7 @@ 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); @@ -890,7 +891,10 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager { alertType = AlertManager.ALERT_TYPE_CONSOLE_PROXY_MIGRATE; } - VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm); + VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm); + _networkMgr.prepareNicForMigration(profile, dest); + _storageMgr.prepareForMigration(profile, dest); + HypervisorGuru hvGuru = _hvGurus.get(vm.getHypervisorType()); VirtualMachineTO to = hvGuru.implement(profile); PrepareForMigrationCommand pfmc = new PrepareForMigrationCommand(to); @@ -915,7 +919,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager { 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); + MigrateAnswer ma = (MigrateAnswer)_agentMgr.send(vm.getLastHostId(), mc); if (!ma.getResult()) { return null; } @@ -960,7 +964,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager { } @Override - public boolean migrate(VirtualMachine.Type vmType, long vmId, long srcHostId) throws InsufficientServerCapacityException { + public boolean migrateAway(VirtualMachine.Type vmType, long vmId, long srcHostId) throws InsufficientServerCapacityException { VirtualMachineGuru vmGuru = _vmGurus.get(vmType); VMInstanceVO vm = vmGuru.findById(vmId); if (vm == null) { @@ -973,6 +977,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager { Long hostId = vm.getHostId(); if (hostId == null) { s_logger.debug("Unable to migrate because the VM doesn't have a host id: " + vm); + return true; } Host host = _hostDao.findById(hostId);