diff --git a/plugins/storage/volume/linstor/CHANGELOG.md b/plugins/storage/volume/linstor/CHANGELOG.md index fb247eef5df..e27e521bcd8 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-02-21] + +### Fixed + +- Always try to delete cs-...-rst resource before doing a snapshot backup + ## [2025-01-27] ### 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 1afba442be9..87dad560f29 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 @@ -1119,6 +1119,8 @@ public class LinstorPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver String snapshotName, String restoredName) throws ApiException { final String rscGrp = getRscGrp(storagePoolVO); + // try to delete -rst resource, could happen if the copy failed and noone deleted it. + deleteResourceDefinition(storagePoolVO, restoredName); ResourceDefinitionCreate rdc = createResourceDefinitionCreate(restoredName, rscGrp); api.resourceDefinitionCreate(rdc); @@ -1261,19 +1263,22 @@ public class LinstorPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver throws ApiException { Answer answer; String restoreName = rscName + "-rst"; - String devName = restoreResourceFromSnapshot(api, pool, rscName, snapshotName, restoreName); + try { + String devName = restoreResourceFromSnapshot(api, pool, rscName, snapshotName, restoreName); - Optional optEPAny = getLinstorEP(api, restoreName); - if (optEPAny.isPresent()) { - // patch the src device path to the temporary linstor resource - snapshotObject.setPath(devName); - origCmd.setSrcTO(snapshotObject.getTO()); - answer = optEPAny.get().sendMessage(origCmd); - } else{ - answer = new Answer(origCmd, false, "Unable to get matching Linstor endpoint."); + Optional optEPAny = getLinstorEP(api, restoreName); + if (optEPAny.isPresent()) { + // patch the src device path to the temporary linstor resource + snapshotObject.setPath(devName); + origCmd.setSrcTO(snapshotObject.getTO()); + answer = optEPAny.get().sendMessage(origCmd); + } else{ + answer = new Answer(origCmd, false, "Unable to get matching Linstor endpoint."); + } + } finally { + // delete the temporary resource, noop if already gone + api.resourceDefinitionDelete(restoreName); } - // delete the temporary resource, noop if already gone - api.resourceDefinitionDelete(restoreName); return answer; } diff --git a/server/src/main/java/com/cloud/server/StatsCollector.java b/server/src/main/java/com/cloud/server/StatsCollector.java index 31d8c80329c..cbd175eece2 100644 --- a/server/src/main/java/com/cloud/server/StatsCollector.java +++ b/server/src/main/java/com/cloud/server/StatsCollector.java @@ -718,10 +718,10 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc getDynamicDataFromDB(); long interval = (Long) dbStats.get(uptime) - lastUptime; long activity = (Long) dbStats.get(queries) - lastQueries; - loadHistory.add(0, Double.valueOf(activity / interval)); + loadHistory.add(0, interval == 0 ? -1 : Double.valueOf(activity / interval)); int maxsize = DATABASE_SERVER_LOAD_HISTORY_RETENTION_NUMBER.value(); while (loadHistory.size() > maxsize) { - loadHistory.remove(maxsize - 1); + loadHistory.remove(maxsize); } } catch (Throwable e) { // pokemon catch to make sure the thread stays running