You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by su...@apache.org on 2025/08/15 13:50:45 UTC
(cloudstack) branch 4.19 updated: linstor: fix getVolumeStats if multiple Linstor primary storages are used (#11397)
This is an automated email from the ASF dual-hosted git repository.
sureshanaparti 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 25f93b1d6b8 linstor: fix getVolumeStats if multiple Linstor primary storages are used (#11397)
25f93b1d6b8 is described below
commit 25f93b1d6b83acbdd14ba942c2f4086e9fdfd888
Author: Rene Peinthor <re...@linbit.com>
AuthorDate: Fri Aug 15 15:50:39 2025 +0200
linstor: fix getVolumeStats if multiple Linstor primary storages are used (#11397)
We didn't account for caching the volume stats for each used Linstor
cluster, so the first asked Linstor cluster would prevent caching
for all the others and so null was returned.
Now we have invalidate counters for each Linstor cluster and
also store the cache result with the Linstor cluster address prefixed.
---
plugins/storage/volume/linstor/CHANGELOG.md | 6 +++++
.../driver/LinstorPrimaryDataStoreDriverImpl.java | 30 +++++++++++++---------
2 files changed, 24 insertions(+), 12 deletions(-)
diff --git a/plugins/storage/volume/linstor/CHANGELOG.md b/plugins/storage/volume/linstor/CHANGELOG.md
index a96b7c75b2b..c0991a9aa2b 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).
+## [2025-08-05]
+
+### Fixed
+
+- getVolumeStats wasn't correctly working if multiple Linstor clusters/primary storages are used.
+
## [2025-07-01]
### Fixed
diff --git a/plugins/storage/volume/linstor/src/main/java/org/apache/cloudstack/storage/datastore/driver/LinstorPrimaryDataStoreDriverImpl.java b/plugins/storage/volume/linstor/src/main/java/org/apache/cloudstack/storage/datastore/driver/LinstorPrimaryDataStoreDriverImpl.java
index 71e1b528506..0eefe0bcf9b 100644
--- a/plugins/storage/volume/linstor/src/main/java/org/apache/cloudstack/storage/datastore/driver/LinstorPrimaryDataStoreDriverImpl.java
+++ b/plugins/storage/volume/linstor/src/main/java/org/apache/cloudstack/storage/datastore/driver/LinstorPrimaryDataStoreDriverImpl.java
@@ -135,7 +135,7 @@ public class LinstorPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
private HostDao _hostDao;
@Inject private VMTemplateDao _vmTemplateDao;
- private long volumeStatsLastUpdate = 0L;
+ private final Map<String, Long> volumeStatsLastUpdate = new HashMap<>();
private final Map<String, Pair<Long, Long>> volumeStats = new HashMap<>();
public LinstorPrimaryDataStoreDriverImpl()
@@ -1533,11 +1533,12 @@ public class LinstorPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
/**
* Updates the cache map containing current allocated size data.
- * @param api Linstor Developers api object
+ * @param linstorAddr Linstor cluster api address
*/
- private void fillVolumeStatsCache(DevelopersApi api) {
+ private void fillVolumeStatsCache(String linstorAddr) {
+ final DevelopersApi api = LinstorUtil.getLinstorAPI(linstorAddr);
try {
- s_logger.trace("Start volume stats cache update");
+ s_logger.trace("Start volume stats cache update for " + linstorAddr);
List<ResourceWithVolumes> resources = api.viewResources(
Collections.emptyList(),
Collections.emptyList(),
@@ -1564,14 +1565,14 @@ public class LinstorPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
}
}
- volumeStats.clear();
+ volumeStats.keySet().removeIf(key -> key.startsWith(linstorAddr));
for (Map.Entry<String, Long> entry : allocSizeMap.entrySet()) {
Long reserved = resSizeMap.getOrDefault(entry.getKey(), 0L);
Pair<Long, Long> volStat = new Pair<>(entry.getValue(), reserved);
- volumeStats.put(entry.getKey(), volStat);
+ volumeStats.put(linstorAddr + "/" + entry.getKey(), volStat);
}
- volumeStatsLastUpdate = System.currentTimeMillis();
- s_logger.trace("Done volume stats cache update: " + volumeStats.size());
+ volumeStatsLastUpdate.put(linstorAddr, System.currentTimeMillis());
+ s_logger.debug(String.format("Done volume stats cache update for %s: %d", linstorAddr, volumeStats.size()));
} catch (ApiException e) {
s_logger.error("Unable to fetch Linstor resources: " + e.getBestMessage());
}
@@ -1579,14 +1580,19 @@ public class LinstorPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
@Override
public Pair<Long, Long> getVolumeStats(StoragePool storagePool, String volumeId) {
- final DevelopersApi api = LinstorUtil.getLinstorAPI(storagePool.getHostAddress());
+ String linstorAddr = storagePool.getHostAddress();
synchronized (volumeStats) {
- long invalidateCacheTime = volumeStatsLastUpdate +
+ long invalidateCacheTime = volumeStatsLastUpdate.getOrDefault(storagePool.getHostAddress(), 0L) +
LinstorConfigurationManager.VolumeStatsCacheTime.value() * 1000;
if (invalidateCacheTime < System.currentTimeMillis()) {
- fillVolumeStatsCache(api);
+ fillVolumeStatsCache(storagePool.getHostAddress());
+ }
+ String volumeKey = linstorAddr + "/" + LinstorUtil.RSC_PREFIX + volumeId;
+ Pair<Long, Long> sizePair = volumeStats.get(volumeKey);
+ if (sizePair == null) {
+ s_logger.warn(String.format("Volumestats for %s not found in cache", volumeKey));
}
- return volumeStats.get(LinstorUtil.RSC_PREFIX + volumeId);
+ return sizePair;
}
}