Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.io.InputStreamReader;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
Expand Down Expand Up @@ -53,6 +54,7 @@
import com.linbit.linstor.api.model.ResourceConnectionModify;
import com.linbit.linstor.api.model.ResourceDefinition;
import com.linbit.linstor.api.model.ResourceGroup;
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;
Expand Down Expand Up @@ -257,6 +259,34 @@
}
}

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);

Check warning on line 268 in plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java

View check run for this annotation

Codecov / codecov/patch

plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java#L263-L268

Added lines #L263 - L268 were not covered by tests
if (answers.hasError()) {
s_logger.error(String.format("Unable to set protocol C and 'allow-two-primaries' on %s", rscName));

Check warning on line 270 in plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java

View check run for this annotation

Codecov / codecov/patch

plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java#L270

Added line #L270 was not covered by tests
// do not fail here as adding allow-two-primaries property is only a problem while live migrating
}
}

Check warning on line 273 in plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java

View check run for this annotation

Codecov / codecov/patch

plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java#L273

Added line #L273 was not covered by tests

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);

Check warning on line 281 in plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java

View check run for this annotation

Codecov / codecov/patch

plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java#L276-L281

Added lines #L276 - L281 were not covered by tests
if (answers.hasError()) {
s_logger.error(String.format(

Check warning on line 283 in plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java

View check run for this annotation

Codecov / codecov/patch

plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java#L283

Added line #L283 was not covered by tests
"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
}
}

Check warning on line 288 in plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java

View check run for this annotation

Codecov / codecov/patch

plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java#L288

Added line #L288 was not covered by tests

/**
* Checks if the given resource is in use by drbd on any host and
* if so set the drbd option allow-two-primaries
Expand All @@ -268,17 +298,13 @@
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);

Check warning on line 305 in plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java

View check run for this annotation

Codecov / codecov/patch

plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java#L305

Added line #L305 was not covered by tests
} else {
setAllowTwoPrimariesOnRc(api, rscName, inUseNode);

Check warning on line 307 in plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java

View check run for this annotation

Codecov / codecov/patch

plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java#L307

Added line #L307 was not covered by tests
}
}
}
Expand Down Expand Up @@ -317,11 +343,22 @@
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);

Check warning on line 350 in plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java

View check run for this annotation

Codecov / codecov/patch

plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java#L348-L350

Added lines #L348 - L350 were not covered by tests
if (answers.hasError()) {
s_logger.error(
String.format("Failed to remove 'protocol' and 'allow-two-primaries' on %s: %s",
rscName, LinstorUtil.getBestErrorMessage(answers)));

Check warning on line 354 in plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java

View check run for this annotation

Codecov / codecov/patch

plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java#L352-L354

Added lines #L352 - L354 were not covered by tests
// do not fail here as removing allow-two-primaries property isn't fatal
}
}

Check warning on line 357 in plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java

View check run for this annotation

Codecov / codecov/patch

plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java#L357

Added line #L357 was not covered by tests

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()) {
Expand All @@ -334,6 +371,15 @@
}
}

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");

Check warning on line 377 in plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java

View check run for this annotation

Codecov / codecov/patch

plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java#L375-L377

Added lines #L375 - L377 were not covered by tests

removeTwoPrimariesRDProps(api, rscName, deleteProps);
removeTwoPrimariesRcProps(api, rscName, inUseNode, deleteProps);
}

Check warning on line 381 in plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java

View check run for this annotation

Codecov / codecov/patch

plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java#L379-L381

Added lines #L379 - L381 were not covered by tests

private boolean tryDisconnectLinstor(String volumePath, KVMStoragePool pool)
{
if (volumePath == null) {
Expand Down Expand Up @@ -367,7 +413,7 @@
try {
String inUseNode = LinstorUtil.isResourceInUse(api, rsc.getName());
if (inUseNode != null && !inUseNode.equalsIgnoreCase(localNodeName)) {
removeTwoPrimariesRcProps(api, inUseNode, rsc.getName());
removeTwoPrimariesProps(api, inUseNode, rsc.getName());

Check warning on line 416 in plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java

View check run for this annotation

Codecov / codecov/patch

plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java#L416

Added line #L416 was not covered by tests
}
} catch (ApiException apiEx) {
s_logger.error(apiEx.getBestMessage());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -27,8 +28,10 @@
import com.linbit.linstor.api.model.ResourceWithVolumes;
import com.linbit.linstor.api.model.StoragePool;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

import com.cloud.utils.exception.CloudRuntimeException;
import org.apache.log4j.Logger;
Expand Down Expand Up @@ -113,6 +116,28 @@
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);

Check warning on line 129 in plugins/storage/volume/linstor/src/main/java/org/apache/cloudstack/storage/datastore/util/LinstorUtil.java

View check run for this annotation

Codecov / codecov/patch

plugins/storage/volume/linstor/src/main/java/org/apache/cloudstack/storage/datastore/util/LinstorUtil.java#L129

Added line #L129 was not covered by tests
if (rscs != null) {
Collection<String> disklessNodes = rscs.stream()

Check warning on line 131 in plugins/storage/volume/linstor/src/main/java/org/apache/cloudstack/storage/datastore/util/LinstorUtil.java

View check run for this annotation

Codecov / codecov/patch

plugins/storage/volume/linstor/src/main/java/org/apache/cloudstack/storage/datastore/util/LinstorUtil.java#L131

Added line #L131 was not covered by tests
.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()));

Check warning on line 136 in plugins/storage/volume/linstor/src/main/java/org/apache/cloudstack/storage/datastore/util/LinstorUtil.java

View check run for this annotation

Codecov / codecov/patch

plugins/storage/volume/linstor/src/main/java/org/apache/cloudstack/storage/datastore/util/LinstorUtil.java#L134-L136

Added lines #L134 - L136 were not covered by tests
}
return false;

Check warning on line 138 in plugins/storage/volume/linstor/src/main/java/org/apache/cloudstack/storage/datastore/util/LinstorUtil.java

View check run for this annotation

Codecov / codecov/patch

plugins/storage/volume/linstor/src/main/java/org/apache/cloudstack/storage/datastore/util/LinstorUtil.java#L138

Added line #L138 was not covered by tests
}

/**
* 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.
Expand Down
Loading