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:
[email protected]


With regards,
Apache Git Services

Reply via email to