From 08ff17d5f9882e56ee194e0f23c9b1dceac09bcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20B=C3=B6ck?= Date: Fri, 12 Jun 2026 12:05:30 -0300 Subject: [PATCH] Snapshot state normalization for failure due to malformed secondary storage heuristic --- .../storage/snapshot/SnapshotManagerImpl.java | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/server/src/main/java/com/cloud/storage/snapshot/SnapshotManagerImpl.java b/server/src/main/java/com/cloud/storage/snapshot/SnapshotManagerImpl.java index d60bff095406..8d058193f5ba 100755 --- a/server/src/main/java/com/cloud/storage/snapshot/SnapshotManagerImpl.java +++ b/server/src/main/java/com/cloud/storage/snapshot/SnapshotManagerImpl.java @@ -1633,11 +1633,17 @@ public SnapshotInfo takeSnapshot(VolumeInfo volume) throws ResourceAllocationExc boolean backupSnapToSecondary = isBackupSnapshotToSecondaryForZone(volume.getDataCenterId()); if (isKvmAndFileBasedStorage && backupSnapToSecondary) { - DataStore imageStore = snapshotSrv.findSnapshotImageStore(snapshot); - if (imageStore == null) { - throw new CloudRuntimeException(String.format("Could not find any secondary storage to allocate snapshot [%s].", snapshot)); + try { + DataStore imageStore = snapshotSrv.findSnapshotImageStore(snapshot); + if (imageStore == null) { + throw new CloudRuntimeException(String.format("Could not find any secondary storage to allocate snapshot [%s].", snapshot)); + } + snapshot.setImageStore(imageStore); + } catch (CloudRuntimeException ex) { + logger.error("There was an error while selecting image store for snapshot: {}", ex.getMessage()); + handleErrorInUncreatedSnapshot(snapshotId); + throw new CloudRuntimeException(ex.getMessage()); } - snapshot.setImageStore(imageStore); } updateSnapshotPayload(volume.getPoolId(), payload, isKvmAndFileBasedStorage, clusterId); @@ -1738,6 +1744,12 @@ private void postSnapshotDirectlyToSecondary(SnapshotInfo snapshot, SnapshotInfo snapshotDetailsDao.removeDetail(snapshotOnPrimary.getId(), AsyncJob.Constants.MS_ID); } + private void handleErrorInUncreatedSnapshot(Long snapshotId) { + SnapshotVO snapshot = _snapshotDao.findById(snapshotId); + snapshot.setState(Snapshot.State.Error); + _snapshotDao.persist(snapshot); + } + @Override public boolean isHypervisorKvmAndFileBasedStorage(VolumeInfo volumeInfo, StoragePool storagePool) { Set fileBasedStores = Set.of(Storage.StoragePoolType.SharedMountPoint, Storage.StoragePoolType.NetworkFilesystem, Storage.StoragePoolType.Filesystem);