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

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


The following commit(s) were added to refs/heads/4.19 by this push:
     new a2f2e87c120 linstor: improve heartbeat check with also asking linstor 
(#10105)
a2f2e87c120 is described below

commit a2f2e87c12095387ff2bc09b0d0fd82615d6d361
Author: Rene Peinthor <[email protected]>
AuthorDate: Mon Dec 16 09:59:57 2024 +0100

    linstor: improve heartbeat check with also asking linstor (#10105)
    
    If a node doesn't have a DRBD connection to another node,
    additionally ask Linstor-Controller if the node is alive.
    Otherwise we would have simply said no and the node might still be alive.
    This is always the case in a non hyperconverged setup.
---
 plugins/storage/volume/linstor/CHANGELOG.md        |  6 ++++
 .../kvm/storage/LinstorStorageAdaptor.java         | 16 +++++++++
 .../hypervisor/kvm/storage/LinstorStoragePool.java | 40 +++++++++++++++++++---
 3 files changed, 57 insertions(+), 5 deletions(-)

diff --git a/plugins/storage/volume/linstor/CHANGELOG.md 
b/plugins/storage/volume/linstor/CHANGELOG.md
index 930e139870f..e1ff9a5e269 100644
--- a/plugins/storage/volume/linstor/CHANGELOG.md
+++ b/plugins/storage/volume/linstor/CHANGELOG.md
@@ -5,6 +5,12 @@ All notable changes to Linstor CloudStack plugin will be 
documented in this file
 The format is based on [Keep a 
Changelog](https://keepachangelog.com/en/1.0.0/),
 and this project adheres to [Semantic 
Versioning](https://semver.org/spec/v2.0.0.html).
 
+## [2024-12-13]
+
+### Fixed
+
+- Linstor heartbeat check now also ask linstor-controller if there is no 
connection between nodes
+
 ## [2024-10-28]
 
 ### Fixed
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 1f71a54a4f3..90b1342c0a2 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
@@ -45,6 +45,7 @@ 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.Node;
 import com.linbit.linstor.api.model.Properties;
 import com.linbit.linstor.api.model.ProviderKind;
 import com.linbit.linstor.api.model.Resource;
@@ -712,4 +713,19 @@ public class LinstorStorageAdaptor implements 
StorageAdaptor {
             throw new CloudRuntimeException(apiEx.getBestMessage(), apiEx);
         }
     }
+
+    public boolean isNodeOnline(LinstorStoragePool pool, String nodeName) {
+        DevelopersApi linstorApi = getLinstorAPI(pool);
+        try {
+            List<Node> node = 
linstorApi.nodeList(Collections.singletonList(nodeName), 
Collections.emptyList(), null, null);
+            if (node == null || node.isEmpty()) {
+                return false;
+            }
+
+            return 
Node.ConnectionStatusEnum.ONLINE.equals(node.get(0).getConnectionStatus());
+        } catch (ApiException apiEx) {
+            s_logger.error(apiEx.getMessage());
+            throw new CloudRuntimeException(apiEx.getBestMessage(), apiEx);
+        }
+    }
 }
diff --git 
a/plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStoragePool.java
 
b/plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStoragePool.java
index 4077d5dadfd..9a9c1a9717a 100644
--- 
a/plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStoragePool.java
+++ 
b/plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStoragePool.java
@@ -279,22 +279,52 @@ public class LinstorStoragePool implements KVMStoragePool 
{
         return sc.execute(parser);
     }
 
+    private boolean checkLinstorNodeOnline(String nodeName) {
+        return ((LinstorStorageAdaptor)_storageAdaptor).isNodeOnline(this, 
nodeName);
+    }
+
+    /**
+     * Checks output of drbdsetup status output if this node has any valid 
connection to the specified
+     * otherNodeName.
+     * If there is no connection, ask the Linstor controller if the node is 
seen online and return false if not.
+     * If there is a connection but not connected(valid) return false.
+     * @param output Output of the drbdsetup status --json command
+     * @param otherNodeName Name of the node to check against
+     * @return true if we could say that this node thinks the node in question 
is reachable, otherwise false.
+     */
     private boolean checkDrbdSetupStatusOutput(String output, String 
otherNodeName) {
         JsonParser jsonParser = new JsonParser();
         JsonArray jResources = (JsonArray) jsonParser.parse(output);
+        boolean connectionFound = false;
         for (JsonElement jElem : jResources) {
             JsonObject jRes = (JsonObject) jElem;
             JsonArray jConnections = jRes.getAsJsonArray("connections");
             for (JsonElement jConElem : jConnections) {
                 JsonObject jConn = (JsonObject) jConElem;
-                if 
(jConn.getAsJsonPrimitive("name").getAsString().equals(otherNodeName)
-                        && 
jConn.getAsJsonPrimitive("connection-state").getAsString().equalsIgnoreCase("Connected"))
 {
-                    return true;
+                if 
(jConn.getAsJsonPrimitive("name").getAsString().equals(otherNodeName))
+                {
+                    connectionFound = true;
+                    if 
(jConn.getAsJsonPrimitive("connection-state").getAsString()
+                            .equalsIgnoreCase("Connected")) {
+                        return true;
+                    }
                 }
             }
         }
-        s_logger.warn(String.format("checkDrbdSetupStatusOutput: no resource 
connected to %s.", otherNodeName));
-        return false;
+        boolean otherNodeOnline = false;
+        if (connectionFound) {
+            s_logger.warn(String.format(
+                    "checkingHeartBeat: connection found, but not in state 
'Connected' to %s", otherNodeName));
+        } else {
+            s_logger.warn(String.format(
+                    "checkingHeartBeat: no resource connected to %s, checking 
LINSTOR", otherNodeName));
+            otherNodeOnline = checkLinstorNodeOnline(otherNodeName);
+        }
+        s_logger.info(String.format(
+                "checkingHeartBeat: other node %s is %s.",
+                otherNodeName,
+                otherNodeOnline ? "online on controller" : "down"));
+        return otherNodeOnline;
     }
 
     private String executeDrbdEventsNow(OutputInterpreter.AllLinesParser 
parser) {

Reply via email to