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

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


The following commit(s) were added to refs/heads/4.20 by this push:
     new 10dcbd76f0f linstor: Provide /dev/drbd/by-res/ resource paths to 
CloudStack (#12300)
10dcbd76f0f is described below

commit 10dcbd76f0fdd2e0eb0674e04e211a3788c8ad89
Author: Rene Peinthor <[email protected]>
AuthorDate: Wed Dec 31 10:55:54 2025 +0100

    linstor: Provide /dev/drbd/by-res/ resource paths to CloudStack (#12300)
---
 plugins/storage/volume/linstor/CHANGELOG.md        | 17 ++++-------
 .../kvm/storage/LinstorStorageAdaptor.java         |  7 +++--
 .../storage/datastore/util/LinstorUtil.java        | 35 ++++++++++++++++++----
 3 files changed, 38 insertions(+), 21 deletions(-)

diff --git a/plugins/storage/volume/linstor/CHANGELOG.md 
b/plugins/storage/volume/linstor/CHANGELOG.md
index 7da3516955d..47d1ddeb06c 100644
--- a/plugins/storage/volume/linstor/CHANGELOG.md
+++ b/plugins/storage/volume/linstor/CHANGELOG.md
@@ -5,22 +5,24 @@ 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).
 
-## [2025-10-03]
+## [2025-12-18]
 
 ### Changed
+- Provide /dev/drbd/by-res/ resource paths to CloudStack for usage.
+
+## [2025-10-03]
 
+### Changed
 - Revert qcow2 snapshot now use sparse/discard options to convert on thin 
devices.
 
 ## [2025-08-05]
 
 ### Fixed
-
 - getVolumeStats wasn't correctly working if multiple Linstor clusters/primary 
storages are used.
 
 ## [2025-07-01]
 
 ### Fixed
-
 - Regression in 4.19.3 and 4.21.0 with templates from snapshots
 
 ## [2025-05-07]
@@ -31,25 +33,21 @@ and this project adheres to [Semantic 
Versioning](https://semver.org/spec/v2.0.0
 ## [2025-03-13]
 
 ### Fixed
-
 - Implemented missing delete datastore, to correctly cleanup on datastore 
removal
 
 ## [2025-02-21]
 
 ### Fixed
-
 - Always try to delete cs-...-rst resource before doing a snapshot backup
 
 ## [2025-01-27]
 
 ### Fixed
-
 - Use of multiple primary storages on the same linstor controller
 
 ## [2025-01-20]
 
 ### Fixed
-
 - Volume snapshots on zfs used the wrong dataset path to hide/unhide snapdev
 
 ## [2024-12-19]
@@ -60,13 +58,11 @@ and this project adheres to [Semantic 
Versioning](https://semver.org/spec/v2.0.0
 ## [2024-12-13]
 
 ### Fixed
-
 - Linstor heartbeat check now also ask linstor-controller if there is no 
connection between nodes
 
 ## [2024-12-11]
 
 ### Fixed
-
 - Only set allow-two-primaries if a live migration is performed
 
 ## [2024-10-28]
@@ -79,17 +75,14 @@ and this project adheres to [Semantic 
Versioning](https://semver.org/spec/v2.0.0
 ## [2024-10-14]
 
 ### Added
-
 - Support for ISO direct download to primary storage
 
 ## [2024-10-04]
 
 ### Added
-
 - Enable qemu discard="unmap" for Linstor block disks
 
 ## [2024-08-27]
 
 ### Changed
-
 - Allow two primaries(+protocol c) is now set on resource-connection level 
instead of rd
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 a664e7ed03b..1fe318e5163 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
@@ -232,7 +232,7 @@ public class LinstorStorageAdaptor implements 
StorageAdaptor {
             makeResourceAvailable(api, foundRscName, false);
 
             if (!resources.isEmpty() && 
!resources.get(0).getVolumes().isEmpty()) {
-                final String devPath = 
resources.get(0).getVolumes().get(0).getDevicePath();
+                final String devPath = 
LinstorUtil.getDevicePathFromResource(resources.get(0));
                 logger.info("Linstor: Created drbd device: " + devPath);
                 final KVMPhysicalDisk kvmDisk = new KVMPhysicalDisk(devPath, 
name, pool);
                 kvmDisk.setFormat(QemuImg.PhysicalDiskFormat.RAW);
@@ -455,8 +455,9 @@ public class LinstorStorageAdaptor implements 
StorageAdaptor {
     private Optional<ResourceWithVolumes> getResourceByPathOrName(
             final List<ResourceWithVolumes> resources, String path) {
         return resources.stream()
-            .filter(rsc -> 
getLinstorRscName(path).equalsIgnoreCase(rsc.getName()) || 
rsc.getVolumes().stream()
-                .anyMatch(v -> path.equals(v.getDevicePath())))
+            .filter(rsc -> 
getLinstorRscName(path).equalsIgnoreCase(rsc.getName()) ||
+                    
path.equals(LinstorUtil.formatDrbdByResDevicePath(rsc.getName())) ||
+                    rsc.getVolumes().stream().anyMatch(v -> 
path.equals(v.getDevicePath())))
             .findFirst();
     }
 
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 9c3c9d32611..4196c12b116 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
@@ -264,6 +264,16 @@ public class LinstorUtil {
         return false;
     }
 
+    /**
+     * Format the device path for DRBD resources.
+     * @param rscName
+     * @return
+     */
+    public static String formatDrbdByResDevicePath(String rscName)
+    {
+        return String.format("/dev/drbd/by-res/%s/0", rscName);
+    }
+
     /**
      * 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.
@@ -283,12 +293,7 @@ public class LinstorUtil {
                 null);
         for (ResourceWithVolumes rsc : resources) {
             if (!rsc.getVolumes().isEmpty()) {
-                // CloudStack resource always only have 1 volume
-                String devicePath = rsc.getVolumes().get(0).getDevicePath();
-                if (devicePath != null && !devicePath.isEmpty()) {
-                    LOGGER.debug("getDevicePath: {} -> {}", rscName, 
devicePath);
-                    return devicePath;
-                }
+                return LinstorUtil.getDevicePathFromResource(rsc);
             }
         }
 
@@ -297,6 +302,24 @@ public class LinstorUtil {
         throw new CloudRuntimeException("Linstor: " + errMsg);
     }
 
+    /**
+     * Check if the resource has DRBD or not and deliver the correct device 
path.
+     * @param rsc
+     * @return
+     */
+    public static String getDevicePathFromResource(ResourceWithVolumes rsc) {
+        if (!rsc.getVolumes().isEmpty()) {
+            // CloudStack resource always only have 1 volume
+            if (rsc.getLayerObject().getDrbd() != null) {
+                return formatDrbdByResDevicePath(rsc.getName());
+            } else {
+                return rsc.getVolumes().get(0).getDevicePath();
+            }
+        }
+        throw new CloudRuntimeException(
+                String.format("getDevicePath: Resource %s/%s doesn't have 
volumes", rsc.getNodeName(), rsc.getName()));
+    }
+
     public static ApiCallRcList applyAuxProps(DevelopersApi api, String 
rscName, String dispName, String vmName)
             throws ApiException
     {

Reply via email to