mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Merge remote-tracking branch 'origin/4.18' into 4.19
Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>
This commit is contained in:
commit
5b7c86aa45
@ -17,6 +17,7 @@
|
||||
package com.cloud.hypervisor.kvm.storage;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@ -47,6 +48,7 @@ import com.linbit.linstor.api.model.ProviderKind;
|
||||
import com.linbit.linstor.api.model.Resource;
|
||||
import com.linbit.linstor.api.model.ResourceConnectionModify;
|
||||
import com.linbit.linstor.api.model.ResourceDefinition;
|
||||
import com.linbit.linstor.api.model.ResourceDefinitionModify;
|
||||
import com.linbit.linstor.api.model.ResourceGroupSpawn;
|
||||
import com.linbit.linstor.api.model.ResourceMakeAvailable;
|
||||
import com.linbit.linstor.api.model.ResourceWithVolumes;
|
||||
@ -231,6 +233,34 @@ public class LinstorStorageAdaptor implements StorageAdaptor {
|
||||
}
|
||||
}
|
||||
|
||||
private void setAllowTwoPrimariesOnRD(DevelopersApi api, String rscName) throws ApiException {
|
||||
ResourceDefinitionModify rdm = new ResourceDefinitionModify();
|
||||
Properties props = new Properties();
|
||||
props.put("DrbdOptions/Net/allow-two-primaries", "yes");
|
||||
props.put("DrbdOptions/Net/protocol", "C");
|
||||
rdm.setOverrideProps(props);
|
||||
ApiCallRcList answers = api.resourceDefinitionModify(rscName, rdm);
|
||||
if (answers.hasError()) {
|
||||
s_logger.error(String.format("Unable to set protocol C and 'allow-two-primaries' on %s", rscName));
|
||||
// do not fail here as adding allow-two-primaries property is only a problem while live migrating
|
||||
}
|
||||
}
|
||||
|
||||
private void setAllowTwoPrimariesOnRc(DevelopersApi api, String rscName, String inUseNode) throws ApiException {
|
||||
ResourceConnectionModify rcm = new ResourceConnectionModify();
|
||||
Properties props = new Properties();
|
||||
props.put("DrbdOptions/Net/allow-two-primaries", "yes");
|
||||
props.put("DrbdOptions/Net/protocol", "C");
|
||||
rcm.setOverrideProps(props);
|
||||
ApiCallRcList answers = api.resourceConnectionModify(rscName, inUseNode, localNodeName, rcm);
|
||||
if (answers.hasError()) {
|
||||
s_logger.error(String.format(
|
||||
"Unable to set protocol C and 'allow-two-primaries' on %s/%s/%s",
|
||||
inUseNode, localNodeName, rscName));
|
||||
// do not fail here as adding allow-two-primaries property is only a problem while live migrating
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given resource is in use by drbd on any host and
|
||||
* if so set the drbd option allow-two-primaries
|
||||
@ -242,17 +272,13 @@ public class LinstorStorageAdaptor implements StorageAdaptor {
|
||||
String inUseNode = LinstorUtil.isResourceInUse(api, rscName);
|
||||
if (inUseNode != null && !inUseNode.equalsIgnoreCase(localNodeName)) {
|
||||
// allow 2 primaries for live migration, should be removed by disconnect on the other end
|
||||
ResourceConnectionModify rcm = new ResourceConnectionModify();
|
||||
Properties props = new Properties();
|
||||
props.put("DrbdOptions/Net/allow-two-primaries", "yes");
|
||||
props.put("DrbdOptions/Net/protocol", "C");
|
||||
rcm.setOverrideProps(props);
|
||||
ApiCallRcList answers = api.resourceConnectionModify(rscName, inUseNode, localNodeName, rcm);
|
||||
if (answers.hasError()) {
|
||||
s_logger.error(String.format(
|
||||
"Unable to set protocol C and 'allow-two-primaries' on %s/%s/%s",
|
||||
inUseNode, localNodeName, rscName));
|
||||
// do not fail here as adding allow-two-primaries property is only a problem while live migrating
|
||||
|
||||
// if non hyperconverged setup, we have to set allow-two-primaries on the resource-definition
|
||||
// as there is no resource connection between diskless nodes.
|
||||
if (LinstorUtil.areResourcesDiskless(api, rscName, Arrays.asList(inUseNode, localNodeName))) {
|
||||
setAllowTwoPrimariesOnRD(api, rscName);
|
||||
} else {
|
||||
setAllowTwoPrimariesOnRc(api, rscName, inUseNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -291,11 +317,22 @@ public class LinstorStorageAdaptor implements StorageAdaptor {
|
||||
return true;
|
||||
}
|
||||
|
||||
private void removeTwoPrimariesRcProps(DevelopersApi api, String inUseNode, String rscName) throws ApiException {
|
||||
private void removeTwoPrimariesRDProps(DevelopersApi api, String rscName, List<String> deleteProps)
|
||||
throws ApiException {
|
||||
ResourceDefinitionModify rdm = new ResourceDefinitionModify();
|
||||
rdm.deleteProps(deleteProps);
|
||||
ApiCallRcList answers = api.resourceDefinitionModify(rscName, rdm);
|
||||
if (answers.hasError()) {
|
||||
s_logger.error(
|
||||
String.format("Failed to remove 'protocol' and 'allow-two-primaries' on %s: %s",
|
||||
rscName, LinstorUtil.getBestErrorMessage(answers)));
|
||||
// do not fail here as removing allow-two-primaries property isn't fatal
|
||||
}
|
||||
}
|
||||
|
||||
private void removeTwoPrimariesRcProps(DevelopersApi api, String rscName, String inUseNode, List<String> deleteProps)
|
||||
throws ApiException {
|
||||
ResourceConnectionModify rcm = new ResourceConnectionModify();
|
||||
List<String> deleteProps = new ArrayList<>();
|
||||
deleteProps.add("DrbdOptions/Net/allow-two-primaries");
|
||||
deleteProps.add("DrbdOptions/Net/protocol");
|
||||
rcm.deleteProps(deleteProps);
|
||||
ApiCallRcList answers = api.resourceConnectionModify(rscName, localNodeName, inUseNode, rcm);
|
||||
if (answers.hasError()) {
|
||||
@ -308,6 +345,15 @@ public class LinstorStorageAdaptor implements StorageAdaptor {
|
||||
}
|
||||
}
|
||||
|
||||
private void removeTwoPrimariesProps(DevelopersApi api, String inUseNode, String rscName) throws ApiException {
|
||||
List<String> deleteProps = new ArrayList<>();
|
||||
deleteProps.add("DrbdOptions/Net/allow-two-primaries");
|
||||
deleteProps.add("DrbdOptions/Net/protocol");
|
||||
|
||||
removeTwoPrimariesRDProps(api, rscName, deleteProps);
|
||||
removeTwoPrimariesRcProps(api, rscName, inUseNode, deleteProps);
|
||||
}
|
||||
|
||||
private boolean tryDisconnectLinstor(String volumePath, KVMStoragePool pool)
|
||||
{
|
||||
if (volumePath == null) {
|
||||
@ -341,7 +387,7 @@ public class LinstorStorageAdaptor implements StorageAdaptor {
|
||||
try {
|
||||
String inUseNode = LinstorUtil.isResourceInUse(api, rsc.getName());
|
||||
if (inUseNode != null && !inUseNode.equalsIgnoreCase(localNodeName)) {
|
||||
removeTwoPrimariesRcProps(api, inUseNode, rsc.getName());
|
||||
removeTwoPrimariesProps(api, inUseNode, rsc.getName());
|
||||
}
|
||||
} catch (ApiException apiEx) {
|
||||
s_logger.error(apiEx.getBestMessage());
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
package org.apache.cloudstack.storage.datastore.util;
|
||||
|
||||
import com.linbit.linstor.api.ApiClient;
|
||||
import com.linbit.linstor.api.ApiConsts;
|
||||
import com.linbit.linstor.api.ApiException;
|
||||
import com.linbit.linstor.api.DevelopersApi;
|
||||
import com.linbit.linstor.api.model.ApiCallRc;
|
||||
@ -33,6 +34,7 @@ import com.linbit.linstor.api.model.Volume;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
@ -209,6 +211,28 @@ public class LinstorUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given resources are diskless.
|
||||
*
|
||||
* @param api developer api object to use
|
||||
* @param rscName resource name to check in use state.
|
||||
* @return NodeName where the resource is inUse, if not in use `null`
|
||||
* @throws ApiException forwards api errors
|
||||
*/
|
||||
public static boolean areResourcesDiskless(DevelopersApi api, String rscName, Collection<String> nodeNames)
|
||||
throws ApiException {
|
||||
List<Resource> rscs = api.resourceList(rscName, null, null);
|
||||
if (rscs != null) {
|
||||
Collection<String> disklessNodes = rscs.stream()
|
||||
.filter(rsc -> rsc.getFlags() != null && (rsc.getFlags().contains(ApiConsts.FLAG_DISKLESS) ||
|
||||
rsc.getFlags().contains(ApiConsts.FLAG_DRBD_DISKLESS)))
|
||||
.map(rsc -> rsc.getNodeName().toLowerCase())
|
||||
.collect(Collectors.toList());
|
||||
return disklessNodes.containsAll(nodeNames.stream().map(String::toLowerCase).collect(Collectors.toList()));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to get the device path for the given resource name.
|
||||
* This could be made a bit more direct after java-linstor api is fixed for layer data subtypes.
|
||||
|
||||
@ -174,6 +174,6 @@ class CsFile:
|
||||
self.new_config = list(temp_config)
|
||||
|
||||
def compare(self, o):
|
||||
result = (isinstance(o, self.__class__) and set(self.config) == set(o.config))
|
||||
result = (isinstance(o, self.__class__) and self.config == o.config)
|
||||
logging.debug("Comparison of CsFiles content is ==> %s" % result)
|
||||
return result
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user