diff --git a/plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java b/plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java index 3a703cdb426..426145d9dcc 100644 --- a/plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java +++ b/plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java @@ -269,27 +269,35 @@ public class LinstorStorageAdaptor implements StorageAdaptor { } final DevelopersApi api = getLinstorAPI(pool); + String rscName; try { - final String rscName = getLinstorRscName(volumePath); + rscName = getLinstorRscName(volumePath); ResourceMakeAvailable rma = new ResourceMakeAvailable(); ApiCallRcList answers = api.resourceMakeAvailableOnNode(rscName, localNodeName, rma); checkLinstorAnswersThrow(answers); + } catch (ApiException apiEx) { + s_logger.error(apiEx); + throw new CloudRuntimeException(apiEx.getBestMessage(), apiEx); + } + + try + { // allow 2 primaries for live migration, should be removed by disconnect on the other end ResourceDefinitionModify rdm = new ResourceDefinitionModify(); Properties props = new Properties(); props.put("DrbdOptions/Net/allow-two-primaries", "yes"); rdm.setOverrideProps(props); - answers = api.resourceDefinitionModify(rscName, rdm); + ApiCallRcList answers = api.resourceDefinitionModify(rscName, rdm); if (answers.hasError()) { s_logger.error("Unable to set 'allow-two-primaries' on " + rscName); - throw new CloudRuntimeException(answers.get(0).getMessage()); + // do not fail here as adding allow-two-primaries property is only a problem while live migrating } } catch (ApiException apiEx) { s_logger.error(apiEx); - throw new CloudRuntimeException(apiEx.getBestMessage(), apiEx); + // do not fail here as adding allow-two-primaries property is only a problem while live migrating } return true; } @@ -353,19 +361,21 @@ public class LinstorStorageAdaptor implements StorageAdaptor { ApiCallRcList answers = api.resourceDefinitionModify(rsc.get().getName(), rdm); if (answers.hasError()) { - s_logger.error("Failed to remove 'allow-two-primaries' on " + rsc.get().getName()); - throw new CloudRuntimeException(answers.get(0).getMessage()); + s_logger.error( + String.format("Failed to remove 'allow-two-primaries' on %s: %s", + rsc.get().getName(), LinstorUtil.getBestErrorMessage(answers))); + // do not fail here as removing allow-two-primaries property isn't fatal } return true; } s_logger.warn("Linstor: Couldn't find resource for this path: " + localPath); } catch (ApiException apiEx) { - s_logger.error(apiEx); - throw new CloudRuntimeException(apiEx.getBestMessage(), apiEx); + s_logger.error(apiEx.getBestMessage()); + // do not fail here as removing allow-two-primaries property isn't fatal } } - return false; + return true; } @Override diff --git a/plugins/storage/volume/linstor/src/main/java/org/apache/cloudstack/storage/datastore/util/LinstorUtil.java b/plugins/storage/volume/linstor/src/main/java/org/apache/cloudstack/storage/datastore/util/LinstorUtil.java index ddd15a5984a..cc85c9834eb 100644 --- a/plugins/storage/volume/linstor/src/main/java/org/apache/cloudstack/storage/datastore/util/LinstorUtil.java +++ b/plugins/storage/volume/linstor/src/main/java/org/apache/cloudstack/storage/datastore/util/LinstorUtil.java @@ -20,6 +20,8 @@ import com.linbit.linstor.api.ApiClient; import com.linbit.linstor.api.ApiException; import com.linbit.linstor.api.Configuration; import com.linbit.linstor.api.DevelopersApi; +import com.linbit.linstor.api.model.ApiCallRc; +import com.linbit.linstor.api.model.ApiCallRcList; import com.linbit.linstor.api.model.ProviderKind; import com.linbit.linstor.api.model.ResourceGroup; import com.linbit.linstor.api.model.StoragePool; @@ -47,6 +49,15 @@ public class LinstorUtil { return new DevelopersApi(client); } + public static String getBestErrorMessage(ApiCallRcList answers) { + return answers != null && !answers.isEmpty() ? + answers.stream() + .filter(ApiCallRc::isError) + .findFirst() + .map(ApiCallRc::getMessage) + .orElse((answers.get(0)).getMessage()) : null; + } + public static long getCapacityBytes(String linstorUrl, String rscGroupName) { DevelopersApi linstorApi = getLinstorAPI(linstorUrl); try {