diff --git a/engine/api/src/org/apache/cloudstack/engine/orchestration/service/VolumeOrchestrationService.java b/engine/api/src/org/apache/cloudstack/engine/orchestration/service/VolumeOrchestrationService.java index 5ac6bb17e33..92daf8809e5 100644 --- a/engine/api/src/org/apache/cloudstack/engine/orchestration/service/VolumeOrchestrationService.java +++ b/engine/api/src/org/apache/cloudstack/engine/orchestration/service/VolumeOrchestrationService.java @@ -93,6 +93,8 @@ public interface VolumeOrchestrationService { void cleanupVolumes(long vmId) throws ConcurrentOperationException; + void disconnectVolumesFromHost(long vmId, long hostId); + void migrateVolumes(VirtualMachine vm, VirtualMachineTO vmTo, Host srcHost, Host destHost, Map volumeToPool); boolean storageMigration(VirtualMachineProfile vm, StoragePool destPool) throws StorageUnavailableException; diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreDriver.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreDriver.java index 36091e0dae8..aad94944fa6 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreDriver.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreDriver.java @@ -18,8 +18,6 @@ */ package org.apache.cloudstack.engine.subsystem.api.storage; -import java.util.List; - import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.storage.command.CommandResult; diff --git a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java index 824dc0b3022..1fec68e46a9 100755 --- a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -483,30 +483,32 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac List volumeExpungeCommands = hvGuru.finalizeExpungeVolumes(vm); - if (volumeExpungeCommands != null) { - Long hostId = vm.getHostId() != null ? vm.getHostId() : vm.getLastHostId(); + Long hostId = vm.getHostId() != null ? vm.getHostId() : vm.getLastHostId(); - if (hostId != null) { - Commands cmds = new Commands(Command.OnError.Stop); + if (volumeExpungeCommands != null && hostId != null) { + Commands cmds = new Commands(Command.OnError.Stop); - for (Command volumeExpungeCommand : volumeExpungeCommands) { - cmds.addCommand(volumeExpungeCommand); - } + for (Command volumeExpungeCommand : volumeExpungeCommands) { + cmds.addCommand(volumeExpungeCommand); + } - _agentMgr.send(hostId, cmds); + _agentMgr.send(hostId, cmds); - if (!cmds.isSuccessful()) { - for (Answer answer : cmds.getAnswers()) { - if (!answer.getResult()) { - s_logger.warn("Failed to expunge vm due to: " + answer.getDetails()); + if (!cmds.isSuccessful()) { + for (Answer answer : cmds.getAnswers()) { + if (!answer.getResult()) { + s_logger.warn("Failed to expunge vm due to: " + answer.getDetails()); - throw new CloudRuntimeException("Unable to expunge " + vm + " due to " + answer.getDetails()); - } + throw new CloudRuntimeException("Unable to expunge " + vm + " due to " + answer.getDetails()); } } } } + if (hostId != null) { + volumeMgr.disconnectVolumesFromHost(vm.getId(), hostId); + } + // Clean up volumes based on the vm's instance id volumeMgr.cleanupVolumes(vm.getId()); @@ -518,7 +520,6 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac // send hypervisor-dependent commands before removing List finalizeExpungeCommands = hvGuru.finalizeExpunge(vm); if (finalizeExpungeCommands != null && finalizeExpungeCommands.size() > 0) { - Long hostId = vm.getHostId() != null ? vm.getHostId() : vm.getLastHostId(); if (hostId != null) { Commands cmds = new Commands(Command.OnError.Stop); for (Command command : finalizeExpungeCommands) { 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 7a5dbf6b195..ff6ace8872b 100644 --- a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java +++ b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java @@ -71,6 +71,8 @@ import com.cloud.exception.InsufficientStorageCapacityException; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.StorageUnavailableException; import com.cloud.host.Host; +import com.cloud.host.HostVO; +import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.offering.DiskOffering; import com.cloud.offering.ServiceOffering; @@ -140,6 +142,8 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati SnapshotDataFactory snapshotFactory; @Inject ConfigDepot _configDepot; + @Inject + HostDao _hostDao; private final StateMachine2 _volStateMachine; protected List _storagePoolAllocators; @@ -839,6 +843,22 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati } } + @Override + public void disconnectVolumesFromHost(long vmId, long hostId) { + HostVO host = _hostDao.findById(hostId); + + List volumesForVm = _volsDao.findByInstance(vmId); + + if (volumesForVm != null) { + for (VolumeVO volumeForVm : volumesForVm) { + VolumeInfo volumeInfo = volFactory.getVolume(volumeForVm.getId()); + DataStore dataStore = dataStoreMgr.getDataStore(volumeForVm.getPoolId(), DataStoreRole.Primary); + + volService.disconnectVolumeFromHost(volumeInfo, host, dataStore); + } + } + } + @Override @DB public Volume migrateVolume(Volume volume, StoragePool destPool) throws StorageUnavailableException {