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 80e4f9de49d..f79d3361b97 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 @@ -94,6 +94,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/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java index cabaa52f0bb..628528a33c4 100755 --- a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -489,30 +489,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()); @@ -524,7 +526,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 f094fb248a9..0d6d7185320 100644 --- a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java +++ b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java @@ -73,6 +73,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; @@ -143,6 +145,8 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati @Inject ConfigDepot _configDepot; @Inject + HostDao _hostDao; + @Inject SnapshotService _snapshotSrv; private final StateMachine2 _volStateMachine; @@ -787,6 +791,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 {