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; }