Updated Branches:
  refs/heads/master a3cec3802 -> 449b5daa7

VMware changes related to managed storage


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/449b5daa
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/449b5daa
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/449b5daa

Branch: refs/heads/master
Commit: 449b5daa70f033128f014942e9dcbacd15b09181
Parents: a3cec38
Author: Mike Tutkowski <[email protected]>
Authored: Thu Oct 31 08:27:30 2013 -0600
Committer: Mike Tutkowski <[email protected]>
Committed: Thu Oct 31 08:30:50 2013 -0600

----------------------------------------------------------------------
 .../vmware/manager/VmwareHostService.java       |  3 +
 .../vmware/resource/VmwareResource.java         | 69 +++++++++++++++++---
 .../VmwareSecondaryStorageResourceHandler.java  |  4 ++
 .../resource/VmwareStorageProcessor.java        | 51 ++++++++++++++-
 .../SolidFirePrimaryDataStoreLifeCycle.java     |  2 +
 .../com/cloud/storage/VolumeApiServiceImpl.java | 15 ++++-
 .../hypervisor/vmware/mo/VirtualMachineMO.java  | 16 ++++-
 7 files changed, 147 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/449b5daa/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareHostService.java
----------------------------------------------------------------------
diff --git 
a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareHostService.java
 
b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareHostService.java
index d0147d1..d5a2284 100644
--- 
a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareHostService.java
+++ 
b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareHostService.java
@@ -16,6 +16,8 @@
 // under the License.
 package com.cloud.hypervisor.vmware.manager;
 
+import java.util.List;
+
 import com.cloud.agent.api.Command;
 import com.cloud.hypervisor.vmware.mo.DatastoreMO;
 import com.cloud.hypervisor.vmware.mo.VmwareHypervisorHost;
@@ -33,4 +35,5 @@ public interface VmwareHostService {
             String iqn, String initiatorChapName, String initiatorChapSecret, 
String mutualChapName, String mutualChapSecret) throws Exception;
     void createVmdk(Command cmd, DatastoreMO dsMo, String volumeDatastorePath, 
Long volumeSize) throws Exception;
     void handleDatastoreAndVmdkDetach(String iqn, String storageHost, int 
storagePort) throws Exception;
+    void removeManagedTargetsFromCluster(List<String> managedIqns) throws 
Exception;
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/449b5daa/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
----------------------------------------------------------------------
diff --git 
a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
 
b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
index 6d3d34a..a205fb6 100755
--- 
a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
+++ 
b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
@@ -2985,7 +2985,9 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
        
         VolumeObjectTO volumeTO = (VolumeObjectTO)vol.getData();
         PrimaryDataStoreTO primaryStore = 
(PrimaryDataStoreTO)volumeTO.getDataStore();
-        
+        Map<String, String> details = vol.getDetails();
+        boolean isManaged = details != null && 
Boolean.parseBoolean(details.get(DiskTO.MANAGED));
+
         Pair<ManagedObjectReference, DatastoreMO> volumeDsDetails = 
