@@ -643,6 +643,11 @@ public StrategyPriority canHandle(Snapshot snapshot, Long zoneId, SnapshotOperat
643643 return StrategyPriority .DEFAULT ;
644644 }
645645
646+ // Check if this is a CLVM volume with snapshot backed up to secondary storage
647+ if (isSnapshotStoredOnSecondaryForCLVMVolume (snapshot , volumeVO )) {
648+ return StrategyPriority .DEFAULT ;
649+ }
650+
646651 return StrategyPriority .CANT_HANDLE ;
647652 }
648653 if (zoneId != null && SnapshotOperation .DELETE .equals (op )) {
@@ -691,4 +696,32 @@ protected boolean isSnapshotStoredOnSameZoneStoreForQCOW2Volume(Snapshot snapsho
691696 dataStoreMgr .getStoreZoneId (s .getDataStoreId (), s .getRole ()), volumeVO .getDataCenterId ()));
692697 }
693698
699+ /**
700+ * Checks if a CLVM volume snapshot is stored on secondary storage in the same zone.
701+ * CLVM snapshots are backed up to secondary storage and removed from primary storage.
702+ */
703+ protected boolean isSnapshotStoredOnSecondaryForCLVMVolume (Snapshot snapshot , VolumeVO volumeVO ) {
704+ if (volumeVO == null ) {
705+ return false ;
706+ }
707+
708+ Long poolId = volumeVO .getPoolId ();
709+ if (poolId == null ) {
710+ return false ;
711+ }
712+
713+ StoragePool pool = (StoragePool ) dataStoreMgr .getDataStore (poolId , DataStoreRole .Primary );
714+ if (pool == null || pool .getPoolType () != StoragePoolType .CLVM ) {
715+ return false ;
716+ }
717+
718+ List <SnapshotDataStoreVO > snapshotStores = snapshotStoreDao .listReadyBySnapshot (snapshot .getId (), DataStoreRole .Image );
719+ if (CollectionUtils .isEmpty (snapshotStores )) {
720+ return false ;
721+ }
722+
723+ return snapshotStores .stream ().anyMatch (s -> Objects .equals (
724+ dataStoreMgr .getStoreZoneId (s .getDataStoreId (), s .getRole ()), volumeVO .getDataCenterId ()));
725+ }
726+
694727}
0 commit comments