This is an automated email from the ASF dual-hosted git repository.

rohit pushed a commit to branch 4.18
in repository https://gitbox.apache.org/repos/asf/cloudstack.git


The following commit(s) were added to refs/heads/4.18 by this push:
     new 56f0448f0d4 Linstor fix migration while node offline (#8610)
56f0448f0d4 is described below

commit 56f0448f0d46e95f50047636000a73fc754fd0be
Author: Rene Peinthor <[email protected]>
AuthorDate: Thu Feb 8 19:27:38 2024 +0100

    Linstor fix migration while node offline (#8610)
    
    * linstor: Add util method getBestErrorMessage from main
    
    * linstor: failed remove of allow-two-primaries is no fatal error
    
    * linstor: Fix failure if a Linstor node is down while migrating
    
    If a Linstor node is down while migrating resource, allow-two-primaries
    setting will fail because we can't reach the downed node. But it will
    still set the property on the other nodes and migration should work.
    We now just report an error instead of completely failing.
---
 .../kvm/storage/LinstorStorageAdaptor.java         | 28 +++++++++++++++-------
 .../storage/datastore/util/LinstorUtil.java        | 11 +++++++++
 2 files changed, 30 insertions(+), 9 deletions(-)

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 {

Reply via email to