From f1e3e83bbf763860dd33a18c36618b4714bf0dbe Mon Sep 17 00:00:00 2001 From: Likitha Shetty Date: Mon, 8 Sep 2014 15:42:48 +0530 Subject: [PATCH] BUG-ID: CLOUDSTACK-7653. VM's are not getting deleted from hypervisor after deleting from UI when using zone wide primary storage. While expunging a volume, CS chooses the endpoint to perform delete operation by selecting any host that has the storage containing the volume mounted on it. Instead, if the volume to be deleted is attached to a VM, the endpoint chosen by CCP should be the host that contains the VM. --- .../engine/subsystem/api/storage/StorageAction.java | 3 ++- .../storage/endpoint/DefaultEndPointSelector.java | 11 +++++++++++ .../storage/resource/VmwareStorageProcessor.java | 9 ++++++--- .../driver/CloudStackPrimaryDataStoreDriverImpl.java | 7 ++++++- 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageAction.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageAction.java index 965df84c2dd..dc93f4aa41e 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageAction.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageAction.java @@ -22,5 +22,6 @@ public enum StorageAction { TAKESNAPSHOT, BACKUPSNAPSHOT, DELETESNAPSHOT, - MIGRATEVOLUME + MIGRATEVOLUME, + DELETEVOLUME } diff --git a/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java b/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java index 0a867f6291b..c620c40d981 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java +++ b/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java @@ -302,6 +302,17 @@ public class DefaultEndPointSelector implements EndPointSelector { return getEndPointFromHostId(hostId); } } + } else if (action == StorageAction.DELETEVOLUME) { + VolumeInfo volume = (VolumeInfo)object; + if (volume.getHypervisorType() == Hypervisor.HypervisorType.VMware) { + VirtualMachine vm = volume.getAttachedVM(); + if (vm != null) { + Long hostId = vm.getHostId() != null ? vm.getHostId() : vm.getLastHostId(); + if (hostId != null) { + return getEndPointFromHostId(hostId); + } + } + } } return select(object); } diff --git a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java index b225e39bc0e..8a4ba08c8d9 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java +++ b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java @@ -1594,9 +1594,12 @@ public class VmwareStorageProcessor implements StorageProcessor { String vmName = vol.getVmName(); if (vmName != null) { - // Find VM under the datacenter and not just the cluster. - DatacenterMO dcMo = new DatacenterMO(context, morDc); - VirtualMachineMO vmMo = dcMo.findVm(vmName); + VirtualMachineMO vmMo = clusterMo.findVmOnHyperHost(vmName); + if (vmMo == null) { + // Volume might be on a zone-wide storage pool, look for VM in datacenter + DatacenterMO dcMo = new DatacenterMO(context, morDc); + vmMo = dcMo.findVm(vmName); + } if (vmMo != null) { if (s_logger.isInfoEnabled()) { s_logger.info("Destroy root volume and VM itself. vmName " + vmName); diff --git a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java index d58c0b15d11..bcc06b021b6 100644 --- a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java +++ b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java @@ -204,7 +204,12 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri CommandResult result = new CommandResult(); try { - EndPoint ep = epSelector.select(data); + EndPoint ep = null; + if (data.getType() == DataObjectType.VOLUME) { + ep = epSelector.select(data, StorageAction.DELETEVOLUME); + } else { + ep = epSelector.select(data); + } if (ep == null) { String errMsg = "No remote endpoint to send DeleteCommand, check if host or ssvm is down?"; s_logger.error(errMsg);