You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by mt...@apache.org on 2013/07/21 01:45:01 UTC

git commit: updated refs/heads/master to 98dd501

Updated Branches:
  refs/heads/master 6689e83d7 -> 98dd501a8


Changes related to Review Board comments

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

Branch: refs/heads/master
Commit: 98dd501a818beef03b5f593822b525348874f007
Parents: 6689e83
Author: Mike Tutkowski <mi...@solidfire.com>
Authored: Sat Jul 20 17:44:23 2013 -0600
Committer: Mike Tutkowski <mi...@solidfire.com>
Committed: Sat Jul 20 17:44:23 2013 -0600

----------------------------------------------------------------------
 .../vmware/resource/VmwareResource.java         | 233 ++++++++++---------
 1 file changed, 128 insertions(+), 105 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/98dd501a/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 bbac725..c7f487e 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
@@ -28,6 +28,7 @@ import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
+import java.util.concurrent.*;
 import java.util.Date;
 import java.util.GregorianCalendar;
 import java.util.HashMap;
@@ -4073,33 +4074,6 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
         return str.replace('/', '-');
     }
 
-    // This methd can be used to determine if the datastore is active yet.
-    // When an iSCSI target is created on a host and that target already contains
-    // the metadata that represents a datastore, the datastore shows up within
-    // vCenter as existent, but not necessarily active.
-    // Call this method and pass in the datastore's name to wait, if necessary,
-    // for the datastore to become active.
-    private boolean datastoreFileExists(DatastoreMO dsMo, String volumeDatastorePath) {
-        for (int i = 0; i < 10; i++) {
-            try {
-                return dsMo.fileExists(volumeDatastorePath);
-            }
-            catch (Exception e) {
-                if (!e.getMessage().contains("is not accessible")) {
-                    break;
-                }
-            }
-
-            try {
-                Thread.sleep(5000);
-            }
-            catch (Exception e) {
-            }
-        }
-
-        return false;
-    }
-
     @Override
     public ManagedObjectReference handleDatastoreAndVmdkAttach(Command cmd, String iqn, String storageHost, int storagePort,
             String initiatorUsername, String initiatorPassword, String targetUsername, String targetPassword) throws Exception {
@@ -4115,7 +4089,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
 
         String volumeDatastorePath = String.format("[%s] %s.vmdk", dsMo.getName(), dsMo.getName());
 
-        if (!datastoreFileExists(dsMo, volumeDatastorePath)) {
+        if (!dsMo.fileExists(volumeDatastorePath)) {
             String dummyVmName = getWorkerName(context, cmd, 0);
 
             VirtualMachineMO vmMo = prepareVolumeHostDummyVm(hyperHost, dsMo, dummyVmName);
@@ -4209,49 +4183,80 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
         }
     }
 
-    private ManagedObjectReference createVmfsDatastore(VmwareHypervisorHost hyperHost, String datastoreName, String storageIpAddress,
-            int storagePortNumber, String iqn, String chapName, String chapSecret, String mutualChapName, String mutualChapSecret) throws Exception {
+    private void addRemoveInternetScsiTargetsToAllHosts(final boolean add, final List<HostInternetScsiHbaStaticTarget> lstTargets,
+            final List<Pair<ManagedObjectReference, String>> lstHosts) throws Exception {
         VmwareContext context = getServiceContext();
-        ManagedObjectReference morCluster = hyperHost.getHyperHostCluster();
-        ClusterMO cluster = new ClusterMO(context, morCluster);
-        List<Pair<ManagedObjectReference, String>> lstHosts = cluster.getClusterHosts();
 
-        HostInternetScsiHbaStaticTarget target = new HostInternetScsiHbaStaticTarget();
+        ExecutorService executorService = Executors.newFixedThreadPool(lstHosts.size());
 
-        target.setAddress(storageIpAddress);
-        target.setPort(storagePortNumber);
-        target.setIScsiName(iqn);
+        final List<Exception> exceptions = new ArrayList<Exception>();
 
-        HostInternetScsiHbaAuthenticationProperties auth = new HostInternetScsiHbaAuthenticationProperties();
+        for (Pair<ManagedObjectReference, String> hostPair : lstHosts) {
+            HostMO host = new HostMO(context, hostPair.first());
+            HostStorageSystemMO hostStorageSystem = host.getHostStorageSystemMO();
 
-        String strAuthType = "chapRequired";
+            boolean iScsiHbaConfigured = false;
 
-        auth.setChapAuthEnabled(true);
-        auth.setChapInherited(false);
-        auth.setChapAuthenticationType(strAuthType);
-        auth.setChapName(chapName);
-        auth.setChapSecret(chapSecret);
-        auth.setMutualChapInherited(false);
-        auth.setMutualChapAuthenticationType(strAuthType);
-        auth.setMutualChapName(mutualChapName);
-        auth.setMutualChapSecret(mutualChapSecret);
+            for (HostHostBusAdapter hba : hostStorageSystem.getStorageDeviceInfo().getHostBusAdapter()) {
+                if (hba instanceof HostInternetScsiHba) {
+                    // just finding an instance of HostInternetScsiHba means that we have found at least one configured iSCSI HBA
+                    // at least one iSCSI HBA must be configured before a CloudStack user can use this host for iSCSI storage
+                    iScsiHbaConfigured = true;
 
-        target.setAuthenticationProperties(auth);
+                    final String iScsiHbaDevice = hba.getDevice();
 
-        final List<HostInternetScsiHbaStaticTarget> lstTargets = new ArrayList<HostInternetScsiHbaStaticTarget>();
+                    final HostStorageSystemMO hss = hostStorageSystem;
 
-        lstTargets.add(target);
+                    executorService.submit(new Thread() {
+                        @Override
+                        public void run() {
+                            try {
+                                if (add) {
+                                    hss.addInternetScsiStaticTargets(iScsiHbaDevice, lstTargets);
+                                }
+                                else {
+                                    hss.removeInternetScsiStaticTargets(iScsiHbaDevice, lstTargets);
+                                }
+
+                                hss.rescanHba(iScsiHbaDevice);
+                                hss.rescanVmfs();
+                            }
+                            catch (Exception ex) {
+                                synchronized (exceptions) {
+                                    exceptions.add(ex);
+                                }
+                            }
+                        }
+                    });
+                }
+            }
+
+            if (!iScsiHbaConfigured) {
+                throw new Exception("An iSCSI HBA must be configured before a host can use iSCSI storage.");
+            }
+        }
+
+        executorService.shutdown();
+
+        if (!executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.MINUTES)) {
+            throw new Exception("The system timed out before completing the task 'rescanAllHosts'.");
+        }
+
+        if (exceptions.size() > 0) {
+            throw new Exception(exceptions.get(0).getMessage());
+        }
+    }
 
-        HostDatastoreSystemMO hostDatastoreSystem = null;
-        HostStorageSystemMO hostStorageSystem = null;
+    private void rescanAllHosts(final List<Pair<ManagedObjectReference, String>> lstHosts) throws Exception {
+        VmwareContext context = getServiceContext();
+
+        ExecutorService executorService = Executors.newFixedThreadPool(lstHosts.size());
 
-        final List<Thread> threads = new ArrayList<Thread>();
         final List<Exception> exceptions = new ArrayList<Exception>();
 
         for (Pair<ManagedObjectReference, String> hostPair : lstHosts) {
             HostMO host = new HostMO(context, hostPair.first());
-            hostDatastoreSystem = host.getHostDatastoreSystemMO();
-            hostStorageSystem = host.getHostStorageSystemMO();
+            HostStorageSystemMO hostStorageSystem = host.getHostStorageSystemMO();
 
             boolean iScsiHbaConfigured = false;
 
@@ -4265,12 +4270,10 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
 
                     final HostStorageSystemMO hss = hostStorageSystem;
 
-                    threads.add(new Thread() {
+                    executorService.submit(new Thread() {
                         @Override
                         public void run() {
                             try {
-                                hss.addInternetScsiStaticTargets(iScsiHbaDevice, lstTargets);
-
                                 hss.rescanHba(iScsiHbaDevice);
                                 hss.rescanVmfs();
                             }
@@ -4289,33 +4292,90 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
             }
         }
 
-        for (Thread thread : threads) {
-            thread.start();
-        }
+        executorService.shutdown();
 
-        for (Thread thread : threads) {
-            thread.join();
+        if (!executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.MINUTES)) {
+            throw new Exception("The system timed out before completing the task 'rescanAllHosts'.");
         }
 
         if (exceptions.size() > 0) {
             throw new Exception(exceptions.get(0).getMessage());
         }
+    }
+
+    private ManagedObjectReference createVmfsDatastore(VmwareHypervisorHost hyperHost, String datastoreName, String storageIpAddress,
+            int storagePortNumber, String iqn, String chapName, String chapSecret, String mutualChapName, String mutualChapSecret) throws Exception {
+        VmwareContext context = getServiceContext();
+        ManagedObjectReference morCluster = hyperHost.getHyperHostCluster();
+        ClusterMO cluster = new ClusterMO(context, morCluster);
+        List<Pair<ManagedObjectReference, String>> lstHosts = cluster.getClusterHosts();
+
+        HostInternetScsiHbaStaticTarget target = new HostInternetScsiHbaStaticTarget();
+
+        target.setAddress(storageIpAddress);
+        target.setPort(storagePortNumber);
+        target.setIScsiName(iqn);
+
+        HostInternetScsiHbaAuthenticationProperties auth = new HostInternetScsiHbaAuthenticationProperties();
+
+        String strAuthType = "chapRequired";
+
+        auth.setChapAuthEnabled(true);
+        auth.setChapInherited(false);
+        auth.setChapAuthenticationType(strAuthType);
+        auth.setChapName(chapName);
+        auth.setChapSecret(chapSecret);
+        auth.setMutualChapInherited(false);
+        auth.setMutualChapAuthenticationType(strAuthType);
+        auth.setMutualChapName(mutualChapName);
+        auth.setMutualChapSecret(mutualChapSecret);
+
+        target.setAuthenticationProperties(auth);
+
+        final List<HostInternetScsiHbaStaticTarget> lstTargets = new ArrayList<HostInternetScsiHbaStaticTarget>();
+
+        lstTargets.add(target);
+
+        addRemoveInternetScsiTargetsToAllHosts(true, lstTargets, lstHosts);
 
-        ManagedObjectReference morDs = hostDatastoreSystem.findDatastoreByName(iqn);
+        rescanAllHosts(lstHosts);
+
+        HostMO host = new HostMO(context, lstHosts.get(0).first());
+        HostDatastoreSystemMO hostDatastoreSystem = host.getHostDatastoreSystemMO();
+
+        ManagedObjectReference morDs = hostDatastoreSystem.findDatastoreByName(datastoreName);
 
         if (morDs != null) {
             return morDs;
         }
 
+        rescanAllHosts(lstHosts);
+
+        HostStorageSystemMO hostStorageSystem = host.getHostStorageSystemMO();
         List<HostScsiDisk> lstHostScsiDisks = hostDatastoreSystem.queryAvailableDisksForVmfs();
 
         HostScsiDisk hostScsiDisk = getHostScsiDisk(hostStorageSystem.getStorageDeviceInfo().getScsiTopology(), lstHostScsiDisks, iqn);
 
         if (hostScsiDisk == null) {
+            // check to see if the datastore actually does exist already
+            morDs = hostDatastoreSystem.findDatastoreByName(datastoreName);
+
+            if (morDs != null) {
+                return morDs;
+            }
+
             throw new Exception("A relevant SCSI disk could not be located to use to create a datastore.");
         }
 
-        return hostDatastoreSystem.createVmfsDatastore(datastoreName, hostScsiDisk);
+        morDs = hostDatastoreSystem.createVmfsDatastore(datastoreName, hostScsiDisk);
+
+        if (morDs != null) {
+            rescanAllHosts(lstHosts);
+
+            return morDs;
+        }
+
+        throw new Exception("Unable to create a datastore");
     }
 
     // the purpose of this method is to find the HostScsiDisk in the passed-in array that exists (if any) because
@@ -4363,46 +4423,9 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
 
         lstTargets.add(target);
 
-        final List<Thread> threads = new ArrayList<Thread>();
-        final List<Exception> exceptions = new ArrayList<Exception>();
-
-        for (Pair<ManagedObjectReference, String> hostPair : lstHosts) {
-            final HostMO host = new HostMO(context, hostPair.first());
-            final HostStorageSystemMO hostStorageSystem = host.getHostStorageSystemMO();
-
-            for (HostHostBusAdapter hba : hostStorageSystem.getStorageDeviceInfo().getHostBusAdapter()) {
-                if (hba instanceof HostInternetScsiHba) {
-                    final String iScsiHbaDevice = hba.getDevice();
+        addRemoveInternetScsiTargetsToAllHosts(false, lstTargets, lstHosts);
 
-                    Thread thread = new Thread() {
-                        @Override
-                        public void run() {
-                            try {
-                                hostStorageSystem.removeInternetScsiStaticTargets(iScsiHbaDevice, lstTargets);
-
-                                hostStorageSystem.rescanHba(iScsiHbaDevice);
-                                hostStorageSystem.rescanVmfs();
-                            }
-                            catch (Exception ex) {
-                                exceptions.add(ex);
-                            }
-                        }
-                    };
-
-                    threads.add(thread);
-
-                    thread.start();
-                }
-            }
-        }
-
-        for (Thread thread : threads) {
-            thread.join();
-        }
-
-        if (exceptions.size() > 0) {
-            throw new Exception(exceptions.get(0).getMessage());
-        }
+        rescanAllHosts(lstHosts);
     }
 
     protected Answer execute(AttachIsoCommand cmd) {