dataStoresDetails.get(primaryStore.getUuid());
         if(volumeDsDetails == null)
                throw new Exception("Primary datastore " + 
primaryStore.getUuid() + " is not mounted on host.");
@@ -2997,17 +2999,25 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
                String disks[] = diskInfo.getDiskChain();
                for(int i = 0; i < disks.length; i++) {
                        DatastoreFile file = new DatastoreFile(disks[i]);
-                       if(file.getDir() != null && file.getDir().isEmpty()) {
+                       if (!isManaged && file.getDir() != null && 
file.getDir().isEmpty()) {
                                s_logger.info("Perform run-time datastore 
folder upgrade. sync " + disks[i] + " to VM folder");
                                disks[i] = 
VmwareStorageLayoutHelper.syncVolumeToVmDefaultFolder(
                            dcMo, vmMo.getName(), dsMo, file.getFileBaseName());
                        }
                }
                return disks;
-       } 
-        
-        String datastoreDiskPath = 
VmwareStorageLayoutHelper.syncVolumeToVmDefaultFolder(
-               dcMo, vmMo.getName(), dsMo, volumeTO.getPath());
+       }
+
+        final String datastoreDiskPath;
+
+        if (isManaged) {
+            datastoreDiskPath = dsMo.getDatastorePath(dsMo.getName() + 
".vmdk");
+        }
+        else {
+            datastoreDiskPath = 
VmwareStorageLayoutHelper.syncVolumeToVmDefaultFolder(
+                dcMo, vmMo.getName(), dsMo, volumeTO.getPath());
+        }
+
         if(!dsMo.fileExists(datastoreDiskPath)) {
                s_logger.warn("Volume " + volumeTO.getId() + " does not seem to 
exist on datastore, out of sync? path: " + datastoreDiskPath);
        }
@@ -3223,7 +3233,10 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
        if(diskInfoBuilder != null) {
                VolumeObjectTO volume = (VolumeObjectTO)vol.getData();
 
-               VirtualMachineDiskInfo diskInfo = 
diskInfoBuilder.getDiskInfoByBackingFileBaseName(volume.getPath());
+            Map<String, String> details = vol.getDetails();
+            boolean isManaged = details != null && 
Boolean.parseBoolean(details.get(DiskTO.MANAGED));
+
+               VirtualMachineDiskInfo diskInfo = 
diskInfoBuilder.getDiskInfoByBackingFileBaseName(isManaged ? new 
DatastoreFile(volume.getPath()).getFileBaseName() : volume.getPath());
                if(diskInfo != null) {
                        s_logger.info("Found existing disk info from volume 
path: " + volume.getPath());
                        return diskInfo;
@@ -3421,7 +3434,16 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
                 PrimaryDataStoreTO primaryStore = 
(PrimaryDataStoreTO)volumeTO.getDataStore();
                 String poolUuid = primaryStore.getUuid();
                 if(poolMors.get(poolUuid) == null) {
-                    ManagedObjectReference morDataStore = 
HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, 
poolUuid);
+                    boolean isManaged = false;
+                    String iScsiName = null;
+                    Map<String, String> details = vol.getDetails();
+
+                    if (details != null) {
+                        isManaged = 
Boolean.parseBoolean(details.get(DiskTO.MANAGED));
+                        iScsiName = details.get(DiskTO.IQN);
+                    }
+
+                    ManagedObjectReference morDataStore = 
HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, 
isManaged ? VmwareResource.getDatastoreName(iScsiName) : poolUuid);
                     if (morDataStore == null) {
                         String msg = "Failed to get the mounted datastore for 
the volume's pool " + poolUuid;
                         s_logger.error(msg);
@@ -4534,7 +4556,7 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
                 String volumeDatastorePath = String.format("[%s] %s.vmdk", 
dsMo.getName(), dsMo.getName());
 
                 if (!dsMo.fileExists(volumeDatastorePath)) {
-                    createVmdk(cmd, dsMo, 
VmwareResource.getDatastoreName(cmd.get_iScsiName()), cmd.getVolumeSize());
+                    createVmdk(cmd, dsMo, volumeDatastorePath, 
cmd.getVolumeSize());
                 }
             }
             else {
@@ -4592,6 +4614,35 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
         }
     }
 
+    @Override
+    public void removeManagedTargetsFromCluster(List<String> iqns) throws 
Exception {
+        List<HostInternetScsiHbaStaticTarget> lstManagedTargets = new 
ArrayList<HostInternetScsiHbaStaticTarget>();
+
+        VmwareContext context = getServiceContext();
+        VmwareHypervisorHost hyperHost = getHyperHost(context);
+        ManagedObjectReference morCluster = hyperHost.getHyperHostCluster();
+        ClusterMO cluster = new ClusterMO(context, morCluster);
+        List<Pair<ManagedObjectReference, String>> lstHosts = 
cluster.getClusterHosts();
+        HostMO host = new HostMO(context, lstHosts.get(0).first());
+        HostStorageSystemMO hostStorageSystem = host.getHostStorageSystemMO();
+
+        for (HostHostBusAdapter hba : 
hostStorageSystem.getStorageDeviceInfo().getHostBusAdapter()) {
+            if (hba instanceof HostInternetScsiHba) {
+                List<HostInternetScsiHbaStaticTarget> lstTargets = 
((HostInternetScsiHba)hba).getConfiguredStaticTarget();
+
+                if (lstTargets != null) {
+                    for (HostInternetScsiHbaStaticTarget target : lstTargets) {
+                        if (iqns.contains(target.getIScsiName())) {
+                            lstManagedTargets.add(target);
+                        }
+                    }
+                }
+            }
+        }
+
+        addRemoveInternetScsiTargetsToAllHosts(false, lstManagedTargets, 
lstHosts);
+    }
+
     private void addRemoveInternetScsiTargetsToAllHosts(final boolean add, 
final List<HostInternetScsiHbaStaticTarget> lstTargets,
             final List<Pair<ManagedObjectReference, String>> lstHosts) throws 
Exception {
         VmwareContext context = getServiceContext();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/449b5daa/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java
----------------------------------------------------------------------
diff --git 
a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java
 
b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java
index c84813f..81f7bd9 100644
--- 
a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java
+++ 
b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java
@@ -360,4 +360,8 @@ public class VmwareSecondaryStorageResourceHandler 
implements SecondaryStorageRe
     public void handleDatastoreAndVmdkDetach(String iqn, String storageHost, 
int storagePort) throws Exception {
         throw new OperationNotSupportedException();
     }
+
+    public void removeManagedTargetsFromCluster(List<String> managedIqns) 
throws Exception {
+        throw new OperationNotSupportedException();
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/449b5daa/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java
----------------------------------------------------------------------
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 71ba4e9..70a8769 100644
--- 
a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java
+++ 
b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java
@@ -23,6 +23,7 @@ import java.io.OutputStreamWriter;
 import java.net.URI;
 import java.rmi.RemoteException;
 import java.util.HashMap;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
@@ -79,6 +80,7 @@ import com.cloud.vm.VirtualMachine.State;
 import com.google.gson.Gson;
 import com.vmware.vim25.ManagedObjectReference;
 import com.vmware.vim25.VirtualDisk;
+import com.vmware.vim25.VirtualDiskFlatVer2BackingInfo;
 
 public class VmwareStorageProcessor implements StorageProcessor {
     private static final Logger s_logger = 
Logger.getLogger(VmwareStorageProcessor.class);
@@ -1194,7 +1196,7 @@ public class VmwareStorageProcessor implements 
StorageProcessor {
                 Map<String, String> details = disk.getDetails();
 
                 morDs = hostService.getVmfsDatastore(hyperHost, 
VmwareResource.getDatastoreName(iScsiName), storageHost, storagePort,
-                            VmwareResource.trimIqn(iScsiName),  
details.get(DiskTO.CHAP_INITIATOR_USERNAME), 
details.get(DiskTO.CHAP_INITIATOR_SECRET),
+                            VmwareResource.trimIqn(iScsiName), 
details.get(DiskTO.CHAP_INITIATOR_USERNAME), 
details.get(DiskTO.CHAP_INITIATOR_SECRET),
                             details.get(DiskTO.CHAP_TARGET_USERNAME), 
details.get(DiskTO.CHAP_TARGET_SECRET));
 
                 DatastoreMO dsMo = new 
DatastoreMO(hostService.getServiceContext(null), morDs);
@@ -1202,7 +1204,7 @@ public class VmwareStorageProcessor implements 
StorageProcessor {
                 String volumeDatastorePath = String.format("[%s] %s.vmdk", 
dsMo.getName(), dsMo.getName());
 
                 if (!dsMo.fileExists(volumeDatastorePath)) {
-                    hostService.createVmdk(cmd, dsMo, 
VmwareResource.getDatastoreName(iScsiName), volumeTO.getSize());
+                    hostService.createVmdk(cmd, dsMo, volumeDatastorePath, 
volumeTO.getSize());
                 }
             }
             else {
@@ -1498,6 +1500,14 @@ public class VmwareStorageProcessor implements 
StorageProcessor {
                             vmMo.safePowerOff(_shutdown_waitMs);
                         }
 
+                        // call this before calling detachAllDisksExcept
+                        // when expunging a VM, we need to see if any of its 
disks are serviced by managed storage
+                        // if there is one or more disk serviced by managed 
storage, remove the iSCSI connection(s)
+                        // don't remove the iSCSI connection(s) until the 
supported disk(s) is/are removed from the VM
+                        // (removeManagedTargetsFromCluster should be called 
after detachAllDisksExcept and vm.destroy)
+                        List<VirtualDisk> virtualDisks = 
vmMo.getVirtualDisks();
+                        List<String> managedIqns = 
getManagedIqnsFromVirtualDisks(virtualDisks);
+
                         List<String> detachedDisks = 
vmMo.detachAllDisksExcept(vol.getPath(), diskInfo != null ? 
diskInfo.getDiskDeviceBusName() : null);
                         VmwareStorageLayoutHelper.moveVolumeToRootFolder(new 
DatacenterMO(context, morDc), detachedDisks);
 
@@ -1505,6 +1515,9 @@ public class VmwareStorageProcessor implements 
StorageProcessor {
                         // vmMo.tearDownDevices(new Class<?>[] { 
VirtualDisk.class, VirtualEthernetCard.class });
                         vmMo.destroy();
 
+                        // 
this.hostService.handleDatastoreAndVmdkDetach(iScsiName, storageHost, 
storagePort);
+                        
this.hostService.removeManagedTargetsFromCluster(managedIqns);
+
                         for (NetworkDetails netDetails : networks) {
                             if (netDetails.getGCTag() != null && 
netDetails.getGCTag().equalsIgnoreCase("true")) {
                                 if (netDetails.getVMMorsOnNetwork() == null || 
netDetails.getVMMorsOnNetwork().length == 1) {
@@ -1555,6 +1568,40 @@ public class VmwareStorageProcessor implements 
StorageProcessor {
         }
     }
 
+    private List<String> getManagedIqnsFromVirtualDisks(List<VirtualDisk> 
virtualDisks) {
+        List<String> managedIqns = new ArrayList<String>();
+
+        if (virtualDisks != null) {
+            for (VirtualDisk virtualDisk : virtualDisks) {
+                if (virtualDisk.getBacking() instanceof 
VirtualDiskFlatVer2BackingInfo) {
+                    VirtualDiskFlatVer2BackingInfo backingInfo = 
(VirtualDiskFlatVer2BackingInfo)virtualDisk.getBacking();
+                    String path = backingInfo.getFileName();
+
+                    path = new DatastoreFile(path).getFileBaseName();
+
+                    String search = "-";
+                    int index = path.indexOf(search);
+
+                    if (index > -1) {
+                        path = path.substring(index + search.length());
+
+                        index = path.lastIndexOf(search);
+
+                        if (index > -1) {
+                            path = path.substring(0, index);
+
+                            if (path.startsWith("iqn.")) {
+                                managedIqns.add(path);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        return managedIqns;
+    }
+
     private Long restoreVolumeFromSecStorage(VmwareHypervisorHost hyperHost, 
DatastoreMO primaryDsMo, String newVolumeName,
             String secStorageUrl, String secStorageDir, String backupName) 
throws Exception {
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/449b5daa/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/lifecycle/SolidFirePrimaryDataStoreLifeCycle.java
----------------------------------------------------------------------
diff --git 
a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/lifecycle/SolidFirePrimaryDataStoreLifeCycle.java
 
b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/lifecycle/SolidFirePrimaryDataStoreLifeCycle.java
index 120a357..be43e1c 100644
--- 
a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/lifecycle/SolidFirePrimaryDataStoreLifeCycle.java
+++ 
b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/lifecycle/SolidFirePrimaryDataStoreLifeCycle.java
@@ -317,10 +317,12 @@ public class SolidFirePrimaryDataStoreLifeCycle 
implements PrimaryDataStoreLifeC
        dataStoreHelper.attachZone(dataStore);
        
         List<HostVO> xenServerHosts = 
_resourceMgr.listAllUpAndEnabledHostsInOneZoneByHypervisor(HypervisorType.XenServer,
 scope.getScopeId());
+        List<HostVO> vmWareServerHosts = 
_resourceMgr.listAllUpAndEnabledHostsInOneZoneByHypervisor(HypervisorType.VMware,
 scope.getScopeId());
         List<HostVO> kvmHosts = 
_resourceMgr.listAllUpAndEnabledHostsInOneZoneByHypervisor(HypervisorType.KVM, 
scope.getScopeId());
         List<HostVO> hosts = new ArrayList<HostVO>();
 
         hosts.addAll(xenServerHosts);
+        hosts.addAll(vmWareServerHosts);
         hosts.addAll(kvmHosts);
 
         for (HostVO host : hosts) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/449b5daa/server/src/com/cloud/storage/VolumeApiServiceImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java 
b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
index d445381..28df219 100644
--- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java
+++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
@@ -1233,6 +1233,19 @@ public class VolumeApiServiceImpl extends ManagerBase 
implements VolumeApiServic
 
         String errorMsg = "Failed to detach volume: " + volume.getName() + " 
from VM: " + vm.getHostName();
         boolean sendCommand = (vm.getState() == State.Running);
+
+        Long hostId = vm.getHostId();
+
+        if (hostId == null) {
+            hostId = vm.getLastHostId();
+
+            HostVO host = _hostDao.findById(hostId);
+
+            if (host != null && host.getHypervisorType() == 
HypervisorType.VMware) {
+                sendCommand = true;
+            }
+        }
+
         Answer answer = null;
 
         if (sendCommand) {
@@ -1251,7 +1264,7 @@ public class VolumeApiServiceImpl extends ManagerBase 
implements VolumeApiServic
             cmd.set_iScsiName(volume.get_iScsiName());
 
             try {
-                answer = _agentMgr.send(vm.getHostId(), cmd);
+                answer = _agentMgr.send(hostId, cmd);
             } catch (Exception e) {
                 throw new CloudRuntimeException(errorMsg + " due to: " + 
e.getMessage());
             }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/449b5daa/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java
----------------------------------------------------------------------
diff --git 
a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java 
b/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java
index a9536cf..784c031 100644
--- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java
+++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java
@@ -1985,7 +1985,21 @@ public class VirtualMachineMO extends BaseMO {
                }
                throw new Exception("Unable to find device controller");
        }
-       
+
+    public List<VirtualDisk> getVirtualDisks() throws Exception {
+        List<VirtualDisk> virtualDisks = new ArrayList<VirtualDisk>();
+
+        List<VirtualDevice> devices = 
(List<VirtualDevice>)_context.getVimClient().getDynamicProperty(_mor, 
"config.hardware.device");
+
+        for (VirtualDevice device : devices) {
+            if (device instanceof VirtualDisk) {
+                virtualDisks.add((VirtualDisk)device);
+            }
+        }
+
+        return virtualDisks;
+    }
+
        public List<String> detachAllDisksExcept(String vmdkBaseName, String 
deviceBusName) throws Exception {
                List<VirtualDevice> devices = 
(List<VirtualDevice>)_context.getVimClient().getDynamicProperty(_mor, 
"config.hardware.device");
 

Reply via email to