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