This is an automated email from the ASF dual-hosted git repository.
mtutkowski pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cloudstack.git
The following commit(s) were added to refs/heads/master by this push:
new 8dd6cef create Volume Access Groups per cluster instead of
CloudStack-RandomUUID() (#3794)
8dd6cef is described below
commit 8dd6cef9a6d395a2b8d876e358077bd150cdc9f1
Author: Sid Kattoju <[email protected]>
AuthorDate: Tue Jun 2 14:58:20 2020 -0400
create Volume Access Groups per cluster instead of CloudStack-RandomUUID()
(#3794)
* create vags per cluster
* vagname in solidfire utils vag object
* fix string compare
* refactor to make use of existing map
* fix typos
* rebuild vag to iqn map after creating cluster vag
* refactor loop using java 8 stream api
* update null entry in vag to iqn map
* remove null vag to iqn mapping when creating cluster id vag
* add initiator to sf vag when adding hosts
* use cluster uuid instead of cluster id and refactor
* update null entry in vagtoiqnmap
* update sfvag list after creating new vag
* pass clusterDao to handleVagForHost
* check if initiator is not already added to the vag
* factor logic into methods
* fix typo and camel case
* fix listing clusters by zone id
Co-authored-by: Sid Kattoju <[email protected]>
---
.../driver/SolidFirePrimaryDataStoreDriver.java | 4 +-
.../SolidFireSharedPrimaryDataStoreLifeCycle.java | 4 +-
.../storage/datastore/util/SolidFireUtil.java | 104 +++++++++++++++------
3 files changed, 83 insertions(+), 29 deletions(-)
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 aa277cd..22e4e95 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
@@ -172,9 +172,11 @@ public class SolidFirePrimaryDataStoreDriver implements
PrimaryDataStoreDriver {
try {
List<HostVO> hosts = hostDao.findByClusterId(clusterId);
+ String clusterUuId = clusterDao.findById(clusterId).getUuid();
+
SolidFireUtil.SolidFireConnection sfConnection =
SolidFireUtil.getSolidFireConnection(storagePoolId, storagePoolDetailsDao);
- SolidFireUtil.placeVolumeInVolumeAccessGroups(sfConnection,
sfVolumeId, hosts);
+ SolidFireUtil.placeVolumeInVolumeAccessGroups(sfConnection,
sfVolumeId, hosts, clusterUuId);
return true;
}
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 2ebd69a..9cc746d 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
@@ -285,7 +285,9 @@ public class SolidFireSharedPrimaryDataStoreLifeCycle
implements PrimaryDataStor
// place the newly created volume in the Volume Access Group
List<HostVO> hosts = hostDao.findByClusterId(clusterId);
- SolidFireUtil.placeVolumeInVolumeAccessGroups(sfConnection,
sfVolume.getId(), hosts);
+ String clusterUuId = clusterDao.findById(clusterId).getUuid();
+
+ SolidFireUtil.placeVolumeInVolumeAccessGroups(sfConnection,
sfVolume.getId(), hosts, clusterUuId);
SolidFireUtil.SolidFireAccount sfAccount =
sfCreateVolume.getAccount();
Account csAccount = CallContext.current().getCallingAccount();
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 9f7b205..acf1d5c 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
@@ -393,7 +393,7 @@ public class SolidFireUtil {
}
}
else {
- List<ClusterVO> clustersInZone =
clusterDao.listByZoneId(storagePoolVO.getDataCenterId());
+ List<ClusterVO> clustersInZone =
clusterDao.listClustersByDcId(storagePoolVO.getDataCenterId());
if (clustersInZone != null) {
for (ClusterVO clusterInZone : clustersInZone) {
@@ -497,7 +497,7 @@ public class SolidFireUtil {
if (sfVag != null) {
placeVolumeIdsInVag(sfConnection, sfVags, sfVag,
hostVO, hostDao);
} else {
- handleVagForHost(sfConnection, sfVags, hostVO,
hostDao);
+ handleVagForHost(sfConnection, sfVags, hostVO,
hostDao, clusterDao);
}
}
}
@@ -513,12 +513,14 @@ public class SolidFireUtil {
// 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) {
+ private static void handleVagForHost(SolidFireUtil.SolidFireConnection
sfConnection, List<SolidFireUtil.SolidFireVag> sfVags, Host host, HostDao
hostDao, ClusterDao clusterDao) {
List<HostVO> hostVOs = hostDao.findByClusterId(host.getClusterId());
if (hostVOs != null) {
int numVags = 0;
+ addInitiatorsToExistingVag(clusterDao, host, sfVags, sfConnection);
+
Collections.shuffle(hostVOs, RANDOM);
for (HostVO hostVO : hostVOs) {
@@ -544,8 +546,9 @@ public class SolidFireUtil {
throw new CloudRuntimeException(errMsg);
}
- addInitiatorsToSolidFireVag(sfConnection,
sfVag.getId(), new String[] { host.getStorageUrl() });
-
+
if(!isInitiatorInSfVag(host.getStorageUrl(),sfVag)) {
+ addInitiatorsToSolidFireVag(sfConnection,
sfVag.getId(), new String[]{host.getStorageUrl()});
+ }
return;
}
}
@@ -571,6 +574,14 @@ public class SolidFireUtil {
}
}
+ private static void addInitiatorsToExistingVag(ClusterDao clusterDao, Host
host, List<SolidFireUtil.SolidFireVag> sfVags,
SolidFireUtil.SolidFireConnection sfConnection){
+ String clusterUuId =
clusterDao.findById(host.getClusterId()).getUuid();
+ SolidFireVag sfVagMatchingClusterId = sfVags.stream().filter(vag ->
vag.getName().equals("CloudStack-"+clusterUuId)).findFirst().orElse(null);
+ if (sfVagMatchingClusterId != null &&
sfVagMatchingClusterId.getInitiators().length < MAX_NUM_INITIATORS_PER_VAG) {
+ addInitiatorsToSolidFireVag(sfConnection,
sfVagMatchingClusterId.getId(), new String[]{host.getStorageUrl()});
+ }
+ }
+
/**
* 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.
@@ -683,7 +694,7 @@ public class SolidFireUtil {
return null;
}
- public static void placeVolumeInVolumeAccessGroups(SolidFireConnection
sfConnection, long sfVolumeId, List<HostVO> hosts) {
+ public static void placeVolumeInVolumeAccessGroups(SolidFireConnection
sfConnection, long sfVolumeId, List<HostVO> hosts, String clusterUuId) {
if (!SolidFireUtil.hostsSupport_iScsi(hosts)) {
String errMsg = "Not all hosts in the compute cluster support
iSCSI.";
@@ -691,11 +702,50 @@ public class SolidFireUtil {
throw new CloudRuntimeException(errMsg);
}
-
List<SolidFireUtil.SolidFireVag> sfVags =
SolidFireUtil.getAllVags(sfConnection);
+ Map<SolidFireUtil.SolidFireVag, List<String>> sfVagToIqnsMap =
buildVagToIQNMap(hosts, sfVags);
+ if (sfVagToIqnsMap.size() > MAX_NUM_VAGS_PER_VOLUME) {
+ throw new CloudRuntimeException("A SolidFire volume can be in at
most four volume access groups simultaneously.");
+ }
+ if (sfVagToIqnsMap.containsKey(null)) {
+ sfVagToIqnsMap = updateNullKeyInSfVagToIqnsMap(sfVagToIqnsMap,
sfVags, sfConnection, clusterUuId, sfVolumeId);
+ }
+ addVolumestoVagIfNotPresent(sfVagToIqnsMap.keySet(), sfVolumeId,
sfConnection);
+ }
- Map<SolidFireUtil.SolidFireVag, List<String>> sfVagToIqnsMap = new
HashMap<>();
+ private static Map<SolidFireUtil.SolidFireVag, List<String>>
updateNullKeyInSfVagToIqnsMap(Map<SolidFireUtil.SolidFireVag,List<String>>
sfVagToIqnsMap, List <SolidFireUtil.SolidFireVag> sfVags, SolidFireConnection
sfConnection, String clusterUuId, long sfVolumeId){
+ SolidFireUtil.SolidFireVag sfVagMatchingClusterId =
createClusterVagIfDoesntExist(sfVags, sfConnection, clusterUuId,
sfVagToIqnsMap, sfVolumeId);
+ sfVagToIqnsMap.put(sfVagMatchingClusterId, sfVagToIqnsMap.get(null));
+ sfVagToIqnsMap.remove(null);
+ return sfVagToIqnsMap;
+ }
+
+ private static SolidFireVag
createClusterVagIfDoesntExist(List<SolidFireUtil.SolidFireVag> sfVags,
SolidFireConnection sfConnection, String clusterUuId,
Map<SolidFireUtil.SolidFireVag, List<String>> sfVagToIqnsMap, long sfVolumeId) {
+ SolidFireVag sfVagMatchingClusterId = sfVags.stream().filter(vag ->
vag.getName().equals("CloudStack-" + clusterUuId)).findFirst().orElse(null);
+ if (sfVagMatchingClusterId == null) {
+ LOGGER.info("Creating volume access group CloudStack-" +
clusterUuId);
+ SolidFireUtil.createVag(sfConnection, "CloudStack-" + clusterUuId,
sfVagToIqnsMap.get(null).toArray(new String[0]), new long[]{sfVolumeId});
+ sfVags = SolidFireUtil.getAllVags(sfConnection);
+ return sfVags.stream().filter(vag ->
vag.getName().equals("CloudStack-" + clusterUuId)).findFirst().orElse(null);
+ }else{
+ return sfVagMatchingClusterId;
+ }
+ }
+
+ private static void
addVolumestoVagIfNotPresent(Set<SolidFireUtil.SolidFireVag> sfVagSet, long
sfVolumeId, SolidFireConnection sfConnection){
+ for (SolidFireUtil.SolidFireVag sfVag : sfVagSet) {
+ if (sfVag != null) {
+ if (!SolidFireUtil.isVolumeIdInSfVag(sfVolumeId, sfVag)) {
+ SolidFireUtil.addVolumeIdsToSolidFireVag(sfConnection,
sfVag.getId(), new Long[] { sfVolumeId });
+ }
+ }
+ }
+ }
+
+ private static Map<SolidFireVag,List<String>>
buildVagToIQNMap(List<HostVO> hosts, List<SolidFireVag> sfVags) {
+
+ Map<SolidFireUtil.SolidFireVag, List<String>> sfVagToIqnsMap = new
HashMap<>();
for (HostVO hostVO : hosts) {
String iqn = hostVO.getStorageUrl();
@@ -705,24 +755,8 @@ public class SolidFireUtil {
iqnsInVag.add(iqn);
}
+ return sfVagToIqnsMap;
- 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 });
- }
- }
}
public static SolidFireUtil.SolidFireVag getVolumeAccessGroup(String
hostIqn, List<SolidFireUtil.SolidFireVag> sfVags) {
@@ -777,6 +811,18 @@ public class SolidFireUtil {
return false;
}
+ private static boolean isInitiatorInSfVag(String initiatorName,
SolidFireUtil.SolidFireVag sfVag) {
+ String[] initiatorsList = sfVag.getInitiators();
+
+ for (String initiator : initiatorsList) {
+ if (initiatorName.equals(initiator)) {
+ 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");
}
@@ -1245,7 +1291,7 @@ public class SolidFireUtil {
if (vags != null) {
for (VolumeAccessGroup vag : vags) {
- SolidFireVag sfVag = new
SolidFireVag(vag.getVolumeAccessGroupID(), vag.getInitiators(),
toPrimitive(vag.getVolumes()));
+ SolidFireVag sfVag = new
SolidFireVag(vag.getVolumeAccessGroupID(), vag.getInitiators(),
toPrimitive(vag.getVolumes()), vag.getName());
lstSolidFireVags.add(sfVag);
}
@@ -1258,11 +1304,13 @@ public class SolidFireUtil {
private final long _id;
private final String[] _initiators;
private final long[] _volumeIds;
+ private final String _vagName;
- SolidFireVag(long id, String[] initiators, long[] volumeIds) {
+ SolidFireVag(long id, String[] initiators, long[] volumeIds, String
name) {
_id = id;
_initiators = initiators;
_volumeIds = volumeIds;
+ _vagName = name;
}
public long getId() {
@@ -1277,6 +1325,8 @@ public class SolidFireUtil {
return _volumeIds;
}
+ public String getName() { return _vagName; }
+
@Override
public int hashCode() {
return String.valueOf(_id).hashCode();