You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by GitBox <gi...@apache.org> on 2018/03/22 18:28:04 UTC

[GitHub] mike-tutkowski closed pull request #2503: Support multiple volume access groups per compute cluster

mike-tutkowski closed pull request #2503: Support multiple volume access groups per compute cluster
URL: https://github.com/apache/cloudstack/pull/2503
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java b/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java
index 30cff850c88..37656bcccc7 100644
--- a/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java
+++ b/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java
@@ -1653,18 +1653,18 @@ private ModifyTargetsCommand getModifyTargetsCommand(long storagePoolId, String
         details.put(ModifyTargetsCommand.STORAGE_HOST, storagePool.getHostAddress());
         details.put(ModifyTargetsCommand.STORAGE_PORT, String.valueOf(storagePool.getPort()));
 
-        ModifyTargetsCommand modifyTargetsCommand = new ModifyTargetsCommand();
+        ModifyTargetsCommand cmd = new ModifyTargetsCommand();
 
         List<Map<String, String>> targets = new ArrayList<>();
 
         targets.add(details);
 
-        modifyTargetsCommand.setTargets(targets);
-        modifyTargetsCommand.setApplyToAllHostsInCluster(true);
-        modifyTargetsCommand.setAdd(add);
-        modifyTargetsCommand.setTargetTypeToRemove(ModifyTargetsCommand.TargetTypeToRemove.DYNAMIC);
+        cmd.setTargets(targets);
+        cmd.setApplyToAllHostsInCluster(true);
+        cmd.setAdd(add);
+        cmd.setTargetTypeToRemove(ModifyTargetsCommand.TargetTypeToRemove.DYNAMIC);
 
-        return modifyTargetsCommand;
+        return cmd;
     }
 
     private List<String> sendModifyTargetsCommand(ModifyTargetsCommand cmd, long hostId) {
diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageProcessor.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageProcessor.java
index 0cea62f18fa..854e08638e9 100644
--- a/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageProcessor.java
+++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageProcessor.java
@@ -2621,7 +2621,7 @@ private void waitForAllHostsToSeeDatastore(List<Pair<ManagedObjectReference, Str
     private boolean verifyAllHostsSeeDatastore(List<Pair<ManagedObjectReference, String>> lstHosts, DatastoreMO dsMO) throws Exception {
         int numHostsChecked = 0;
 
-        for (Pair<ManagedObjectReference, String> host: lstHosts) {
+        for (Pair<ManagedObjectReference, String> host : lstHosts) {
             ManagedObjectReference morHostToMatch = host.first();
             HostMO hostToMatchMO = new HostMO(dsMO.getContext(), morHostToMatch);
 
@@ -2657,10 +2657,27 @@ private void waitForAllHostsToMountDatastore(List<Pair<ManagedObjectReference, S
         }
     }
 
+    private void waitForAllHostsToMountDatastore2(List<HostMO> lstHosts, DatastoreMO dsMO) throws Exception {
+        long secondsToWait = 120;
+        long endWaitTime = System.currentTimeMillis() + secondsToWait * 1000;
+
+        boolean isConditionMet = false;
+
+        while (System.currentTimeMillis() < endWaitTime && !isConditionMet) {
+            Thread.sleep(5000);
+
+            isConditionMet = verifyAllHostsMountedDatastore2(lstHosts, dsMO);
+        }
+
+        if (!isConditionMet) {
+            throw new CloudRuntimeException("Not all hosts mounted the datastore");
+        }
+    }
+
     private boolean verifyAllHostsMountedDatastore(List<Pair<ManagedObjectReference, String>> lstHosts, DatastoreMO dsMO) throws Exception {
         int numHostsChecked = 0;
 
-        for (Pair<ManagedObjectReference, String> host: lstHosts) {
+        for (Pair<ManagedObjectReference, String> host : lstHosts) {
             ManagedObjectReference morHostToMatch = host.first();
             HostMO hostToMatchMO = new HostMO(dsMO.getContext(), morHostToMatch);
 
@@ -2684,6 +2701,30 @@ private boolean verifyAllHostsMountedDatastore(List<Pair<ManagedObjectReference,
         return lstHosts.size() == numHostsChecked;
     }
 
+    private boolean verifyAllHostsMountedDatastore2(List<HostMO> lstHosts, DatastoreMO dsMO) throws Exception {
+        int numHostsChecked = 0;
+
+        for (HostMO hostToMatchMO : lstHosts) {
+            List<DatastoreHostMount> datastoreHostMounts = dsMO.getHostMounts();
+
+            for (DatastoreHostMount datastoreHostMount : datastoreHostMounts) {
+                ManagedObjectReference morHost = datastoreHostMount.getKey();
+                HostMO hostMO = new HostMO(dsMO.getContext(), morHost);
+
+                if (hostMO.getHostName().equals(hostToMatchMO.getHostName())) {
+                    if (datastoreHostMount.getMountInfo().isMounted() && datastoreHostMount.getMountInfo().isAccessible()) {
+                        numHostsChecked++;
+                    }
+                    else {
+                        return false;
+                    }
+                }
+            }
+        }
+
+        return lstHosts.size() == numHostsChecked;
+    }
+
     // the purpose of this method is to find the HostScsiDisk in the passed-in array that exists (if any) because
     // we added the static iqn to an iSCSI HBA
     private static HostScsiDisk getHostScsiDisk(HostScsiTopology hst, List<HostScsiDisk> lstHostScsiDisks, String iqn) {
@@ -2770,6 +2811,25 @@ private void mountVmfsDatastore(DatastoreMO dsMO, List<Pair<ManagedObjectReferen
         }
     }
 
+    private void mountVmfsDatastore2(DatastoreMO dsMO, List<HostMO> hosts) throws Exception {
+        for (HostMO hostMO : hosts) {
+            if (!isDatastoreMounted(dsMO, hostMO)) {
+                HostStorageSystemMO hostStorageSystemMO = hostMO.getHostStorageSystemMO();
+
+                try {
+                    hostStorageSystemMO.mountVmfsVolume(getDatastoreUuid(dsMO, hostMO));
+                }
+                catch (InvalidStateFaultMsg ex) {
+                    List<HostMO> currentHosts = new ArrayList<>(1);
+
+                    currentHosts.add(hostMO);
+
+                    waitForAllHostsToMountDatastore2(currentHosts, dsMO);
+                }
+            }
+        }
+    }
+
     private void unmountVmfsDatastore(VmwareContext context, VmwareHypervisorHost hyperHost, String datastoreName,
                                       List<Pair<ManagedObjectReference, String>> hosts) throws Exception {
         ManagedObjectReference morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, datastoreName);
@@ -2778,9 +2838,25 @@ private void unmountVmfsDatastore(VmwareContext context, VmwareHypervisorHost hy
         for (Pair<ManagedObjectReference, String> host : hosts) {
             HostMO hostMO = new HostMO(context, host.first());
 
-            HostStorageSystemMO hostStorageSystemMO = hostMO.getHostStorageSystemMO();
+            if (isDatastoreMounted(dsMO, hostMO)) {
+                HostStorageSystemMO hostStorageSystemMO = hostMO.getHostStorageSystemMO();
+
+                hostStorageSystemMO.unmountVmfsVolume(getDatastoreUuid(dsMO, hostMO));
+            }
+        }
+    }
+
+    private void unmountVmfsDatastore2(VmwareContext context, VmwareHypervisorHost hyperHost, String datastoreName,
+                                       List<HostMO> hosts) throws Exception {
+        ManagedObjectReference morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, datastoreName);
+        DatastoreMO dsMO = new DatastoreMO(context, morDs);
+
+        for (HostMO hostMO : hosts) {
+            if (isDatastoreMounted(dsMO, hostMO)) {
+                HostStorageSystemMO hostStorageSystemMO = hostMO.getHostStorageSystemMO();
 
-            hostStorageSystemMO.unmountVmfsVolume(getDatastoreUuid(dsMO, hostMO));
+                hostStorageSystemMO.unmountVmfsVolume(getDatastoreUuid(dsMO, hostMO));
+            }
         }
     }
 
@@ -2902,6 +2978,20 @@ public void handleTargets(boolean add, ModifyTargetsCommand.TargetTypeToRemove t
 
                         if (rescan) {
                             rescanAllHosts(hosts, true, false);
+
+                            List<HostInternetScsiHbaStaticTarget> targetsToAdd = new ArrayList<>();
+
+                            targetsToAdd.addAll(getTargets(staticTargetsForHost));
+                            targetsToAdd.addAll(getTargets(dynamicTargetsForHost));
+
+                            for (HostInternetScsiHbaStaticTarget targetToAdd : targetsToAdd) {
+                                HostDatastoreSystemMO hostDatastoreSystemMO = host.getHostDatastoreSystemMO();
+                                String datastoreName = waitForDatastoreName(hostDatastoreSystemMO, targetToAdd.getIScsiName());
+                                ManagedObjectReference morDs = hostDatastoreSystemMO.findDatastoreByName(datastoreName);
+                                DatastoreMO datastoreMO = new DatastoreMO(host.getContext(), morDs);
+
+                                mountVmfsDatastore2(datastoreMO, hosts);
+                            }
                         }
                     }
                     catch (Exception ex) {
@@ -2925,24 +3015,11 @@ public void handleTargets(boolean add, ModifyTargetsCommand.TargetTypeToRemove t
                 if (targetsToRemove.size() > 0) {
                     if (isRemoveAsync) {
                         new Thread(() -> {
-                            try {
-                                addRemoveInternetScsiTargetsToAllHosts(false, targetsToRemove, hosts);
-
-                                rescanAllHosts(hosts, true, false);
-                            } catch (Exception ex) {
-                                s_logger.warn(ex.getMessage());
-                            }
+                            handleRemove(targetsToRemove, host, hosts);
                         }).start();
                     } else {
                         executorService.submit(new Thread(() -> {
-                            try {
-                                addRemoveInternetScsiTargetsToAllHosts(false, targetsToRemove, hosts);
-
-                                rescanAllHosts(hosts, true, false);
-                            }
-                            catch (Exception ex) {
-                                s_logger.warn(ex.getMessage());
-                            }
+                            handleRemove(targetsToRemove, host, hosts);
                         }));
                     }
                 }
@@ -2956,6 +3033,61 @@ public void handleTargets(boolean add, ModifyTargetsCommand.TargetTypeToRemove t
         }
     }
 
+    private String waitForDatastoreName(HostDatastoreSystemMO hostDatastoreSystemMO, String iqn) throws Exception {
+        long secondsToWait = 120;
+        long endWaitTime = System.currentTimeMillis() + secondsToWait * 1000;
+
+        do {
+            String datastoreName = getDatastoreName(hostDatastoreSystemMO, iqn);
+
+            if (datastoreName != null) {
+                return datastoreName;
+            }
+
+            Thread.sleep(5000);
+        }
+        while (System.currentTimeMillis() < endWaitTime);
+
+        throw new CloudRuntimeException("Could not find the datastore name");
+    }
+
+    private String getDatastoreName(HostDatastoreSystemMO hostDatastoreSystemMO, String iqn) throws Exception {
+        String datastoreName = "-" + iqn + "-0";
+
+        ManagedObjectReference morDs = hostDatastoreSystemMO.findDatastoreByName(datastoreName);
+
+        if (morDs != null) {
+            return datastoreName;
+        }
+
+        datastoreName = "_" + iqn + "_0";
+
+        morDs = hostDatastoreSystemMO.findDatastoreByName(datastoreName);
+
+        if (morDs != null) {
+            return datastoreName;
+        }
+
+        return null;
+    }
+
+    private void handleRemove(List<HostInternetScsiHbaStaticTarget> targetsToRemove, HostMO host, List<HostMO> hosts) {
+        try {
+            for (HostInternetScsiHbaStaticTarget target : targetsToRemove) {
+                String datastoreName = waitForDatastoreName(host.getHostDatastoreSystemMO(), target.getIScsiName());
+
+                unmountVmfsDatastore2(host.getContext(), host, datastoreName, hosts);
+            }
+
+            addRemoveInternetScsiTargetsToAllHosts(false, targetsToRemove, hosts);
+
+            rescanAllHosts(hosts, true, false);
+        }
+        catch (Exception ex) {
+            s_logger.warn(ex.getMessage());
+        }
+    }
+
     private void addRemoveInternetScsiTargetsToAllHosts(VmwareContext context, final boolean add, final List<HostInternetScsiHbaStaticTarget> targets,
                                                         List<Pair<ManagedObjectReference, String>> hostPairs) throws Exception {
         List<HostMO> hosts = new ArrayList<>();
diff --git a/plugins/storage/volume/solidfire/src/main/java/org/apache/cloudstack/storage/datastore/driver/SolidFirePrimaryDataStoreDriver.java b/plugins/storage/volume/solidfire/src/main/java/org/apache/cloudstack/storage/datastore/driver/SolidFirePrimaryDataStoreDriver.java
index e7f96ca4a79..cff963da22e 100644
--- a/plugins/storage/volume/solidfire/src/main/java/org/apache/cloudstack/storage/datastore/driver/SolidFirePrimaryDataStoreDriver.java
+++ b/plugins/storage/volume/solidfire/src/main/java/org/apache/cloudstack/storage/datastore/driver/SolidFirePrimaryDataStoreDriver.java
@@ -30,8 +30,6 @@
 import com.cloud.agent.api.to.DataTO;
 import com.cloud.agent.api.to.DiskTO;
 import com.cloud.dc.ClusterVO;
-import com.cloud.dc.ClusterDetailsVO;
-import com.cloud.dc.ClusterDetailsDao;
 import com.cloud.dc.dao.ClusterDao;
 import com.cloud.host.Host;
 import com.cloud.host.HostVO;
@@ -87,7 +85,6 @@
 
 public class SolidFirePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
     private static final Logger LOGGER = Logger.getLogger(SolidFirePrimaryDataStoreDriver.class);
-    private static final int LOCK_TIME_IN_SECONDS = 300;
     private static final int LOWEST_HYPERVISOR_SNAPSHOT_RESERVE = 10;
     private static final long MIN_IOPS_FOR_TEMPLATE_VOLUME = 100L;
     private static final long MAX_IOPS_FOR_TEMPLATE_VOLUME = 20000L;
@@ -101,7 +98,6 @@
     @Inject private AccountDao accountDao;
     @Inject private AccountDetailsDao accountDetailsDao;
     @Inject private ClusterDao clusterDao;
-    @Inject private ClusterDetailsDao clusterDetailsDao;
     @Inject private DataStoreManager dataStoreMgr;
     @Inject private HostDao hostDao;
     @Inject private SnapshotDao snapshotDao;
@@ -146,14 +142,8 @@ public ChapInfo getChapInfo(DataObject dataObject) {
         return null;
     }
 
-    // get the VAG associated with volumeInfo's cluster, if any (ListVolumeAccessGroups)
-    // if the VAG exists
-    //     update the VAG to contain all IQNs of the hosts (ModifyVolumeAccessGroup)
-    //     if the ID of volumeInfo in not in the VAG, add it (ModifyVolumeAccessGroup)
-    // if the VAG doesn't exist, create it with the IQNs of the hosts and the ID of volumeInfo (CreateVolumeAccessGroup)
     @Override
-    public boolean grantAccess(DataObject dataObject, Host host, DataStore dataStore)
-    {
+    public boolean grantAccess(DataObject dataObject, Host host, DataStore dataStore) {
         Preconditions.checkArgument(dataObject != null, "'dataObject' should not be 'null'");
         Preconditions.checkArgument(host != null, "'host' should not be 'null'");
         Preconditions.checkArgument(dataStore != null, "'dataStore' should not be 'null'");
@@ -166,7 +156,7 @@ public boolean grantAccess(DataObject dataObject, Host host, DataStore dataStore
 
         GlobalLock lock = GlobalLock.getInternLock(cluster.getUuid());
 
-        if (!lock.lock(LOCK_TIME_IN_SECONDS)) {
+        if (!lock.lock(SolidFireUtil.LOCK_TIME_IN_SECONDS)) {
             String errMsg = "Couldn't lock the DB (in grantAccess) on the following string: " + cluster.getUuid();
 
             LOGGER.warn(errMsg);
@@ -175,32 +165,11 @@ public boolean grantAccess(DataObject dataObject, Host host, DataStore dataStore
         }
 
         try {
-            ClusterDetailsVO clusterDetail = clusterDetailsDao.findDetail(clusterId, SolidFireUtil.getVagKey(storagePoolId));
-
-            String vagId = clusterDetail != null ? clusterDetail.getValue() : null;
-
             List<HostVO> hosts = hostDao.findByClusterId(clusterId);
 
-            if (!SolidFireUtil.hostsSupport_iScsi(hosts)) {
-                String errMsg = "Not all hosts in the compute cluster support iSCSI.";
-
-                LOGGER.warn(errMsg);
-
-                throw new CloudRuntimeException(errMsg);
-            }
-
             SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePoolId, storagePoolDetailsDao);
 
-            if (vagId != null) {
-                SolidFireUtil.SolidFireVag sfVag = SolidFireUtil.getVag(sfConnection, Long.parseLong(vagId));
-
-                long[] volumeIds = SolidFireUtil.getNewVolumeIds(sfVag.getVolumeIds(), sfVolumeId, true);
-
-                SolidFireUtil.modifyVag(sfConnection, sfVag.getId(), sfVag.getInitiators(), volumeIds);
-            }
-            else {
-                SolidFireUtil.placeVolumeInVolumeAccessGroup(sfConnection, sfVolumeId, storagePoolId, cluster.getUuid(), hosts, clusterDetailsDao);
-            }
+            SolidFireUtil.placeVolumeInVolumeAccessGroups(sfConnection, sfVolumeId, hosts);
 
             return true;
         }
@@ -210,9 +179,6 @@ public boolean grantAccess(DataObject dataObject, Host host, DataStore dataStore
         }
     }
 
-    // get the VAG associated with volumeInfo's cluster, if any (ListVolumeAccessGroups) // might not exist if using CHAP
-    // if the VAG exists
-    //     remove the ID of volumeInfo from the VAG (ModifyVolumeAccessGroup)
     @Override
     public void revokeAccess(DataObject dataObject, Host host, DataStore dataStore)
     {
@@ -228,27 +194,23 @@ public void revokeAccess(DataObject dataObject, Host host, DataStore dataStore)
 
         GlobalLock lock = GlobalLock.getInternLock(cluster.getUuid());
 
-        if (!lock.lock(LOCK_TIME_IN_SECONDS)) {
+        if (!lock.lock(SolidFireUtil.LOCK_TIME_IN_SECONDS)) {
             String errMsg = "Couldn't lock the DB (in revokeAccess) on the following string: " + cluster.getUuid();
 
-            LOGGER.debug(errMsg);
+            LOGGER.warn(errMsg);
 
             throw new CloudRuntimeException(errMsg);
         }
 
         try {
-            ClusterDetailsVO clusterDetail = clusterDetailsDao.findDetail(clusterId, SolidFireUtil.getVagKey(storagePoolId));
-
-            String vagId = clusterDetail != null ? clusterDetail.getValue() : null;
-
-            if (vagId != null) {
-                SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePoolId, storagePoolDetailsDao);
-
-                SolidFireUtil.SolidFireVag sfVag = SolidFireUtil.getVag(sfConnection, Long.parseLong(vagId));
+            SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePoolId, storagePoolDetailsDao);
 
-                long[] volumeIds = SolidFireUtil.getNewVolumeIds(sfVag.getVolumeIds(), sfVolumeId, false);
+            List<SolidFireUtil.SolidFireVag> sfVags = SolidFireUtil.getAllVags(sfConnection);
 
-                SolidFireUtil.modifyVag(sfConnection, sfVag.getId(), sfVag.getInitiators(), volumeIds);
+            for (SolidFireUtil.SolidFireVag sfVag : sfVags) {
+                if (SolidFireUtil.sfVagContains(sfVag, sfVolumeId, clusterId, hostDao)) {
+                    SolidFireUtil.removeVolumeIdsFromSolidFireVag(sfConnection, sfVag.getId(), new Long[] { sfVolumeId });
+                }
             }
         }
         finally {
@@ -732,11 +694,7 @@ private boolean isBasicRevokeAccess(long volumeId) {
     private boolean getBooleanValueFromVolumeDetails(long volumeId, String name) {
         VolumeDetailVO volumeDetail = volumeDetailsDao.findDetail(volumeId, name);
 
-        if (volumeDetail != null && volumeDetail.getValue() != null) {
-            return Boolean.parseBoolean(volumeDetail.getValue());
-        }
-
-        return false;
+        return volumeDetail != null && volumeDetail.getValue() != null && Boolean.parseBoolean(volumeDetail.getValue());
     }
 
     private long getCsIdForCloning(long volumeId, String cloneOf) {
@@ -752,11 +710,7 @@ private long getCsIdForCloning(long volumeId, String cloneOf) {
     private boolean shouldTakeSnapshot(long snapshotId) {
         SnapshotDetailsVO snapshotDetails = snapshotDetailsDao.findDetail(snapshotId, "takeSnapshot");
 
-        if (snapshotDetails != null && snapshotDetails.getValue() != null) {
-            return Boolean.parseBoolean(snapshotDetails.getValue());
-        }
-
-        return false;
+        return snapshotDetails != null && snapshotDetails.getValue() != null && Boolean.parseBoolean(snapshotDetails.getValue());
     }
 
     private SolidFireUtil.SolidFireVolume createClone(SolidFireUtil.SolidFireConnection sfConnection, long dataObjectId, VolumeInfo volumeInfo, long sfAccountId,
diff --git a/plugins/storage/volume/solidfire/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/SolidFireSharedPrimaryDataStoreLifeCycle.java b/plugins/storage/volume/solidfire/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/SolidFireSharedPrimaryDataStoreLifeCycle.java
index 3172b1af5b4..2e3dbde4824 100644
--- a/plugins/storage/volume/solidfire/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/SolidFireSharedPrimaryDataStoreLifeCycle.java
+++ b/plugins/storage/volume/solidfire/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/SolidFireSharedPrimaryDataStoreLifeCycle.java
@@ -23,6 +23,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.UUID;
 
 import javax.inject.Inject;
 
@@ -49,8 +50,6 @@
 import com.cloud.agent.api.DeleteStoragePoolCommand;
 import com.cloud.agent.api.ModifyTargetsCommand;
 import com.cloud.agent.api.StoragePoolInfo;
-import com.cloud.dc.ClusterDetailsDao;
-import com.cloud.dc.ClusterDetailsVO;
 import com.cloud.dc.ClusterVO;
 import com.cloud.dc.dao.ClusterDao;
 import com.cloud.dc.dao.DataCenterDao;
@@ -75,23 +74,22 @@
 import com.cloud.utils.exception.CloudRuntimeException;
 
 public class SolidFireSharedPrimaryDataStoreLifeCycle implements PrimaryDataStoreLifeCycle {
-    private static final Logger s_logger = Logger.getLogger(SolidFireSharedPrimaryDataStoreLifeCycle.class);
-
-    @Inject private AccountDao _accountDao;
-    @Inject private AccountDetailsDao _accountDetailsDao;
-    @Inject private AgentManager _agentMgr;
-    @Inject private ClusterDao _clusterDao;
-    @Inject private ClusterDetailsDao _clusterDetailsDao;
-    @Inject private DataCenterDao _zoneDao;
-    @Inject private HostDao _hostDao;
-    @Inject private PrimaryDataStoreDao _primaryDataStoreDao;
-    @Inject private PrimaryDataStoreHelper _primaryDataStoreHelper;
-    @Inject private ResourceManager _resourceMgr;
-    @Inject private StorageManager _storageMgr;
-    @Inject private StoragePoolAutomation _storagePoolAutomation;
-    @Inject private StoragePoolDetailsDao _storagePoolDetailsDao;
-    @Inject private StoragePoolHostDao _storagePoolHostDao;
-    @Inject private TemplateManager _tmpltMgr;
+    private static final Logger LOGGER = Logger.getLogger(SolidFireSharedPrimaryDataStoreLifeCycle.class);
+
+    @Inject private AccountDao accountDao;
+    @Inject private AccountDetailsDao accountDetailsDao;
+    @Inject private AgentManager agentMgr;
+    @Inject private ClusterDao clusterDao;
+    @Inject private DataCenterDao zoneDao;
+    @Inject private HostDao hostDao;
+    @Inject private PrimaryDataStoreDao primaryDataStoreDao;
+    @Inject private PrimaryDataStoreHelper primaryDataStoreHelper;
+    @Inject private ResourceManager resourceMgr;
+    @Inject private StorageManager storageMgr;
+    @Inject private StoragePoolAutomation storagePoolAutomation;
+    @Inject private StoragePoolDetailsDao storagePoolDetailsDao;
+    @Inject private StoragePoolHostDao storagePoolHostDao;
+    @Inject private TemplateManager tmpltMgr;
 
     // invoked to add primary storage that is based on the SolidFire plug-in
     @Override
@@ -184,7 +182,7 @@ public DataStore initialize(Map<String, Object> dsInfos) {
                 lMinIops = Long.parseLong(minIops);
             }
         } catch (Exception ex) {
-            s_logger.info("[ignored] error getting Min IOPS: " + ex.getLocalizedMessage());
+            LOGGER.info("[ignored] error getting Min IOPS: " + ex.getLocalizedMessage());
         }
 
         try {
@@ -194,7 +192,7 @@ public DataStore initialize(Map<String, Object> dsInfos) {
                 lMaxIops = Long.parseLong(maxIops);
             }
         } catch (Exception ex) {
-            s_logger.info("[ignored] error getting Max IOPS: " + ex.getLocalizedMessage());
+            LOGGER.info("[ignored] error getting Max IOPS: " + ex.getLocalizedMessage());
         }
 
         try {
@@ -204,7 +202,7 @@ public DataStore initialize(Map<String, Object> dsInfos) {
                 lBurstIops = Long.parseLong(burstIops);
             }
         } catch (Exception ex) {
-            s_logger.info("[ignored] error getting Burst IOPS: " + ex.getLocalizedMessage());
+            LOGGER.info("[ignored] error getting Burst IOPS: " + ex.getLocalizedMessage());
         }
 
         if (lMinIops > lMaxIops) {
@@ -245,7 +243,7 @@ public DataStore initialize(Map<String, Object> dsInfos) {
 
         details.put(SolidFireUtil.VOLUME_ID, String.valueOf(sfVolume.getId()));
 
-        parameters.setUuid(iqn);
+        parameters.setUuid(UUID.randomUUID().toString());
 
         if (HypervisorType.VMware.equals(hypervisorType)) {
             String datastore = iqn.replace("/", "_");
@@ -266,14 +264,14 @@ public DataStore initialize(Map<String, Object> dsInfos) {
             parameters.setPath(iqn);
         }
 
-        ClusterVO cluster = _clusterDao.findById(clusterId);
+        ClusterVO cluster = clusterDao.findById(clusterId);
 
         GlobalLock lock = GlobalLock.getInternLock(cluster.getUuid());
 
-        if (!lock.lock(SolidFireUtil.s_lockTimeInSeconds)) {
+        if (!lock.lock(SolidFireUtil.LOCK_TIME_IN_SECONDS)) {
             String errMsg = "Couldn't lock the DB on the following string: " + cluster.getUuid();
 
-            s_logger.debug(errMsg);
+            LOGGER.debug(errMsg);
 
             throw new CloudRuntimeException(errMsg);
         }
@@ -282,21 +280,21 @@ public DataStore initialize(Map<String, Object> dsInfos) {
 
         try {
             // this adds a row in the cloud.storage_pool table for this SolidFire volume
-            dataStore = _primaryDataStoreHelper.createPrimaryDataStore(parameters);
+            dataStore = primaryDataStoreHelper.createPrimaryDataStore(parameters);
 
             // now that we have a DataStore (we need the id from the DataStore instance), we can create a Volume Access Group, if need be, and
             // place the newly created volume in the Volume Access Group
-            List<HostVO> hosts = _hostDao.findByClusterId(clusterId);
+            List<HostVO> hosts = hostDao.findByClusterId(clusterId);
 
-            SolidFireUtil.placeVolumeInVolumeAccessGroup(sfConnection, sfVolume.getId(), dataStore.getId(), cluster.getUuid(), hosts, _clusterDetailsDao);
+            SolidFireUtil.placeVolumeInVolumeAccessGroups(sfConnection, sfVolume.getId(), hosts);
 
             SolidFireUtil.SolidFireAccount sfAccount = sfCreateVolume.getAccount();
             Account csAccount = CallContext.current().getCallingAccount();
 
-            SolidFireUtil.updateCsDbWithSolidFireAccountInfo(csAccount.getId(), sfAccount, dataStore.getId(), _accountDetailsDao);
+            SolidFireUtil.updateCsDbWithSolidFireAccountInfo(csAccount.getId(), sfAccount, dataStore.getId(), accountDetailsDao);
         } catch (Exception ex) {
             if (dataStore != null) {
-                _primaryDataStoreDao.expunge(dataStore.getId());
+                primaryDataStoreDao.expunge(dataStore.getId());
             }
 
             throw new CloudRuntimeException(ex.getMessage());
@@ -310,7 +308,7 @@ public DataStore initialize(Map<String, Object> dsInfos) {
     }
 
     private HypervisorType getHypervisorTypeForCluster(long clusterId) {
-        ClusterVO cluster = _clusterDao.findById(clusterId);
+        ClusterVO cluster = clusterDao.findById(clusterId);
 
         if (cluster == null) {
             throw new CloudRuntimeException("Cluster ID '" + clusterId + "' was not found in the database.");
@@ -354,7 +352,7 @@ private SolidFireCreateVolume createSolidFireVolume(SolidFireUtil.SolidFireConne
         try {
             Account csAccount = CallContext.current().getCallingAccount();
             long csAccountId = csAccount.getId();
-            AccountVO accountVo = _accountDao.findById(csAccountId);
+            AccountVO accountVo = accountDao.findById(csAccountId);
 
             String sfAccountName = SolidFireUtil.getSolidFireAccountName(accountVo.getUuid(), csAccountId);
 
@@ -386,11 +384,11 @@ public boolean attachCluster(DataStore store, ClusterScope scope) {
         PrimaryDataStoreInfo primaryDataStoreInfo = (PrimaryDataStoreInfo)store;
 
         // check if there is at least one host up in this cluster
-        List<HostVO> allHosts = _resourceMgr.listAllUpHosts(Host.Type.Routing, primaryDataStoreInfo.getClusterId(),
+        List<HostVO> allHosts = resourceMgr.listAllUpHosts(Host.Type.Routing, primaryDataStoreInfo.getClusterId(),
                 primaryDataStoreInfo.getPodId(), primaryDataStoreInfo.getDataCenterId());
 
         if (allHosts.isEmpty()) {
-            _primaryDataStoreDao.expunge(primaryDataStoreInfo.getId());
+            primaryDataStoreDao.expunge(primaryDataStoreInfo.getId());
 
             throw new CloudRuntimeException("No host up to associate a storage pool with in cluster " + primaryDataStoreInfo.getClusterId());
         }
@@ -413,23 +411,23 @@ public boolean attachCluster(DataStore store, ClusterScope scope) {
 
         for (HostVO host : allHosts) {
             try {
-                _storageMgr.connectHostToSharedPool(host.getId(), primaryDataStoreInfo.getId());
+                storageMgr.connectHostToSharedPool(host.getId(), primaryDataStoreInfo.getId());
 
                 poolHosts.add(host);
             } catch (Exception e) {
-                s_logger.warn("Unable to establish a connection between " + host + " and " + primaryDataStoreInfo, e);
+                LOGGER.warn("Unable to establish a connection between " + host + " and " + primaryDataStoreInfo, e);
             }
         }
 
         if (poolHosts.isEmpty()) {
-            s_logger.warn("No host can access storage pool '" + primaryDataStoreInfo + "' on cluster '" + primaryDataStoreInfo.getClusterId() + "'.");
+            LOGGER.warn("No host can access storage pool '" + primaryDataStoreInfo + "' on cluster '" + primaryDataStoreInfo.getClusterId() + "'.");
 
-            _primaryDataStoreDao.expunge(primaryDataStoreInfo.getId());
+            primaryDataStoreDao.expunge(primaryDataStoreInfo.getId());
 
             throw new CloudRuntimeException("Failed to access storage pool");
         }
 
-        _primaryDataStoreHelper.attachCluster(store);
+        primaryDataStoreHelper.attachCluster(store);
 
         return true;
     }
@@ -444,31 +442,31 @@ private boolean createStoragePool(HostVO host, StoragePool storagePool) {
 
             Map<String, String> details = new HashMap<>();
 
-            StoragePoolDetailVO storagePoolDetail = _storagePoolDetailsDao.findDetail(storagePool.getId(), SolidFireUtil.DATASTORE_NAME);
+            StoragePoolDetailVO storagePoolDetail = storagePoolDetailsDao.findDetail(storagePool.getId(), SolidFireUtil.DATASTORE_NAME);
 
             details.put(CreateStoragePoolCommand.DATASTORE_NAME, storagePoolDetail.getValue());
 
-            storagePoolDetail = _storagePoolDetailsDao.findDetail(storagePool.getId(), SolidFireUtil.IQN);
+            storagePoolDetail = storagePoolDetailsDao.findDetail(storagePool.getId(), SolidFireUtil.IQN);
 
             details.put(CreateStoragePoolCommand.IQN, storagePoolDetail.getValue());
 
-            storagePoolDetail = _storagePoolDetailsDao.findDetail(storagePool.getId(), SolidFireUtil.STORAGE_VIP);
+            storagePoolDetail = storagePoolDetailsDao.findDetail(storagePool.getId(), SolidFireUtil.STORAGE_VIP);
 
             details.put(CreateStoragePoolCommand.STORAGE_HOST, storagePoolDetail.getValue());
 
-            storagePoolDetail = _storagePoolDetailsDao.findDetail(storagePool.getId(), SolidFireUtil.STORAGE_PORT);
+            storagePoolDetail = storagePoolDetailsDao.findDetail(storagePool.getId(), SolidFireUtil.STORAGE_PORT);
 
             details.put(CreateStoragePoolCommand.STORAGE_PORT, storagePoolDetail.getValue());
 
             cmd.setDetails(details);
         }
 
-        Answer answer = _agentMgr.easySend(hostId, cmd);
+        Answer answer = agentMgr.easySend(hostId, cmd);
 
         if (answer != null && answer.getResult()) {
             return true;
         } else {
-            _primaryDataStoreDao.expunge(storagePool.getId());
+            primaryDataStoreDao.expunge(storagePool.getId());
 
             final String msg;
 
@@ -478,7 +476,7 @@ private boolean createStoragePool(HostVO host, StoragePool storagePool) {
                 msg = "Cannot create storage pool through host '" + hostId + "' due to CreateStoragePoolCommand returns null";
             }
 
-            s_logger.warn(msg);
+            LOGGER.warn(msg);
 
             throw new CloudRuntimeException(msg);
         }
@@ -491,16 +489,16 @@ public boolean attachZone(DataStore dataStore, ZoneScope scope, HypervisorType h
 
     @Override
     public boolean maintain(DataStore dataStore) {
-        _storagePoolAutomation.maintain(dataStore);
-        _primaryDataStoreHelper.maintain(dataStore);
+        storagePoolAutomation.maintain(dataStore);
+        primaryDataStoreHelper.maintain(dataStore);
 
         return true;
     }
 
     @Override
     public boolean cancelMaintain(DataStore store) {
-        _primaryDataStoreHelper.cancelMaintain(store);
-        _storagePoolAutomation.cancelMaintain(store);
+        primaryDataStoreHelper.cancelMaintain(store);
+        storagePoolAutomation.cancelMaintain(store);
 
         return true;
     }
@@ -508,7 +506,7 @@ public boolean cancelMaintain(DataStore store) {
     // invoked to delete primary storage that is based on the SolidFire plug-in
     @Override
     public boolean deleteDataStore(DataStore dataStore) {
-        List<StoragePoolHostVO> hostPoolRecords = _storagePoolHostDao.listByPoolId(dataStore.getId());
+        List<StoragePoolHostVO> hostPoolRecords = storagePoolHostDao.listByPoolId(dataStore.getId());
 
         HypervisorType hypervisorType = null;
 
@@ -521,11 +519,11 @@ public boolean deleteDataStore(DataStore dataStore) {
         }
 
         StoragePool storagePool = (StoragePool)dataStore;
-        StoragePoolVO storagePoolVO = _primaryDataStoreDao.findById(storagePool.getId());
-        List<VMTemplateStoragePoolVO> unusedTemplatesInPool = _tmpltMgr.getUnusedTemplatesInPool(storagePoolVO);
+        StoragePoolVO storagePoolVO = primaryDataStoreDao.findById(storagePool.getId());
+        List<VMTemplateStoragePoolVO> unusedTemplatesInPool = tmpltMgr.getUnusedTemplatesInPool(storagePoolVO);
 
         for (VMTemplateStoragePoolVO templatePoolVO : unusedTemplatesInPool) {
-            _tmpltMgr.evictTemplateFromStoragePool(templatePoolVO);
+            tmpltMgr.evictTemplateFromStoragePool(templatePoolVO);
         }
 
         Long clusterId = null;
@@ -539,31 +537,31 @@ public boolean deleteDataStore(DataStore dataStore) {
 
                 Map<String, String> details = new HashMap<>();
 
-                StoragePoolDetailVO storagePoolDetail = _storagePoolDetailsDao.findDetail(storagePool.getId(), SolidFireUtil.DATASTORE_NAME);
+                StoragePoolDetailVO storagePoolDetail = storagePoolDetailsDao.findDetail(storagePool.getId(), SolidFireUtil.DATASTORE_NAME);
 
                 details.put(DeleteStoragePoolCommand.DATASTORE_NAME, storagePoolDetail.getValue());
 
-                storagePoolDetail = _storagePoolDetailsDao.findDetail(storagePool.getId(), SolidFireUtil.IQN);
+                storagePoolDetail = storagePoolDetailsDao.findDetail(storagePool.getId(), SolidFireUtil.IQN);
 
                 details.put(DeleteStoragePoolCommand.IQN, storagePoolDetail.getValue());
 
-                storagePoolDetail = _storagePoolDetailsDao.findDetail(storagePool.getId(), SolidFireUtil.STORAGE_VIP);
+                storagePoolDetail = storagePoolDetailsDao.findDetail(storagePool.getId(), SolidFireUtil.STORAGE_VIP);
 
                 details.put(DeleteStoragePoolCommand.STORAGE_HOST, storagePoolDetail.getValue());
 
-                storagePoolDetail = _storagePoolDetailsDao.findDetail(storagePool.getId(), SolidFireUtil.STORAGE_PORT);
+                storagePoolDetail = storagePoolDetailsDao.findDetail(storagePool.getId(), SolidFireUtil.STORAGE_PORT);
 
                 details.put(DeleteStoragePoolCommand.STORAGE_PORT, storagePoolDetail.getValue());
 
                 deleteCmd.setDetails(details);
             }
 
-            final Answer answer = _agentMgr.easySend(host.getHostId(), deleteCmd);
+            final Answer answer = agentMgr.easySend(host.getHostId(), deleteCmd);
 
             if (answer != null && answer.getResult()) {
-                s_logger.info("Successfully deleted storage pool using Host ID " + host.getHostId());
+                LOGGER.info("Successfully deleted storage pool using Host ID " + host.getHostId());
 
-                HostVO hostVO = _hostDao.findById(host.getHostId());
+                HostVO hostVO = hostDao.findById(host.getHostId());
 
                 if (hostVO != null) {
                     clusterId = hostVO.getClusterId();
@@ -574,29 +572,39 @@ public boolean deleteDataStore(DataStore dataStore) {
             }
             else {
                 if (answer != null) {
-                    s_logger.error("Failed to delete storage pool using Host ID " + host.getHostId() + ": " + answer.getResult());
+                    LOGGER.error("Failed to delete storage pool using Host ID " + host.getHostId() + ": " + answer.getResult());
                 }
                 else {
-                    s_logger.error("Failed to delete storage pool using Host ID " + host.getHostId());
+                    LOGGER.error("Failed to delete storage pool using Host ID " + host.getHostId());
                 }
             }
         }
 
         if (clusterId != null) {
-            ClusterVO cluster = _clusterDao.findById(clusterId);
+            ClusterVO cluster = clusterDao.findById(clusterId);
 
             GlobalLock lock = GlobalLock.getInternLock(cluster.getUuid());
 
-            if (!lock.lock(SolidFireUtil.s_lockTimeInSeconds)) {
+            if (!lock.lock(SolidFireUtil.LOCK_TIME_IN_SECONDS)) {
                 String errMsg = "Couldn't lock the DB on the following string: " + cluster.getUuid();
 
-                s_logger.debug(errMsg);
+                LOGGER.debug(errMsg);
 
                 throw new CloudRuntimeException(errMsg);
             }
 
             try {
-                removeVolumeFromVag(storagePool.getId(), clusterId);
+                long sfVolumeId = getVolumeId(storagePool.getId());
+
+                SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePool.getId(), storagePoolDetailsDao);
+
+                List<SolidFireUtil.SolidFireVag> sfVags = SolidFireUtil.getAllVags(sfConnection);
+
+                for (SolidFireUtil.SolidFireVag sfVag : sfVags) {
+                    if (SolidFireUtil.sfVagContains(sfVag, sfVolumeId, clusterId, hostDao)) {
+                        SolidFireUtil.removeVolumeIdsFromSolidFireVag(sfConnection, sfVag.getId(), new Long[] { sfVolumeId });
+                    }
+                }
             }
             finally {
                 lock.unlock();
@@ -610,16 +618,16 @@ public boolean deleteDataStore(DataStore dataStore) {
 
         deleteSolidFireVolume(storagePool.getId());
 
-        return _primaryDataStoreHelper.deletePrimaryDataStore(dataStore);
+        return primaryDataStoreHelper.deletePrimaryDataStore(dataStore);
     }
 
     private void handleTargetsForVMware(long hostId, long storagePoolId) {
-        HostVO host = _hostDao.findById(hostId);
+        HostVO host = hostDao.findById(hostId);
 
         if (host.getHypervisorType() == HypervisorType.VMware) {
-            String storageAddress = _storagePoolDetailsDao.findDetail(storagePoolId, SolidFireUtil.STORAGE_VIP).getValue();
-            int storagePort = Integer.parseInt(_storagePoolDetailsDao.findDetail(storagePoolId, SolidFireUtil.STORAGE_PORT).getValue());
-            String iqn = _storagePoolDetailsDao.findDetail(storagePoolId, SolidFireUtil.IQN).getValue();
+            String storageAddress = storagePoolDetailsDao.findDetail(storagePoolId, SolidFireUtil.STORAGE_VIP).getValue();
+            int storagePort = Integer.parseInt(storagePoolDetailsDao.findDetail(storagePoolId, SolidFireUtil.STORAGE_PORT).getValue());
+            String iqn = storagePoolDetailsDao.findDetail(storagePoolId, SolidFireUtil.IQN).getValue();
 
             ModifyTargetsCommand cmd = new ModifyTargetsCommand();
 
@@ -644,39 +652,22 @@ private void handleTargetsForVMware(long hostId, long storagePoolId) {
     }
 
     private void sendModifyTargetsCommand(ModifyTargetsCommand cmd, long hostId) {
-        Answer answer = _agentMgr.easySend(hostId, cmd);
+        Answer answer = agentMgr.easySend(hostId, cmd);
 
         if (answer == null) {
             String msg = "Unable to get an answer to the modify targets command";
 
-            s_logger.warn(msg);
+            LOGGER.warn(msg);
         }
         else if (!answer.getResult()) {
             String msg = "Unable to modify target on the following host: " + hostId;
 
-            s_logger.warn(msg);
-        }
-    }
-
-    private void removeVolumeFromVag(long storagePoolId, long clusterId) {
-        long sfVolumeId = getVolumeId(storagePoolId);
-        ClusterDetailsVO clusterDetail = _clusterDetailsDao.findDetail(clusterId, SolidFireUtil.getVagKey(storagePoolId));
-
-        String vagId = clusterDetail != null ? clusterDetail.getValue() : null;
-
-        if (vagId != null) {
-            SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePoolId, _storagePoolDetailsDao);
-
-            SolidFireUtil.SolidFireVag sfVag = SolidFireUtil.getVag(sfConnection, Long.parseLong(vagId));
-
-            long[] volumeIds = SolidFireUtil.getNewVolumeIds(sfVag.getVolumeIds(), sfVolumeId, false);
-
-            SolidFireUtil.modifyVag(sfConnection, sfVag.getId(), sfVag.getInitiators(), volumeIds);
+            LOGGER.warn(msg);
         }
     }
 
     private void deleteSolidFireVolume(long storagePoolId) {
-        SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePoolId, _storagePoolDetailsDao);
+        SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePoolId, storagePoolDetailsDao);
 
         long sfVolumeId = getVolumeId(storagePoolId);
 
@@ -684,7 +675,7 @@ private void deleteSolidFireVolume(long storagePoolId) {
     }
 
     private long getVolumeId(long storagePoolId) {
-        StoragePoolDetailVO storagePoolDetail = _storagePoolDetailsDao.findDetail(storagePoolId, SolidFireUtil.VOLUME_ID);
+        StoragePoolDetailVO storagePoolDetail = storagePoolDetailsDao.findDetail(storagePoolId, SolidFireUtil.VOLUME_ID);
 
         String volumeId = storagePoolDetail.getValue();
 
@@ -692,7 +683,7 @@ private long getVolumeId(long storagePoolId) {
     }
 
     private long getIopsValue(long storagePoolId, String iopsKey) {
-        StoragePoolDetailVO storagePoolDetail = _storagePoolDetailsDao.findDetail(storagePoolId, iopsKey);
+        StoragePoolDetailVO storagePoolDetail = storagePoolDetailsDao.findDetail(storagePoolId, iopsKey);
 
         String iops = storagePoolDetail.getValue();
 
@@ -704,7 +695,7 @@ private static boolean isSupportedHypervisorType(HypervisorType hypervisorType)
     }
 
     private HypervisorType getHypervisorType(long hostId) {
-        HostVO host = _hostDao.findById(hostId);
+        HostVO host = hostDao.findById(hostId);
 
         if (host != null) {
             return host.getHypervisorType();
@@ -729,7 +720,7 @@ public void updateStoragePool(StoragePool storagePool, Map<String, String> detai
         Long capacityBytes = strCapacityBytes != null ? Long.parseLong(strCapacityBytes) : null;
         Long capacityIops = strCapacityIops != null ? Long.parseLong(strCapacityIops) : null;
 
-        SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePool.getId(), _storagePoolDetailsDao);
+        SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePool.getId(), storagePoolDetailsDao);
 
         long size = capacityBytes != null ? capacityBytes : storagePool.getCapacityBytes();
 
@@ -764,16 +755,16 @@ public void updateStoragePool(StoragePool storagePool, Map<String, String> detai
 
         SolidFireUtil.modifyVolume(sfConnection, getVolumeId(storagePool.getId()), size, null, minIops, maxIops, burstIops);
 
-        SolidFireUtil.updateCsDbWithSolidFireIopsInfo(storagePool.getId(), _primaryDataStoreDao, _storagePoolDetailsDao, minIops, maxIops, burstIops);
+        SolidFireUtil.updateCsDbWithSolidFireIopsInfo(storagePool.getId(), primaryDataStoreDao, storagePoolDetailsDao, minIops, maxIops, burstIops);
     }
 
     @Override
     public void enableStoragePool(DataStore dataStore) {
-        _primaryDataStoreHelper.enable(dataStore);
+        primaryDataStoreHelper.enable(dataStore);
     }
 
     @Override
     public void disableStoragePool(DataStore dataStore) {
-        _primaryDataStoreHelper.disable(dataStore);
+        primaryDataStoreHelper.disable(dataStore);
     }
 }
diff --git a/plugins/storage/volume/solidfire/src/main/java/org/apache/cloudstack/storage/datastore/provider/SolidFireHostListener.java b/plugins/storage/volume/solidfire/src/main/java/org/apache/cloudstack/storage/datastore/provider/SolidFireHostListener.java
index f9c27e9d840..a43efe2bb2f 100644
--- a/plugins/storage/volume/solidfire/src/main/java/org/apache/cloudstack/storage/datastore/provider/SolidFireHostListener.java
+++ b/plugins/storage/volume/solidfire/src/main/java/org/apache/cloudstack/storage/datastore/provider/SolidFireHostListener.java
@@ -40,7 +40,6 @@
 import com.cloud.agent.api.ModifyStoragePoolCommand;
 import com.cloud.agent.api.ModifyTargetsCommand;
 import com.cloud.alert.AlertManager;
-import com.cloud.dc.ClusterDetailsDao;
 import com.cloud.dc.dao.ClusterDao;
 import com.cloud.host.HostVO;
 import com.cloud.host.dao.HostDao;
@@ -56,31 +55,31 @@
 import com.cloud.vm.dao.VMInstanceDao;
 
 public class SolidFireHostListener implements HypervisorHostListener {
-    private static final Logger s_logger = Logger.getLogger(SolidFireHostListener.class);
-
-    @Inject private AgentManager _agentMgr;
-    @Inject private AlertManager _alertMgr;
-    @Inject private ClusterDao _clusterDao;
-    @Inject private ClusterDetailsDao _clusterDetailsDao;
-    @Inject private DataStoreManager _dataStoreMgr;
-    @Inject private HostDao _hostDao;
-    @Inject private PrimaryDataStoreDao _storagePoolDao;
-    @Inject private StoragePoolDetailsDao _storagePoolDetailsDao;
+    private static final Logger LOGGER = Logger.getLogger(SolidFireHostListener.class);
+
+    @Inject private AgentManager agentMgr;
+    @Inject private AlertManager alertMgr;
+    @Inject private ClusterDao clusterDao;
+    @Inject private DataStoreManager dataStoreMgr;
+    @Inject private HostDao hostDao;
+    @Inject private PrimaryDataStoreDao storagePoolDao;
+    @Inject private StoragePoolDetailsDao storagePoolDetailsDao;
     @Inject private StoragePoolHostDao storagePoolHostDao;
-    @Inject private VMInstanceDao _vmDao;
-    @Inject private VolumeDao _volumeDao;
+    @Inject private VMInstanceDao vmDao;
+    @Inject private VolumeDao volumeDao;
 
     @Override
     public boolean hostAdded(long hostId) {
-        HostVO host = _hostDao.findById(hostId);
+        HostVO host = hostDao.findById(hostId);
 
         if (host == null) {
-            s_logger.error("Failed to add host by SolidFireHostListener as host was not found with id=" + hostId);
+            LOGGER.error("Failed to add host by SolidFireHostListener as host was not found with id = " + hostId);
+
             return false;
         }
 
-        SolidFireUtil.hostAddedToOrRemovedFromCluster(hostId, host.getClusterId(), true, SolidFireUtil.PROVIDER_NAME,
-                _clusterDao, _clusterDetailsDao, _storagePoolDao, _storagePoolDetailsDao, _hostDao);
+        SolidFireUtil.hostAddedToCluster(hostId, host.getClusterId(), SolidFireUtil.PROVIDER_NAME,
+                clusterDao, hostDao, storagePoolDao, storagePoolDetailsDao);
 
         handleVMware(host, true, ModifyTargetsCommand.TargetTypeToRemove.NEITHER);
 
@@ -89,7 +88,7 @@ public boolean hostAdded(long hostId) {
 
     @Override
     public boolean hostConnect(long hostId, long storagePoolId) {
-        HostVO host = _hostDao.findById(hostId);
+        HostVO host = hostDao.findById(hostId);
 
         StoragePoolHostVO storagePoolHost = storagePoolHostDao.findByPoolHost(storagePoolId, hostId);
 
@@ -122,25 +121,25 @@ public boolean hostDisconnected(long hostId, long storagePoolId) {
 
     @Override
     public boolean hostAboutToBeRemoved(long hostId) {
+        HostVO host = hostDao.findById(hostId);
+
+        SolidFireUtil.hostRemovedFromCluster(hostId, host.getClusterId(), SolidFireUtil.PROVIDER_NAME,
+                clusterDao, hostDao, storagePoolDao, storagePoolDetailsDao);
+
+        handleVMware(host, false, ModifyTargetsCommand.TargetTypeToRemove.BOTH);
+
         return true;
     }
 
     @Override
     public boolean hostRemoved(long hostId, long clusterId) {
-        SolidFireUtil.hostAddedToOrRemovedFromCluster(hostId, clusterId, false, SolidFireUtil.PROVIDER_NAME,
-                _clusterDao, _clusterDetailsDao, _storagePoolDao, _storagePoolDetailsDao, _hostDao);
-
-        HostVO host = _hostDao.findById(hostId);
-
-        handleVMware(host, false, ModifyTargetsCommand.TargetTypeToRemove.BOTH);
-
         return true;
     }
 
     private void handleXenServer(long clusterId, long hostId, long storagePoolId) {
         List<String> storagePaths = getStoragePaths(clusterId, storagePoolId);
 
-        StoragePool storagePool = (StoragePool)_dataStoreMgr.getDataStore(storagePoolId, DataStoreRole.Primary);
+        StoragePool storagePool = (StoragePool)dataStoreMgr.getDataStore(storagePoolId, DataStoreRole.Primary);
 
         for (String storagePath : storagePaths) {
             ModifyStoragePoolCommand cmd = new ModifyStoragePoolCommand(true, storagePool);
@@ -153,7 +152,7 @@ private void handleXenServer(long clusterId, long hostId, long storagePoolId) {
 
     private void handleVMware(HostVO host, boolean add, ModifyTargetsCommand.TargetTypeToRemove targetTypeToRemove) {
         if (HypervisorType.VMware.equals(host.getHypervisorType())) {
-            List<StoragePoolVO> storagePools = _storagePoolDao.findPoolsByProvider(SolidFireUtil.PROVIDER_NAME);
+            List<StoragePoolVO> storagePools = storagePoolDao.findPoolsByProvider(SolidFireUtil.PROVIDER_NAME);
 
             if (storagePools != null && storagePools.size() > 0) {
                 List<Map<String, String>> targets = new ArrayList<>();
@@ -169,6 +168,7 @@ private void handleVMware(HostVO host, boolean add, ModifyTargetsCommand.TargetT
                 cmd.setTargets(targets);
                 cmd.setAdd(add);
                 cmd.setTargetTypeToRemove(targetTypeToRemove);
+                cmd.setRemoveAsync(true);
 
                 sendModifyTargetsCommand(cmd, host.getId());
             }
@@ -176,7 +176,7 @@ private void handleVMware(HostVO host, boolean add, ModifyTargetsCommand.TargetT
     }
 
     private void handleKVM(long hostId, long storagePoolId) {
-        StoragePool storagePool = (StoragePool)_dataStoreMgr.getDataStore(storagePoolId, DataStoreRole.Primary);
+        StoragePool storagePool = (StoragePool)dataStoreMgr.getDataStore(storagePoolId, DataStoreRole.Primary);
 
         ModifyStoragePoolCommand cmd = new ModifyStoragePoolCommand(true, storagePool);
 
@@ -187,19 +187,19 @@ private void handleKVM(long hostId, long storagePoolId) {
         List<String> storagePaths = new ArrayList<>();
 
         // If you do not pass in null for the second parameter, you only get back applicable ROOT disks.
-        List<VolumeVO> volumes = _volumeDao.findByPoolId(storagePoolId, null);
+        List<VolumeVO> volumes = volumeDao.findByPoolId(storagePoolId, null);
 
         if (volumes != null) {
             for (VolumeVO volume : volumes) {
                 Long instanceId = volume.getInstanceId();
 
                 if (instanceId != null) {
-                    VMInstanceVO vmInstance = _vmDao.findById(instanceId);
+                    VMInstanceVO vmInstance = vmDao.findById(instanceId);
 
                     Long hostIdForVm = vmInstance.getHostId() != null ? vmInstance.getHostId() : vmInstance.getLastHostId();
 
                     if (hostIdForVm != null) {
-                        HostVO hostForVm = _hostDao.findById(hostIdForVm);
+                        HostVO hostForVm = hostDao.findById(hostIdForVm);
 
                         if (hostForVm != null && hostForVm.getClusterId().equals(clusterId)) {
                             storagePaths.add(volume.get_iScsiName());
@@ -215,22 +215,22 @@ private void handleKVM(long hostId, long storagePoolId) {
     private List<Map<String, String>> getTargets(long clusterId, long storagePoolId) {
         List<Map<String, String>> targets = new ArrayList<>();
 
-        StoragePoolVO storagePool = _storagePoolDao.findById(storagePoolId);
+        StoragePoolVO storagePool = storagePoolDao.findById(storagePoolId);
 
         // If you do not pass in null for the second parameter, you only get back applicable ROOT disks.
-        List<VolumeVO> volumes = _volumeDao.findByPoolId(storagePoolId, null);
+        List<VolumeVO> volumes = volumeDao.findByPoolId(storagePoolId, null);
 
         if (volumes != null) {
             for (VolumeVO volume : volumes) {
                 Long instanceId = volume.getInstanceId();
 
                 if (instanceId != null) {
-                    VMInstanceVO vmInstance = _vmDao.findById(instanceId);
+                    VMInstanceVO vmInstance = vmDao.findById(instanceId);
 
                     Long hostIdForVm = vmInstance.getHostId() != null ? vmInstance.getHostId() : vmInstance.getLastHostId();
 
                     if (hostIdForVm != null) {
-                        HostVO hostForVm = _hostDao.findById(hostIdForVm);
+                        HostVO hostForVm = hostDao.findById(hostIdForVm);
 
                         if (hostForVm.getClusterId().equals(clusterId)) {
                             Map<String, String> details = new HashMap<>();
@@ -250,7 +250,7 @@ private void handleKVM(long hostId, long storagePoolId) {
     }
 
     private void sendModifyTargetsCommand(ModifyTargetsCommand cmd, long hostId) {
-        Answer answer = _agentMgr.easySend(hostId, cmd);
+        Answer answer = agentMgr.easySend(hostId, cmd);
 
         if (answer == null) {
             throw new CloudRuntimeException("Unable to get an answer to the modify targets command");
@@ -259,16 +259,16 @@ private void sendModifyTargetsCommand(ModifyTargetsCommand cmd, long hostId) {
         if (!answer.getResult()) {
             String msg = "Unable to modify targets on the following host: " + hostId;
 
-            HostVO host = _hostDao.findById(hostId);
+            HostVO host = hostDao.findById(hostId);
 
-            _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, host.getDataCenterId(), host.getPodId(), msg, msg);
+            alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, host.getDataCenterId(), host.getPodId(), msg, msg);
 
             throw new CloudRuntimeException(msg);
         }
     }
 
     private void sendModifyStoragePoolCommand(ModifyStoragePoolCommand cmd, StoragePool storagePool, long hostId) {
-        Answer answer = _agentMgr.easySend(hostId, cmd);
+        Answer answer = agentMgr.easySend(hostId, cmd);
 
         if (answer == null) {
             throw new CloudRuntimeException("Unable to get an answer to the modify storage pool command (" + storagePool.getId() + ")");
@@ -277,7 +277,7 @@ private void sendModifyStoragePoolCommand(ModifyStoragePoolCommand cmd, StorageP
         if (!answer.getResult()) {
             String msg = "Unable to attach storage pool " + storagePool.getId() + " to host " + hostId;
 
-            _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, storagePool.getDataCenterId(), storagePool.getPodId(), msg, msg);
+            alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, storagePool.getDataCenterId(), storagePool.getPodId(), msg, msg);
 
             throw new CloudRuntimeException("Unable to establish a connection from agent to storage pool " + storagePool.getId() + " due to " + answer.getDetails() +
                 " (" + storagePool.getId() + ")");
@@ -285,6 +285,6 @@ private void sendModifyStoragePoolCommand(ModifyStoragePoolCommand cmd, StorageP
 
         assert (answer instanceof ModifyStoragePoolAnswer) : "ModifyStoragePoolAnswer expected ; Pool = " + storagePool.getId() + " Host = " + hostId;
 
-        s_logger.info("Connection established between storage pool " + storagePool + " and host + " + hostId);
+        LOGGER.info("Connection established between storage pool " + storagePool + " and host + " + hostId);
     }
 }
diff --git a/plugins/storage/volume/solidfire/src/main/java/org/apache/cloudstack/storage/datastore/provider/SolidFireSharedHostListener.java b/plugins/storage/volume/solidfire/src/main/java/org/apache/cloudstack/storage/datastore/provider/SolidFireSharedHostListener.java
index 66aafacdbfd..575a3020d37 100644
--- a/plugins/storage/volume/solidfire/src/main/java/org/apache/cloudstack/storage/datastore/provider/SolidFireSharedHostListener.java
+++ b/plugins/storage/volume/solidfire/src/main/java/org/apache/cloudstack/storage/datastore/provider/SolidFireSharedHostListener.java
@@ -40,7 +40,6 @@
 import com.cloud.agent.api.ModifyStoragePoolCommand;
 import com.cloud.agent.api.ModifyTargetsCommand;
 import com.cloud.alert.AlertManager;
-import com.cloud.dc.ClusterDetailsDao;
 import com.cloud.dc.dao.ClusterDao;
 import com.cloud.host.HostVO;
 import com.cloud.host.dao.HostDao;
@@ -57,7 +56,6 @@
     @Inject private AgentManager agentMgr;
     @Inject private AlertManager alertMgr;
     @Inject private ClusterDao clusterDao;
-    @Inject private ClusterDetailsDao clusterDetailsDao;
     @Inject private DataStoreManager dataStoreMgr;
     @Inject private HostDao hostDao;
     @Inject private PrimaryDataStoreDao storagePoolDao;
@@ -69,14 +67,15 @@ public boolean hostAdded(long hostId) {
         HostVO host = hostDao.findById(hostId);
 
         if (host == null) {
-            LOGGER.error("Failed to add host by SolidFireSharedHostListener as host was not found with id=" + hostId);
+            LOGGER.error("Failed to add host by SolidFireSharedHostListener as host was not found with id = " + hostId);
+
             return false;
         }
 
-        SolidFireUtil.hostAddedToOrRemovedFromCluster(hostId, host.getClusterId(), true, SolidFireUtil.SHARED_PROVIDER_NAME,
-                clusterDao, clusterDetailsDao, storagePoolDao, storagePoolDetailsDao, hostDao);
+        SolidFireUtil.hostAddedToCluster(hostId, host.getClusterId(), SolidFireUtil.SHARED_PROVIDER_NAME,
+                clusterDao, hostDao, storagePoolDao, storagePoolDetailsDao);
 
-        handleVMware(hostId, true, ModifyTargetsCommand.TargetTypeToRemove.NEITHER);
+        handleVMware(host, true, ModifyTargetsCommand.TargetTypeToRemove.NEITHER);
 
         return true;
     }
@@ -123,10 +122,10 @@ public boolean hostDisconnected(long hostId, long storagePoolId) {
     public boolean hostAboutToBeRemoved(long hostId) {
         HostVO host = hostDao.findById(hostId);
 
-        SolidFireUtil.hostAddedToOrRemovedFromCluster(hostId, host.getClusterId(), false, SolidFireUtil.SHARED_PROVIDER_NAME,
-                clusterDao, clusterDetailsDao, storagePoolDao, storagePoolDetailsDao, hostDao);
+        SolidFireUtil.hostRemovedFromCluster(hostId, host.getClusterId(), SolidFireUtil.SHARED_PROVIDER_NAME,
+                clusterDao, hostDao, storagePoolDao, storagePoolDetailsDao);
 
-        handleVMware(hostId, false, ModifyTargetsCommand.TargetTypeToRemove.BOTH);
+        handleVMware(host, false, ModifyTargetsCommand.TargetTypeToRemove.BOTH);
 
         return true;
     }
@@ -136,9 +135,7 @@ public boolean hostRemoved(long hostId, long clusterId) {
         return true;
     }
 
-    private void handleVMware(long hostId, boolean add, ModifyTargetsCommand.TargetTypeToRemove targetTypeToRemove) {
-        HostVO host = hostDao.findById(hostId);
-
+    private void handleVMware(HostVO host, boolean add, ModifyTargetsCommand.TargetTypeToRemove targetTypeToRemove) {
         if (HypervisorType.VMware.equals(host.getHypervisorType())) {
             List<StoragePoolVO> storagePools = storagePoolDao.findPoolsByProvider(SolidFireUtil.SHARED_PROVIDER_NAME);
 
@@ -179,7 +176,7 @@ private void handleVMware(long hostId, boolean add, ModifyTargetsCommand.TargetT
                     cmd.setTargetTypeToRemove(targetTypeToRemove);
                     cmd.setRemoveAsync(true);
 
-                    sendModifyTargetsCommand(cmd, hostId);
+                    sendModifyTargetsCommand(cmd, host.getId());
                 }
             }
         }
diff --git a/plugins/storage/volume/solidfire/src/main/java/org/apache/cloudstack/storage/datastore/util/SolidFireUtil.java b/plugins/storage/volume/solidfire/src/main/java/org/apache/cloudstack/storage/datastore/util/SolidFireUtil.java
index 81adf4b343e..53f8342291e 100644
--- a/plugins/storage/volume/solidfire/src/main/java/org/apache/cloudstack/storage/datastore/util/SolidFireUtil.java
+++ b/plugins/storage/volume/solidfire/src/main/java/org/apache/cloudstack/storage/datastore/util/SolidFireUtil.java
@@ -17,12 +17,14 @@
 package org.apache.cloudstack.storage.datastore.util;
 
 import java.util.ArrayList;
-import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Random;
 import java.util.Set;
 import java.util.StringTokenizer;
+import java.util.UUID;
 
 import org.apache.commons.lang.StringUtils;
 import org.apache.log4j.Logger;
@@ -32,8 +34,6 @@
 import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao;
 import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
 
-import com.cloud.dc.ClusterDetailsDao;
-import com.cloud.dc.ClusterDetailsVO;
 import com.cloud.dc.ClusterVO;
 import com.cloud.dc.dao.ClusterDao;
 import com.cloud.host.Host;
@@ -44,11 +44,14 @@
 import com.cloud.utils.db.GlobalLock;
 import com.cloud.utils.exception.CloudRuntimeException;
 
+import com.google.common.base.Preconditions;
 import com.google.common.primitives.Longs;
 
 import com.solidfire.client.ElementFactory;
 import com.solidfire.element.api.Account;
 import com.solidfire.element.api.AddAccountRequest;
+import com.solidfire.element.api.AddInitiatorsToVolumeAccessGroupRequest;
+import com.solidfire.element.api.AddVolumesToVolumeAccessGroupRequest;
 import com.solidfire.element.api.CloneVolumeRequest;
 import com.solidfire.element.api.CloneVolumeResult;
 import com.solidfire.element.api.CreateSnapshotRequest;
@@ -62,9 +65,10 @@
 import com.solidfire.element.api.ListSnapshotsRequest;
 import com.solidfire.element.api.ListVolumeAccessGroupsRequest;
 import com.solidfire.element.api.ListVolumesRequest;
-import com.solidfire.element.api.ModifyVolumeAccessGroupRequest;
 import com.solidfire.element.api.ModifyVolumeRequest;
 import com.solidfire.element.api.QoS;
+import com.solidfire.element.api.RemoveInitiatorsFromVolumeAccessGroupRequest;
+import com.solidfire.element.api.RemoveVolumesFromVolumeAccessGroupRequest;
 import com.solidfire.element.api.RollbackToSnapshotRequest;
 import com.solidfire.element.api.Snapshot;
 import com.solidfire.element.api.SolidFireElement;
@@ -75,12 +79,13 @@
 import static org.apache.commons.lang.ArrayUtils.toPrimitive;
 
 public class SolidFireUtil {
-    private static final Logger s_logger = Logger.getLogger(SolidFireUtil.class);
+    private static final Logger LOGGER = Logger.getLogger(SolidFireUtil.class);
 
     public static final String PROVIDER_NAME = "SolidFire";
     public static final String SHARED_PROVIDER_NAME = "SolidFireShared";
 
-    public static final int s_lockTimeInSeconds = 300;
+    private static final Random RANDOM = new Random(System.nanoTime());
+    public static final int LOCK_TIME_IN_SECONDS = 300;
 
     public static final String LOG_PREFIX = "SolidFire: ";
 
@@ -127,6 +132,8 @@
     public static final String DATASTORE_NAME = "datastoreName";
     public static final String IQN = "iqn";
 
+    private static final String SF_CS_ACCOUNT_PREFIX = "CloudStack_";
+
     public static final long MIN_VOLUME_SIZE = 1000000000;
 
     public static final long MIN_IOPS_PER_VOLUME = 100;
@@ -136,6 +143,9 @@
     private static final int DEFAULT_MANAGEMENT_PORT = 443;
     private static final int DEFAULT_STORAGE_PORT = 3260;
 
+    private static final int MAX_NUM_VAGS_PER_VOLUME = 4;
+    private static final int MAX_NUM_INITIATORS_PER_VAG = 64;
+
     public static class SolidFireConnection {
         private final String _managementVip;
         private final int _managementPort;
@@ -300,7 +310,7 @@ public static String getValue(String keyToMatch, String url, boolean throwExcept
     }
 
     public static String getSolidFireAccountName(String csAccountUuid, long csAccountId) {
-        return "CloudStack_" + csAccountUuid + "_" + csAccountId;
+        return SF_CS_ACCOUNT_PREFIX + csAccountUuid + "_" + csAccountId;
     }
 
     public static void updateCsDbWithSolidFireIopsInfo(long storagePoolId, PrimaryDataStoreDao primaryDataStoreDao,
@@ -344,17 +354,72 @@ public static SolidFireAccount getAccount(SolidFireConnection sfConnection, Stri
         }
     }
 
-    public static void hostAddedToOrRemovedFromCluster(long hostId, long clusterId, boolean added, String storageProvider,
-            ClusterDao clusterDao, ClusterDetailsDao clusterDetailsDao, PrimaryDataStoreDao storagePoolDao,
-            StoragePoolDetailsDao storagePoolDetailsDao, HostDao hostDao) {
+    private static boolean isCloudStackOnlyVag(SolidFireConnection sfConnection, SolidFireVag sfVag) {
+        long[] volumeIds = sfVag.getVolumeIds();
+
+        if (volumeIds == null || volumeIds.length == 0) {
+            // We count this situation as being "CloudStack only" because the reason we call this method is to determine
+            // if we can remove a host from a VAG (we only want to allow the host to be removed from the VAG if there are
+            // no non-CloudStack volumes in it).
+            return true;
+        }
+
+        List<Long> knownSfAccountsForCs = new ArrayList<>();
+
+        for (long volumeId : volumeIds) {
+            SolidFireVolume sfVolume = getVolume(sfConnection, volumeId);
+            long sfAccountId = sfVolume.getAccountId();
+
+            if (!knownSfAccountsForCs.contains(sfAccountId)) {
+                SolidFireAccount sfAccount = getAccountById(sfConnection, sfAccountId);
+
+                if (sfAccount.getName().startsWith(SF_CS_ACCOUNT_PREFIX)) {
+                    knownSfAccountsForCs.add(sfAccountId);
+                }
+                else {
+                    return false;
+                }
+            }
+        }
+
+        return true;
+    }
+
+    private static boolean isStorageApplicableToZoneOrCluster(StoragePoolVO storagePoolVO, long clusterId, ClusterDao clusterDao) {
+        if (storagePoolVO.getClusterId() != null) {
+            if (storagePoolVO.getClusterId() == clusterId) {
+                return true;
+            }
+        }
+        else {
+            List<ClusterVO> clustersInZone = clusterDao.listByZoneId(storagePoolVO.getDataCenterId());
+
+            if (clustersInZone != null) {
+                for (ClusterVO clusterInZone : clustersInZone) {
+                    if (clusterInZone.getId() == clusterId) {
+                        return true;
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+
+    public static void hostRemovedFromCluster(long hostId, long clusterId, String storageProvider, ClusterDao clusterDao, HostDao hostDao,
+                                              PrimaryDataStoreDao storagePoolDao, StoragePoolDetailsDao storagePoolDetailsDao) {
+        HostVO hostVO = hostDao.findByIdIncludingRemoved(hostId);
+
+        Preconditions.checkArgument(hostVO != null, "Could not locate host for ID: " + hostId);
+
         ClusterVO cluster = clusterDao.findById(clusterId);
 
         GlobalLock lock = GlobalLock.getInternLock(cluster.getUuid());
 
-        if (!lock.lock(s_lockTimeInSeconds)) {
+        if (!lock.lock(LOCK_TIME_IN_SECONDS)) {
             String errMsg = "Couldn't lock the DB on the following string: " + cluster.getUuid();
 
-            s_logger.debug(errMsg);
+            LOGGER.warn(errMsg);
 
             throw new CloudRuntimeException(errMsg);
         }
@@ -366,26 +431,72 @@ public static void hostAddedToOrRemovedFromCluster(long hostId, long clusterId,
                 List<SolidFireUtil.SolidFireConnection> sfConnections = new ArrayList<>();
 
                 for (StoragePoolVO storagePool : storagePools) {
-                    ClusterDetailsVO clusterDetail = clusterDetailsDao.findDetail(clusterId, SolidFireUtil.getVagKey(storagePool.getId()));
+                    if (!isStorageApplicableToZoneOrCluster(storagePool, clusterId, clusterDao)) {
+                        continue;
+                    }
+
+                    SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePool.getId(), storagePoolDetailsDao);
+
+                    if (!sfConnections.contains(sfConnection)) {
+                        sfConnections.add(sfConnection);
+
+                        List<SolidFireUtil.SolidFireVag> sfVags = SolidFireUtil.getAllVags(sfConnection);
+                        SolidFireVag sfVag = getVolumeAccessGroup(hostVO.getStorageUrl(), sfVags);
 
-                    String vagId = clusterDetail != null ? clusterDetail.getValue() : null;
+                        if (sfVag != null && isCloudStackOnlyVag(sfConnection, sfVag)) {
+                            removeInitiatorsFromSolidFireVag(sfConnection, sfVag.getId(), new String[] { hostVO.getStorageUrl() });
+                        }
+                    }
+                }
+            }
+        }
+        finally {
+            lock.unlock();
+            lock.releaseRef();
+        }
+    }
+
+    public static void hostAddedToCluster(long hostId, long clusterId, String storageProvider, ClusterDao clusterDao, HostDao hostDao,
+                                          PrimaryDataStoreDao storagePoolDao, StoragePoolDetailsDao storagePoolDetailsDao) {
+        HostVO hostVO = hostDao.findById(hostId);
+
+        Preconditions.checkArgument(hostVO != null, "Could not locate host for ID: " + hostId);
+
+        ClusterVO cluster = clusterDao.findById(clusterId);
+
+        GlobalLock lock = GlobalLock.getInternLock(cluster.getUuid());
 
-                    if (vagId != null) {
-                        SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePool.getId(), storagePoolDetailsDao);
+        if (!lock.lock(LOCK_TIME_IN_SECONDS)) {
+            String errMsg = "Couldn't lock the DB on the following string: " + cluster.getUuid();
+
+            LOGGER.warn(errMsg);
+
+            throw new CloudRuntimeException(errMsg);
+        }
+
+        try {
+            List<StoragePoolVO> storagePools = storagePoolDao.findPoolsByProvider(storageProvider);
 
-                        if (!sfConnections.contains(sfConnection)) {
-                            sfConnections.add(sfConnection);
+            if (storagePools != null && storagePools.size() > 0) {
+                List<SolidFireUtil.SolidFireConnection> sfConnections = new ArrayList<>();
 
-                            SolidFireUtil.SolidFireVag sfVag = SolidFireUtil.getVag(sfConnection, Long.parseLong(vagId));
+                for (StoragePoolVO storagePool : storagePools) {
+                    if (!isStorageApplicableToZoneOrCluster(storagePool, clusterId, clusterDao)) {
+                        continue;
+                    }
 
-                            List<HostVO> hostsToAddOrRemove = new ArrayList<>();
-                            HostVO hostToAddOrRemove = hostDao.findByIdIncludingRemoved(hostId);
+                    SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePool.getId(), storagePoolDetailsDao);
 
-                            hostsToAddOrRemove.add(hostToAddOrRemove);
+                    if (!sfConnections.contains(sfConnection)) {
+                        sfConnections.add(sfConnection);
 
-                            String[] hostIqns = SolidFireUtil.getNewHostIqns(sfVag.getInitiators(), SolidFireUtil.getIqnsFromHosts(hostsToAddOrRemove), added);
+                        List<SolidFireUtil.SolidFireVag> sfVags = SolidFireUtil.getAllVags(sfConnection);
+                        SolidFireVag sfVag = getVolumeAccessGroup(hostVO.getStorageUrl(), sfVags);
 
-                            SolidFireUtil.modifyVag(sfConnection, sfVag.getId(), hostIqns, sfVag.getVolumeIds());
+                        if (sfVag != null) {
+                            placeVolumeIdsInVag(sfConnection, sfVags, sfVag, hostVO, hostDao);
+                        } else {
+                            handleVagForHost(sfConnection, sfVags, hostVO, hostDao);
                         }
                     }
                 }
@@ -397,50 +508,283 @@ public static void hostAddedToOrRemovedFromCluster(long hostId, long clusterId,
         }
     }
 
-    public static long placeVolumeInVolumeAccessGroup(SolidFireConnection sfConnection, long sfVolumeId, long storagePoolId,
-                                                      String vagUuid, List<HostVO> hosts, ClusterDetailsDao clusterDetailsDao) {
-        if (hosts == null || hosts.isEmpty()) {
-            throw new CloudRuntimeException("There must be at least one host in the cluster.");
+    // Put the host in an existing VAG or create a new one (only create a new one if all existing VAGs are full (i.e. 64 hosts max per VAG) and if
+    // creating a new VAG won't exceed 4 VAGs for the computer cluster).
+    // If none of the hosts in the cluster are in a VAG, then leave this host out of a VAG.
+    // Place applicable volume IDs in VAG, if need be (account of volume starts with SF_CS_ACCOUNT_PREFIX).
+    private static void handleVagForHost(SolidFireUtil.SolidFireConnection sfConnection, List<SolidFireUtil.SolidFireVag> sfVags, Host host, HostDao hostDao) {
+        List<HostVO> hostVOs = hostDao.findByClusterId(host.getClusterId());
+
+        if (hostVOs != null) {
+            int numVags = 0;
+
+            Collections.shuffle(hostVOs, RANDOM);
+
+            for (HostVO hostVO : hostVOs) {
+                if (hostVO.getId() != host.getId()) {
+                    SolidFireVag sfVag = getVolumeAccessGroup(hostVO.getStorageUrl(), sfVags);
+
+                    if (sfVag != null) {
+                        numVags++;
+
+                        // A volume should be visible to all hosts that are in the same compute cluster. That being the case, you
+                        // can use MAX_NUM_VAGS_PER_VOLUME here. This is to limit the number of VAGs being used in a compute cluster
+                        // to MAX_NUM_VAGS_PER_VOLUME.
+                        if (numVags > MAX_NUM_VAGS_PER_VOLUME) {
+                            throw new CloudRuntimeException("Can support at most four volume access groups per compute cluster (>)");
+                        }
+
+                        if (sfVag.getInitiators().length < MAX_NUM_INITIATORS_PER_VAG) {
+                            if (!hostSupports_iScsi(host)) {
+                                String errMsg = "Host with ID " + host.getId() + " does not support iSCSI.";
+
+                                LOGGER.warn(errMsg);
+
+                                throw new CloudRuntimeException(errMsg);
+                            }
+
+                            addInitiatorsToSolidFireVag(sfConnection, sfVag.getId(), new String[] { host.getStorageUrl() });
+
+                            return;
+                        }
+                    }
+                }
+            }
+
+            if (numVags == MAX_NUM_VAGS_PER_VOLUME) {
+                throw new CloudRuntimeException("Can support at most four volume access groups per compute cluster (==)");
+            }
+
+            if (numVags > 0) {
+                if (!hostSupports_iScsi(host)) {
+                    String errMsg = "Host with ID " + host.getId() + " does not support iSCSI.";
+
+                    LOGGER.warn(errMsg);
+
+                    throw new CloudRuntimeException(errMsg);
+                }
+
+                SolidFireUtil.createVag(sfConnection, "CloudStack-" + UUID.randomUUID().toString(),
+                        new String[]{host.getStorageUrl()}, getVolumeIds(sfConnection, sfVags, host, hostDao));
+            }
         }
+    }
 
-        long lVagId;
+    // Make use of the volume access group (VAG) of a random host in the cluster. With this VAG, collect all of its volume IDs that are for
+    // volumes that are in SolidFire accounts that are for CloudStack.
+    private static long[] getVolumeIds(SolidFireUtil.SolidFireConnection sfConnection, List<SolidFireUtil.SolidFireVag> sfVags,
+                                       Host host, HostDao hostDao) {
+        List<Long> volumeIdsToReturn = new ArrayList<>();
 
-        try {
-            lVagId = SolidFireUtil.createVag(sfConnection, "CloudStack-" + vagUuid,
-                SolidFireUtil.getIqnsFromHosts(hosts), new long[] { sfVolumeId });
+        SolidFireVag sfVagForRandomHostInCluster = getVagForRandomHostInCluster(sfVags, host, hostDao);
+
+        if (sfVagForRandomHostInCluster != null) {
+            long[] volumeIds = sfVagForRandomHostInCluster.getVolumeIds();
+
+            if (volumeIds != null) {
+                List<Long> knownSfAccountsForCs = new ArrayList<>();
+                List<Long> knownSfAccountsNotForCs = new ArrayList<>();
+
+                for (long volumeId : volumeIds) {
+                    SolidFireVolume sfVolume = getVolume(sfConnection, volumeId);
+                    long sfAccountId = sfVolume.getAccountId();
+
+                    if (knownSfAccountsForCs.contains(sfAccountId)) {
+                        volumeIdsToReturn.add(volumeId);
+                    }
+                    else if (!knownSfAccountsNotForCs.contains(sfAccountId)) {
+                        SolidFireAccount sfAccount = getAccountById(sfConnection, sfAccountId);
+
+                        if (sfAccount.getName().startsWith(SF_CS_ACCOUNT_PREFIX)) {
+                            knownSfAccountsForCs.add(sfAccountId);
+
+                            volumeIdsToReturn.add(volumeId);
+                        }
+                        else {
+                            knownSfAccountsNotForCs.add(sfAccountId);
+                        }
+                    }
+                }
+            }
         }
-        catch (Exception ex) {
-            String iqnInVagAlready1 = "Exceeded maximum number of Volume Access Groups per initiator";
-            String iqnInVagAlready2 = "Exceeded maximum number of VolumeAccessGroups per Initiator";
 
-            if (!ex.getMessage().contains(iqnInVagAlready1) && !ex.getMessage().contains(iqnInVagAlready2)) {
-                throw new CloudRuntimeException(ex.getMessage());
+        return volumeIdsToReturn.stream().mapToLong(l -> l).toArray();
+    }
+
+    private static void placeVolumeIdsInVag(SolidFireUtil.SolidFireConnection sfConnection, List<SolidFireUtil.SolidFireVag> sfVags,
+                                            SolidFireVag sfVag, Host host, HostDao hostDao) {
+        SolidFireVag sfVagForRandomHostInCluster = getVagForRandomHostInCluster(sfVags, host, hostDao);
+
+        if (sfVagForRandomHostInCluster != null) {
+            long[] volumeIds = sfVagForRandomHostInCluster.getVolumeIds();
+
+            if (volumeIds != null) {
+                List<Long> knownSfAccountsForCs = new ArrayList<>();
+                List<Long> knownSfAccountsNotForCs = new ArrayList<>();
+
+                List<Long> newVolumeIds = new ArrayList<>();
+
+                for (long volumeId : volumeIds) {
+                    SolidFireVolume sfVolume = getVolume(sfConnection, volumeId);
+                    long sfAccountId = sfVolume.getAccountId();
+
+                    if (knownSfAccountsForCs.contains(sfAccountId)) {
+                        addVolumeIdToSolidFireVag(volumeId, sfVag, newVolumeIds);
+                    }
+                    else if (!knownSfAccountsNotForCs.contains(sfAccountId)) {
+                        SolidFireAccount sfAccount = getAccountById(sfConnection, sfAccountId);
+
+                        if (sfAccount.getName().startsWith(SF_CS_ACCOUNT_PREFIX)) {
+                            knownSfAccountsForCs.add(sfAccountId);
+
+                            addVolumeIdToSolidFireVag(volumeId, sfVag, newVolumeIds);
+                        }
+                        else {
+                            knownSfAccountsNotForCs.add(sfAccountId);
+                        }
+                    }
+                }
+
+                if (newVolumeIds.size() > 0) {
+                    addVolumeIdsToSolidFireVag(sfConnection, sfVag.getId(), newVolumeIds.toArray(new Long[0]));
+                }
             }
+        }
+    }
+
+    private static void addVolumeIdToSolidFireVag(long volumeId, SolidFireVag sfVag, List<Long> newVolumeIds) {
+        List<Long> existingVolumeIds = Longs.asList(sfVag.getVolumeIds());
 
-            // getCompatibleVag throws an exception if an existing VAG can't be located
-            SolidFireUtil.SolidFireVag sfVag = getCompatibleVag(sfConnection, hosts);
+        if (!existingVolumeIds.contains(volumeId) && !newVolumeIds.contains(volumeId)) {
+            newVolumeIds.add(volumeId);
+        }
+    }
 
-            lVagId = sfVag.getId();
+    private static SolidFireVag getVagForRandomHostInCluster(List<SolidFireUtil.SolidFireVag> sfVags, Host host, HostDao hostDao) {
+        List<HostVO> hostVOs = hostDao.findByClusterId(host.getClusterId());
 
-            long[] volumeIds = getNewVolumeIds(sfVag.getVolumeIds(), sfVolumeId, true);
+        if (hostVOs != null) {
+            Collections.shuffle(hostVOs, RANDOM);
 
-            SolidFireUtil.modifyVag(sfConnection, lVagId, sfVag.getInitiators(), volumeIds);
+            for (HostVO hostVO : hostVOs) {
+                if (hostVO.getId() != host.getId() && hostSupports_iScsi(hostVO)) {
+                    SolidFireVag sfVag = getVolumeAccessGroup(hostVO.getStorageUrl(), sfVags);
+
+                    if (sfVag != null) {
+                        return sfVag;
+                    }
+                }
+            }
         }
 
-        ClusterDetailsVO clusterDetail = new ClusterDetailsVO(hosts.get(0).getClusterId(), getVagKey(storagePoolId), String.valueOf(lVagId));
+        return null;
+    }
+
+    public static void placeVolumeInVolumeAccessGroups(SolidFireConnection sfConnection, long sfVolumeId, List<HostVO> hosts) {
+        if (!SolidFireUtil.hostsSupport_iScsi(hosts)) {
+            String errMsg = "Not all hosts in the compute cluster support iSCSI.";
+
+            LOGGER.warn(errMsg);
 
-        clusterDetailsDao.persist(clusterDetail);
+            throw new CloudRuntimeException(errMsg);
+        }
 
-        return lVagId;
+        List<SolidFireUtil.SolidFireVag> sfVags = SolidFireUtil.getAllVags(sfConnection);
+
+        Map<SolidFireUtil.SolidFireVag, List<String>> sfVagToIqnsMap = new HashMap<>();
+
+        for (HostVO hostVO : hosts) {
+            String iqn = hostVO.getStorageUrl();
+
+            SolidFireUtil.SolidFireVag sfVag = getVolumeAccessGroup(iqn, sfVags);
+
+            List<String> iqnsInVag = sfVagToIqnsMap.computeIfAbsent(sfVag, k -> new ArrayList<>());
+
+            iqnsInVag.add(iqn);
+        }
+
+        if (sfVagToIqnsMap.size() > MAX_NUM_VAGS_PER_VOLUME) {
+            throw new CloudRuntimeException("A SolidFire volume can be in at most four volume access groups simultaneously.");
+        }
+
+        for (SolidFireUtil.SolidFireVag sfVag : sfVagToIqnsMap.keySet()) {
+            if (sfVag != null) {
+                if (!SolidFireUtil.isVolumeIdInSfVag(sfVolumeId, sfVag)) {
+                    SolidFireUtil.addVolumeIdsToSolidFireVag(sfConnection, sfVag.getId(), new Long[] { sfVolumeId });
+                }
+            }
+            else {
+                List<String> iqnsNotInVag = sfVagToIqnsMap.get(null);
+
+                SolidFireUtil.createVag(sfConnection, "CloudStack-" + UUID.randomUUID().toString(),
+                        iqnsNotInVag.toArray(new String[0]), new long[] { sfVolumeId });
+            }
+        }
+    }
+
+    private static SolidFireUtil.SolidFireVag getVolumeAccessGroup(String hostIqn, List<SolidFireUtil.SolidFireVag> sfVags) {
+        if (hostIqn == null) {
+            return null;
+        }
+
+        hostIqn = hostIqn.toLowerCase();
+
+        if (sfVags != null) {
+            for (SolidFireUtil.SolidFireVag sfVag : sfVags) {
+                List<String> lstInitiators = getStringArrayAsLowerCaseStringList(sfVag.getInitiators());
+
+                // lstInitiators should not be returned from getStringArrayAsLowerCaseStringList as null
+                if (lstInitiators.contains(hostIqn)) {
+                    return sfVag;
+                }
+            }
+        }
+
+        return null;
     }
 
-    public static boolean hostsSupport_iScsi(List<HostVO> hosts) {
+    public static boolean sfVagContains(SolidFireUtil.SolidFireVag sfVag, long sfVolumeId, long clusterId, HostDao hostDao) {
+        if (isVolumeIdInSfVag(sfVolumeId, sfVag)) {
+            String[] iqns = sfVag.getInitiators();
+            List<HostVO> hosts = hostDao.findByClusterId(clusterId);
+
+            for (String iqn : iqns) {
+                for (HostVO host : hosts) {
+                    String hostIqn = host.getStorageUrl();
+
+                    if (iqn.equalsIgnoreCase(hostIqn)) {
+                        return true;
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+
+    private static boolean isVolumeIdInSfVag(long sfVolumeIdToCheck, SolidFireUtil.SolidFireVag sfVag) {
+        long[] sfVolumeIds = sfVag.getVolumeIds();
+
+        for (long sfVolumeId : sfVolumeIds) {
+            if (sfVolumeId == sfVolumeIdToCheck) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    private static boolean hostSupports_iScsi(Host host) {
+        return host != null && host.getStorageUrl() != null && host.getStorageUrl().trim().length() > 0 && host.getStorageUrl().startsWith("iqn");
+    }
+
+    private static boolean hostsSupport_iScsi(List<HostVO> hosts) {
         if (hosts == null || hosts.size() == 0) {
             return false;
         }
 
         for (Host host : hosts) {
-            if (host == null || host.getStorageUrl() == null || host.getStorageUrl().trim().length() == 0 || !host.getStorageUrl().startsWith("iqn")) {
+            if (!hostSupports_iScsi(host)) {
                 return false;
             }
         }
@@ -448,14 +792,6 @@ public static boolean hostsSupport_iScsi(List<HostVO> hosts) {
         return true;
     }
 
-    public static long[] getNewVolumeIds(long[] volumeIds, long volumeIdToAddOrRemove, boolean add) {
-        if (add) {
-            return getNewVolumeIdsAdd(volumeIds, volumeIdToAddOrRemove);
-        }
-
-        return getNewVolumeIdsRemove(volumeIds, volumeIdToAddOrRemove);
-    }
-
     public static String getVagKey(long storagePoolId) {
         return "sfVolumeAccessGroup_" + storagePoolId;
     }
@@ -851,32 +1187,43 @@ private static long createVag(SolidFireConnection sfConnection, String vagName,
         return getSolidFireElement(sfConnection).createVolumeAccessGroup(request).getVolumeAccessGroupID();
     }
 
-    public static void modifyVag(SolidFireConnection sfConnection, long vagId, String[] iqns, long[] volumeIds) {
-        ModifyVolumeAccessGroupRequest request = ModifyVolumeAccessGroupRequest.builder()
+    private static void addInitiatorsToSolidFireVag(SolidFireConnection sfConnection, long vagId, String[] initiators) {
+        AddInitiatorsToVolumeAccessGroupRequest request = AddInitiatorsToVolumeAccessGroupRequest.builder()
                 .volumeAccessGroupID(vagId)
-                .optionalInitiators(iqns)
-                .optionalVolumes(Longs.asList(volumeIds).toArray(new Long[volumeIds.length]))
+                .initiators(initiators)
                 .build();
 
-        getSolidFireElement(sfConnection).modifyVolumeAccessGroup(request);
+        getSolidFireElement(sfConnection).addInitiatorsToVolumeAccessGroup(request);
     }
 
-    public static SolidFireVag getVag(SolidFireConnection sfConnection, long vagId)
-    {
-        ListVolumeAccessGroupsRequest request = ListVolumeAccessGroupsRequest.builder()
-                .optionalStartVolumeAccessGroupID(vagId)
-                .optionalLimit(1L)
+    private static void removeInitiatorsFromSolidFireVag(SolidFireConnection sfConnection, long vagId, String[] initiators) {
+        RemoveInitiatorsFromVolumeAccessGroupRequest request = RemoveInitiatorsFromVolumeAccessGroupRequest.builder()
+                .volumeAccessGroupID(vagId)
+                .initiators(initiators)
                 .build();
 
-        VolumeAccessGroup vag = getSolidFireElement(sfConnection).listVolumeAccessGroups(request).getVolumeAccessGroups()[0];
+        getSolidFireElement(sfConnection).removeInitiatorsFromVolumeAccessGroup(request);
+    }
 
-        String[] vagIqns = vag.getInitiators();
-        long[] vagVolumeIds = toPrimitive(vag.getVolumes());
+    private static void addVolumeIdsToSolidFireVag(SolidFireConnection sfConnection, long vagId, Long[] volumeIds) {
+        AddVolumesToVolumeAccessGroupRequest request = AddVolumesToVolumeAccessGroupRequest.builder()
+                .volumeAccessGroupID(vagId)
+                .volumes(volumeIds)
+                .build();
 
-        return new SolidFireVag(vagId, vagIqns, vagVolumeIds);
+        getSolidFireElement(sfConnection).addVolumesToVolumeAccessGroup(request);
     }
 
-    private static List<SolidFireVag> getAllVags(SolidFireConnection sfConnection)
+    public static void removeVolumeIdsFromSolidFireVag(SolidFireConnection sfConnection, long vagId, Long[] volumeIds) {
+        RemoveVolumesFromVolumeAccessGroupRequest request = RemoveVolumesFromVolumeAccessGroupRequest.builder()
+                .volumeAccessGroupID(vagId)
+                .volumes(volumeIds)
+                .build();
+
+        getSolidFireElement(sfConnection).removeVolumesFromVolumeAccessGroup(request);
+    }
+
+    public static List<SolidFireVag> getAllVags(SolidFireConnection sfConnection)
     {
         ListVolumeAccessGroupsRequest request = ListVolumeAccessGroupsRequest.builder().build();
 
@@ -980,113 +1327,6 @@ private static int getPort(String keyToMatch, String url, int defaultPortNumber)
         return portNumber;
     }
 
-    private static String[] getNewHostIqns(String[] iqns, String[] iqnsToAddOrRemove, boolean add) {
-        if (add) {
-            return getNewHostIqnsAdd(iqns, iqnsToAddOrRemove);
-        }
-
-        return getNewHostIqnsRemove(iqns, iqnsToAddOrRemove);
-    }
-
-    private static String[] getNewHostIqnsAdd(String[] iqns, String[] iqnsToAdd) {
-        List<String> lstIqns = iqns != null ? new ArrayList<>(Arrays.asList(iqns)) : new ArrayList<String>();
-
-        if (iqnsToAdd != null) {
-            for (String iqnToAdd : iqnsToAdd) {
-                if (!lstIqns.contains(iqnToAdd)) {
-                    lstIqns.add(iqnToAdd);
-                }
-            }
-        }
-
-        return lstIqns.toArray(new String[0]);
-    }
-
-    private static String[] getNewHostIqnsRemove(String[] iqns, String[] iqnsToRemove) {
-        List<String> lstIqns = iqns != null ? new ArrayList<>(Arrays.asList(iqns)) : new ArrayList<String>();
-
-        if (iqnsToRemove != null) {
-            for (String iqnToRemove : iqnsToRemove) {
-                lstIqns.remove(iqnToRemove);
-            }
-        }
-
-        return lstIqns.toArray(new String[0]);
-    }
-
-    private static long[] getNewVolumeIdsAdd(long[] volumeIds, long volumeIdToAdd) {
-        List<Long> lstVolumeIds = new ArrayList<>();
-
-        if (volumeIds != null) {
-            for (long volumeId : volumeIds) {
-                lstVolumeIds.add(volumeId);
-            }
-        }
-
-        if (lstVolumeIds.contains(volumeIdToAdd)) {
-            return volumeIds;
-        }
-
-        lstVolumeIds.add(volumeIdToAdd);
-
-        return toPrimitive(lstVolumeIds.toArray(new Long[lstVolumeIds.size()]));
-    }
-
-    private static long[] getNewVolumeIdsRemove(long[] volumeIds, long volumeIdToRemove) {
-        List<Long> lstVolumeIds = new ArrayList<>();
-
-        if (volumeIds != null) {
-            for (long volumeId : volumeIds) {
-                lstVolumeIds.add(volumeId);
-            }
-        }
-
-        lstVolumeIds.remove(volumeIdToRemove);
-
-        return toPrimitive(lstVolumeIds.toArray(new Long[lstVolumeIds.size()]));
-    }
-
-    private static String[] getIqnsFromHosts(List<? extends Host> hosts) {
-        if (hosts == null || hosts.size() == 0) {
-            throw new CloudRuntimeException("There do not appear to be any hosts in this cluster.");
-        }
-
-        List<String> lstIqns = new ArrayList<>();
-
-        for (Host host : hosts) {
-            lstIqns.add(host.getStorageUrl());
-        }
-
-        return lstIqns.toArray(new String[0]);
-    }
-
-    // this method takes in a collection of hosts and tries to find an existing VAG that has all of them in it
-    // if successful, the VAG is returned; else, a CloudRuntimeException is thrown and this issue should be corrected by an admin
-    private static SolidFireUtil.SolidFireVag getCompatibleVag(SolidFireConnection sfConnection, List<HostVO> hosts) {
-        List<SolidFireUtil.SolidFireVag> sfVags = SolidFireUtil.getAllVags(sfConnection);
-
-        if (sfVags != null) {
-            List<String> hostIqns = new ArrayList<>();
-
-            // where the method we're in is called, hosts should not be null
-            for (HostVO host : hosts) {
-                // where the method we're in is called, host.getStorageUrl() should not be null (it actually should start with "iqn")
-                hostIqns.add(host.getStorageUrl().toLowerCase());
-            }
-
-            for (SolidFireUtil.SolidFireVag sfVag : sfVags) {
-                List<String> lstInitiators = getStringArrayAsLowerCaseStringList(sfVag.getInitiators());
-
-                // lstInitiators should not be returned from getStringArrayAsLowerCaseStringList as null
-                if (lstInitiators.containsAll(hostIqns)) {
-                    return sfVag;
-                }
-            }
-        }
-
-        throw new CloudRuntimeException("Unable to locate the appropriate SolidFire Volume Access Group");
-    }
-
     private static List<String> getStringArrayAsLowerCaseStringList(String[] aString) {
         List<String> lstLowerCaseString = new ArrayList<>();
 
@@ -1106,10 +1346,6 @@ private static int getPort(String keyToMatch, String url, int defaultPortNumber)
             return null;
         }
 
-        Map<String, Object> convertedMap = new HashMap<>();
-
-        convertedMap.putAll(map);
-
-        return convertedMap;
+        return new HashMap<>(map);
     }
 }


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services