You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by mt...@apache.org on 2014/01/10 07:37:13 UTC
git commit: updated refs/heads/master to 68fda5a
Updated Branches:
refs/heads/master a354d969c -> 68fda5a8d
Merge from 4.3: CLOUDSTACK-4810: Enable hypervisor snapshots for CloudStack-managed storage (for XenServer and VMware)
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/68fda5a8
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/68fda5a8
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/68fda5a8
Branch: refs/heads/master
Commit: 68fda5a8ddaa7817277ac740b1e4b6986dc710a8
Parents: a354d96
Author: Mike Tutkowski <mi...@solidfire.com>
Authored: Thu Jan 9 23:36:36 2014 -0700
Committer: Mike Tutkowski <mi...@solidfire.com>
Committed: Thu Jan 9 23:36:36 2014 -0700
----------------------------------------------------------------------
.../driver/SolidfirePrimaryDataStoreDriver.java | 96 +++++++++++++++++++-
.../storage/datastore/util/SolidFireUtil.java | 60 ++++++++++--
2 files changed, 143 insertions(+), 13 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/68fda5a8/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java
----------------------------------------------------------------------
diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java
index 1212b60..7d305e0 100644
--- a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java
+++ b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java
@@ -272,16 +272,39 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
SolidFireUtil.SolidFireVag sfVag = SolidFireUtil.getSolidFireVag(sfConnection.getManagementVip(), sfConnection.getManagementPort(),
sfConnection.getClusterAdminUsername(), sfConnection.getClusterAdminPassword(), Long.parseLong(vagId));
+ String[] hostIqns = getNewHostIqns(sfVag.getInitiators(), getIqnsFromHosts(hosts));
long[] volumeIds = getNewVolumeIds(sfVag.getVolumeIds(), sfVolumeId, true);
SolidFireUtil.modifySolidFireVag(sfConnection.getManagementVip(), sfConnection.getManagementPort(),
sfConnection.getClusterAdminUsername(), sfConnection.getClusterAdminPassword(), sfVag.getId(),
- getIqnsFromHosts(hosts), volumeIds);
+ hostIqns, volumeIds);
}
else {
- long lVagId = SolidFireUtil.createSolidFireVag(sfConnection.getManagementVip(), sfConnection.getManagementPort(),
- sfConnection.getClusterAdminUsername(), sfConnection.getClusterAdminPassword(), "CloudStack-" + UUID.randomUUID().toString(),
- getIqnsFromHosts(hosts), new long[] { sfVolumeId });
+ long lVagId;
+
+ try {
+ lVagId = SolidFireUtil.createSolidFireVag(sfConnection.getManagementVip(), sfConnection.getManagementPort(),
+ sfConnection.getClusterAdminUsername(), sfConnection.getClusterAdminPassword(), "CloudStack-" + UUID.randomUUID().toString(),
+ getIqnsFromHosts(hosts), new long[] { sfVolumeId });
+ }
+ catch (Exception ex) {
+ String iqnInVagAlready = "Exceeded maximum number of Volume Access Groups per initiator";
+
+ if (!ex.getMessage().contains(iqnInVagAlready)) {
+ throw new CloudRuntimeException(ex.getMessage());
+ }
+
+ // getCompatibleVag throws an exception if an existing VAG can't be located
+ SolidFireUtil.SolidFireVag sfVag = getCompatibleVag(hosts, sfConnection);
+
+ long[] volumeIds = getNewVolumeIds(sfVag.getVolumeIds(), sfVolumeId, true);
+
+ SolidFireUtil.modifySolidFireVag(sfConnection.getManagementVip(), sfConnection.getManagementPort(),
+ sfConnection.getClusterAdminUsername(), sfConnection.getClusterAdminPassword(), sfVag.getId(),
+ sfVag.getInitiators(), volumeIds);
+
+ lVagId = sfVag.getId();
+ }
clusterDetail = new ClusterDetailsVO(clusterId, getVagKey(storagePoolId), String.valueOf(lVagId));
@@ -291,6 +314,48 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
return true;
}
+ // this method takes in a collection of hosts and tries to find an existing VAG that has all three 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 SolidFireUtil.SolidFireVag getCompatibleVag(List<HostVO> hosts, SolidFireConnection sfConnection) {
+ List<SolidFireUtil.SolidFireVag> sfVags = SolidFireUtil.getAllSolidFireVags(sfConnection.getManagementVip(), sfConnection.getManagementPort(),
+ sfConnection.getClusterAdminUsername(), sfConnection.getClusterAdminPassword());
+
+ if (sfVags != null) {
+ List<String> hostIqns = new ArrayList<String>();
+
+ // 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 List<String> getStringArrayAsLowerCaseStringList(String[] aString) {
+ List<String> lstLowerCaseString = new ArrayList<String>();
+
+ if (aString != null) {
+ for (String str : aString) {
+ if (str != null) {
+ lstLowerCaseString.add(str.toLowerCase());
+ }
+ }
+ }
+
+ return lstLowerCaseString;
+ }
+
// 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)
@@ -317,11 +382,12 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
SolidFireUtil.SolidFireVag sfVag = SolidFireUtil.getSolidFireVag(sfConnection.getManagementVip(), sfConnection.getManagementPort(),
sfConnection.getClusterAdminUsername(), sfConnection.getClusterAdminPassword(), Long.parseLong(vagId));
+ String[] hostIqns = getNewHostIqns(sfVag.getInitiators(), getIqnsFromHosts(hosts));
long[] volumeIds = getNewVolumeIds(sfVag.getVolumeIds(), sfVolumeId, false);
SolidFireUtil.modifySolidFireVag(sfConnection.getManagementVip(), sfConnection.getManagementPort(),
sfConnection.getClusterAdminUsername(), sfConnection.getClusterAdminPassword(), sfVag.getId(),
- getIqnsFromHosts(hosts), volumeIds);
+ hostIqns, volumeIds);
}
}
@@ -339,6 +405,26 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
return true;
}
+ private String[] getNewHostIqns(String[] currentIqns, String[] newIqns) {
+ List<String> lstIqns = new ArrayList<String>();
+
+ if (currentIqns != null) {
+ for (String currentIqn : currentIqns) {
+ lstIqns.add(currentIqn);
+ }
+ }
+
+ if (newIqns != null) {
+ for (String newIqn : newIqns) {
+ if (!lstIqns.contains(newIqn)) {
+ lstIqns.add(newIqn);
+ }
+ }
+ }
+
+ return lstIqns.toArray(new String[0]);
+ }
+
private long[] getNewVolumeIds(long[] volumeIds, long volumeIdToAddOrRemove, boolean add) {
if (add) {
return getNewVolumeIdsAdd(volumeIds, volumeIdToAddOrRemove);
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/68fda5a8/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/util/SolidFireUtil.java
----------------------------------------------------------------------
diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/util/SolidFireUtil.java b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/util/SolidFireUtil.java
index 8d023d6..3c457ba 100644
--- a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/util/SolidFireUtil.java
+++ b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/util/SolidFireUtil.java
@@ -267,7 +267,8 @@ public class SolidFireUtil {
}
}
- public static long createSolidFireAccount(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword, String strAccountName) {
+ public static long createSolidFireAccount(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword, String strAccountName)
+ {
final Gson gson = new GsonBuilder().create();
AccountToAdd accountToAdd = new AccountToAdd(strAccountName);
@@ -283,8 +284,7 @@ public class SolidFireUtil {
return accountAddResult.result.accountID;
}
- public static SolidFireAccount getSolidFireAccountById(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword,
- long lSfAccountId)
+ public static SolidFireAccount getSolidFireAccountById(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword, long lSfAccountId)
{
final Gson gson = new GsonBuilder().create();
@@ -305,7 +305,8 @@ public class SolidFireUtil {
return new SolidFireAccount(lSfAccountId, strSfAccountName, strSfAccountInitiatorSecret, strSfAccountTargetSecret);
}
- public static SolidFireAccount getSolidFireAccountByName(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword, String strSfAccountName) {
+ public static SolidFireAccount getSolidFireAccountByName(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword, String strSfAccountName)
+ {
final Gson gson = new GsonBuilder().create();
AccountToGetByName accountToGetByName = new AccountToGetByName(strSfAccountName);
@@ -325,8 +326,7 @@ public class SolidFireUtil {
return new SolidFireAccount(lSfAccountId, strSfAccountName, strSfAccountInitiatorSecret, strSfAccountTargetSecret);
}
- public static void deleteSolidFireAccount(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword,
- long lAccountId)
+ public static void deleteSolidFireAccount(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword, long lAccountId)
{
final Gson gson = new GsonBuilder().create();
@@ -449,7 +449,35 @@ public class SolidFireUtil {
return new SolidFireVag(lVagId, vagIqns, vagVolumeIds);
}
- public static void deleteSolidFireVag(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword, long lVagId) {
+ public static List<SolidFireVag> getAllSolidFireVags(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword)
+ {
+ final Gson gson = new GsonBuilder().create();
+
+ AllVags allVags = new AllVags();
+
+ String strAllVagsJson = gson.toJson(allVags);
+
+ String strAllVagsGetResultJson = executeJsonRpc(strAllVagsJson, strSfMvip, iSfPort, strSfAdmin, strSfPassword);
+
+ VagGetResult allVagsGetResult = gson.fromJson(strAllVagsGetResultJson, VagGetResult.class);
+
+ verifyResult(allVagsGetResult.result, strAllVagsGetResultJson, gson);
+
+ List<SolidFireVag> lstSolidFireVags = new ArrayList<SolidFireVag>();
+
+ if (allVagsGetResult.result.volumeAccessGroups != null ) {
+ for (VagGetResult.Result.Vag vag : allVagsGetResult.result.volumeAccessGroups) {
+ SolidFireVag sfVag = new SolidFireVag(vag.volumeAccessGroupID, vag.initiators, vag.volumes);
+
+ lstSolidFireVags.add(sfVag);
+ }
+ }
+
+ return lstSolidFireVags;
+ }
+
+ public static void deleteSolidFireVag(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword, long lVagId)
+ {
final Gson gson = new GsonBuilder().create();
VagToDelete vagToDelete = new VagToDelete(lVagId);
@@ -817,7 +845,23 @@ public class SolidFireUtil {
}
@SuppressWarnings("unused")
- private static final class VagToDelete {
+ private static final class AllVags
+ {
+ private final String method = "ListVolumeAccessGroups";
+ private final VagToGetParams params;
+
+ private AllVags()
+ {
+ params = new VagToGetParams();
+ }
+
+ private static final class VagToGetParams
+ {}
+ }
+
+ @SuppressWarnings("unused")
+ private static final class VagToDelete
+ {
private final String method = "DeleteVolumeAccessGroup";
private final VagToDeleteParams params;