This is an automated email from the ASF dual-hosted git repository.

sureshanaparti pushed a commit to branch 4.22
in repository https://gitbox.apache.org/repos/asf/cloudstack.git


The following commit(s) were added to refs/heads/4.22 by this push:
     new 2a60305792c Fix snapshot chaining on Xen (#12597)
2a60305792c is described below

commit 2a60305792c19911012469a1ef8e80deec960a47
Author: João Jandre <[email protected]>
AuthorDate: Fri Apr 10 02:35:26 2026 -0300

    Fix snapshot chaining on Xen (#12597)
---
 .../storage/datastore/db/SnapshotDataStoreDao.java        |  2 ++
 .../storage/datastore/db/SnapshotDataStoreDaoImpl.java    | 15 +++++++++++++++
 .../storage/snapshot/DefaultSnapshotStrategy.java         |  2 +-
 .../storage/snapshot/DefaultSnapshotStrategyTest.java     |  7 +------
 4 files changed, 19 insertions(+), 7 deletions(-)

diff --git 
a/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java
 
b/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java
index 6aeee1ad1cc..3329983d711 100644
--- 
a/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java
+++ 
b/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java
@@ -51,6 +51,8 @@ StateDao<ObjectInDataStoreStateMachine.State, 
ObjectInDataStoreStateMachine.Even
 
     SnapshotDataStoreVO findBySnapshotIdAndDataStoreRoleAndState(long 
snapshotId, DataStoreRole role, ObjectInDataStoreStateMachine.State state);
 
+    List<SnapshotDataStoreVO> listBySnapshotIdAndDataStoreRoleAndStateIn(long 
snapshotId, DataStoreRole role, ObjectInDataStoreStateMachine.State... state);
+
     List<SnapshotDataStoreVO> listReadyByVolumeIdAndCheckpointPathNotNull(long 
volumeId);
 
     SnapshotDataStoreVO findOneBySnapshotId(long snapshotId, long zoneId);
diff --git 
a/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDaoImpl.java
 
b/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDaoImpl.java
index bbb2b4f3a88..8b7a2b78de7 100644
--- 
a/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDaoImpl.java
+++ 
b/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDaoImpl.java
@@ -68,6 +68,7 @@ public class SnapshotDataStoreDaoImpl extends 
GenericDaoBase<SnapshotDataStoreVO
     protected SearchBuilder<SnapshotDataStoreVO> 
searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq;
     private SearchBuilder<SnapshotDataStoreVO> stateSearch;
     private SearchBuilder<SnapshotDataStoreVO> idStateNinSearch;
+    private SearchBuilder<SnapshotDataStoreVO> idEqRoleEqStateInSearch;
     protected SearchBuilder<SnapshotVO> snapshotVOSearch;
     private SearchBuilder<SnapshotDataStoreVO> snapshotCreatedSearch;
     private SearchBuilder<SnapshotDataStoreVO> dataStoreAndInstallPathSearch;
@@ -151,6 +152,11 @@ public class SnapshotDataStoreDaoImpl extends 
GenericDaoBase<SnapshotDataStoreVO
         idStateNinSearch.and(STATE, idStateNinSearch.entity().getState(), 
SearchCriteria.Op.NOTIN);
         idStateNinSearch.done();
 
+        idEqRoleEqStateInSearch = createSearchBuilder();
+        idEqRoleEqStateInSearch.and(SNAPSHOT_ID, 
idEqRoleEqStateInSearch.entity().getSnapshotId(), SearchCriteria.Op.EQ);
+        idEqRoleEqStateInSearch.and(STORE_ROLE, 
idEqRoleEqStateInSearch.entity().getRole(), SearchCriteria.Op.EQ);
+        idEqRoleEqStateInSearch.and(STATE, 
idEqRoleEqStateInSearch.entity().getState(), SearchCriteria.Op.IN);
+
         snapshotVOSearch = snapshotDao.createSearchBuilder();
         snapshotVOSearch.and(VOLUME_ID, 
snapshotVOSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
         snapshotVOSearch.done();
@@ -387,6 +393,15 @@ public class SnapshotDataStoreDaoImpl extends 
GenericDaoBase<SnapshotDataStoreVO
         return findOneBy(sc);
     }
 
+    @Override
+    public List<SnapshotDataStoreVO> 
listBySnapshotIdAndDataStoreRoleAndStateIn(long snapshotId, DataStoreRole role, 
State... state) {
+        SearchCriteria<SnapshotDataStoreVO> sc = 
idEqRoleEqStateInSearch.create();
+        sc.setParameters(SNAPSHOT_ID, snapshotId);
+        sc.setParameters(STORE_ROLE, role);
+        sc.setParameters(STATE, (Object[])state);
+        return listBy(sc);
+    }
+
     @Override
     public SnapshotDataStoreVO findOneBySnapshotId(long snapshotId, long 
zoneId) {
         try (TransactionLegacy transactionLegacy = 
TransactionLegacy.currentTxn()) {
diff --git 
a/engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/snapshot/DefaultSnapshotStrategy.java
 
b/engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/snapshot/DefaultSnapshotStrategy.java
index 0e38df5a2b1..3c037f05639 100644
--- 
a/engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/snapshot/DefaultSnapshotStrategy.java
+++ 
b/engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/snapshot/DefaultSnapshotStrategy.java
@@ -120,7 +120,7 @@ public class DefaultSnapshotStrategy extends 
SnapshotStrategyBase {
     private final List<Snapshot.State> snapshotStatesAbleToDeleteSnapshot = 
Arrays.asList(Snapshot.State.Destroying, Snapshot.State.Destroyed, 
Snapshot.State.Error, Snapshot.State.Hidden);
 
     public SnapshotDataStoreVO getSnapshotImageStoreRef(long snapshotId, long 
zoneId) {
-        List<SnapshotDataStoreVO> snaps = 
snapshotStoreDao.listReadyBySnapshot(snapshotId, DataStoreRole.Image);
+        List<SnapshotDataStoreVO> snaps = 
snapshotStoreDao.listBySnapshotIdAndDataStoreRoleAndStateIn(snapshotId, 
DataStoreRole.Image, State.Ready, State.Hidden);
         for (SnapshotDataStoreVO ref : snaps) {
             if (zoneId == dataStoreMgr.getStoreZoneId(ref.getDataStoreId(), 
ref.getRole())) {
                 return ref;
diff --git 
a/engine/storage/snapshot/src/test/java/org/apache/cloudstack/storage/snapshot/DefaultSnapshotStrategyTest.java
 
b/engine/storage/snapshot/src/test/java/org/apache/cloudstack/storage/snapshot/DefaultSnapshotStrategyTest.java
index 53f98c18f1b..41bfaa6f0c7 100644
--- 
a/engine/storage/snapshot/src/test/java/org/apache/cloudstack/storage/snapshot/DefaultSnapshotStrategyTest.java
+++ 
b/engine/storage/snapshot/src/test/java/org/apache/cloudstack/storage/snapshot/DefaultSnapshotStrategyTest.java
@@ -257,11 +257,6 @@ public class DefaultSnapshotStrategyTest {
 
     @Test
     public void testGetSnapshotImageStoreRefNull() {
-        SnapshotDataStoreVO ref1 = Mockito.mock(SnapshotDataStoreVO.class);
-        Mockito.when(ref1.getDataStoreId()).thenReturn(1L);
-        Mockito.when(ref1.getRole()).thenReturn(DataStoreRole.Image);
-        
Mockito.when(snapshotDataStoreDao.listReadyBySnapshot(Mockito.anyLong(), 
Mockito.any(DataStoreRole.class))).thenReturn(List.of(ref1));
-        Mockito.when(dataStoreManager.getStoreZoneId(1L, 
DataStoreRole.Image)).thenReturn(2L);
         
Assert.assertNull(defaultSnapshotStrategySpy.getSnapshotImageStoreRef(1L, 1L));
     }
 
@@ -270,7 +265,7 @@ public class DefaultSnapshotStrategyTest {
         SnapshotDataStoreVO ref1 = Mockito.mock(SnapshotDataStoreVO.class);
         Mockito.when(ref1.getDataStoreId()).thenReturn(1L);
         Mockito.when(ref1.getRole()).thenReturn(DataStoreRole.Image);
-        
Mockito.when(snapshotDataStoreDao.listReadyBySnapshot(Mockito.anyLong(), 
Mockito.any(DataStoreRole.class))).thenReturn(List.of(ref1));
+        
Mockito.when(snapshotDataStoreDao.listBySnapshotIdAndDataStoreRoleAndStateIn(Mockito.anyLong(),
 Mockito.any(DataStoreRole.class), Mockito.any(), 
Mockito.any())).thenReturn(List.of(ref1));
         Mockito.when(dataStoreManager.getStoreZoneId(1L, 
DataStoreRole.Image)).thenReturn(1L);
         
Assert.assertNotNull(defaultSnapshotStrategySpy.getSnapshotImageStoreRef(1L, 
1L));
     }

Reply via email to