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/09 04:54:54 UTC
git commit: updated refs/heads/4.3 to 2efe61d
Updated Branches:
refs/heads/4.3 ce9760f4c -> 2efe61ddb
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/2efe61dd
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/2efe61dd
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/2efe61dd
Branch: refs/heads/4.3
Commit: 2efe61ddbc57316348bc0fa328a09fe4dadb08d2
Parents: ce9760f
Author: Mike Tutkowski <mi...@solidfire.com>
Authored: Tue Jan 7 22:52:11 2014 -0700
Committer: Mike Tutkowski <mi...@solidfire.com>
Committed: Wed Jan 8 20:53:53 2014 -0700
----------------------------------------------------------------------
.../driver/SolidfirePrimaryDataStoreDriver.java | 108 ++++++++++++++++---
.../storage/datastore/util/SolidFireUtil.java | 54 ++++++++--
2 files changed, 141 insertions(+), 21 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2efe61dd/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 ff3e33b..0bf9c50 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
@@ -133,18 +133,15 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
return new SolidFireConnection(mVip, mPort, clusterAdminUsername, clusterAdminPassword);
}
- private SolidFireUtil.SolidFireAccount createSolidFireAccount(String sfAccountName,
- SolidFireConnection sfConnection) {
+ private SolidFireUtil.SolidFireAccount createSolidFireAccount(String sfAccountName, SolidFireConnection sfConnection) {
String mVip = sfConnection.getManagementVip();
int mPort = sfConnection.getManagementPort();
String clusterAdminUsername = sfConnection.getClusterAdminUsername();
String clusterAdminPassword = sfConnection.getClusterAdminPassword();
- long accountNumber = SolidFireUtil.createSolidFireAccount(mVip, mPort,
- clusterAdminUsername, clusterAdminPassword, sfAccountName);
+ long accountNumber = SolidFireUtil.createSolidFireAccount(mVip, mPort, clusterAdminUsername, clusterAdminPassword, sfAccountName);
- return SolidFireUtil.getSolidFireAccountById(mVip, mPort,
- clusterAdminUsername, clusterAdminPassword, accountNumber);
+ return SolidFireUtil.getSolidFireAccountById(mVip, mPort, clusterAdminUsername, clusterAdminPassword, accountNumber);
}
private void updateCsDbWithAccountInfo(long csAccountId, SolidFireUtil.SolidFireAccount sfAccount) {
@@ -185,8 +182,7 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
private final String _targetUsername;
private final String _targetSecret;
- public ChapInfoImpl(String initiatorUsername, String initiatorSecret,
- String targetUsername, String targetSecret) {
+ public ChapInfoImpl(String initiatorUsername, String initiatorSecret, String targetUsername, String targetSecret) {
_initiatorUsername = initiatorUsername;
_initiatorSecret = initiatorSecret;
_targetUsername = targetUsername;
@@ -269,16 +265,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));
@@ -288,6 +307,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)
@@ -314,11 +375,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);
}
}
@@ -336,6 +398,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/2efe61dd/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 a372497..2d528ef 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
@@ -276,8 +276,7 @@ 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();
@@ -294,8 +293,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();
@@ -316,8 +314,7 @@ 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();
@@ -338,8 +335,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();
@@ -467,6 +463,33 @@ public class SolidFireUtil
return new SolidFireVag(lVagId, vagIqns, vagVolumeIds);
}
+ 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();
@@ -855,6 +878,21 @@ public class SolidFireUtil
}
@SuppressWarnings("unused")
+ 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";