Skip to content

Commit 36db8ae

Browse files
Srivastava, PiyushSrivastava, Piyush
authored andcommitted
Merge branch 'main' of https://github.com/NetApp/cloudstack into feature/CSTACKEX-122
2 parents 121bbfe + fccaf83 commit 36db8ae

File tree

29 files changed

+3452
-279
lines changed

29 files changed

+3452
-279
lines changed

engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDaoImpl.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase<SnapshotDataStoreVO
6868
protected SearchBuilder<SnapshotDataStoreVO> searchFilteringStoreIdEqStateEqStoreRoleEqIdEqUpdateCountEqSnapshotIdEqVolumeIdEq;
6969
private SearchBuilder<SnapshotDataStoreVO> stateSearch;
7070
private SearchBuilder<SnapshotDataStoreVO> idStateNeqSearch;
71+
private SearchBuilder<SnapshotDataStoreVO> idStateNinSearch;
7172
protected SearchBuilder<SnapshotVO> snapshotVOSearch;
7273
private SearchBuilder<SnapshotDataStoreVO> snapshotCreatedSearch;
7374
private SearchBuilder<SnapshotDataStoreVO> dataStoreAndInstallPathSearch;
@@ -151,6 +152,11 @@ public boolean configure(String name, Map<String, Object> params) throws Configu
151152
idStateNeqSearch.and(STATE, idStateNeqSearch.entity().getState(), SearchCriteria.Op.NEQ);
152153
idStateNeqSearch.done();
153154

155+
idStateNinSearch = createSearchBuilder();
156+
idStateNinSearch.and(SNAPSHOT_ID, idStateNinSearch.entity().getSnapshotId(), SearchCriteria.Op.EQ);
157+
idStateNinSearch.and(STATE, idStateNinSearch.entity().getState(), SearchCriteria.Op.NIN);
158+
idStateNinSearch.done();
159+
154160
snapshotVOSearch = snapshotDao.createSearchBuilder();
155161
snapshotVOSearch.and(VOLUME_ID, snapshotVOSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
156162
snapshotVOSearch.done();
@@ -488,7 +494,7 @@ public List<SnapshotDataStoreVO> findBySnapshotIdWithNonDestroyedState(long snap
488494

489495
@Override
490496
public List<SnapshotDataStoreVO> findBySnapshotIdAndNotInDestroyedHiddenState(long snapshotId) {
491-
SearchCriteria<SnapshotDataStoreVO> sc = idStateNeqSearch.create();
497+
SearchCriteria<SnapshotDataStoreVO> sc = idStateNinSearch.create();
492498
sc.setParameters(SNAPSHOT_ID, snapshotId);
493499
sc.setParameters(STATE, State.Destroyed.name(), State.Hidden.name());
494500
return listBy(sc);

engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/vmsnapshot/KvmFileBasedStorageVmSnapshotStrategy.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ public class KvmFileBasedStorageVmSnapshotStrategy extends StorageVMSnapshotStra
7777

7878
private static final List<Storage.StoragePoolType> supportedStoragePoolTypes = List.of(Storage.StoragePoolType.Filesystem, Storage.StoragePoolType.NetworkFilesystem, Storage.StoragePoolType.SharedMountPoint);
7979

80+
private static final String ONTAP_PROVIDER_NAME = "NetApp ONTAP";
81+
8082
@Inject
8183
protected SnapshotDataStoreDao snapshotDataStoreDao;
8284

@@ -325,6 +327,11 @@ public StrategyPriority canHandle(Long vmId, Long rootPoolId, boolean snapshotMe
325327
List<VolumeVO> volumes = volumeDao.findByInstance(vmId);
326328
for (VolumeVO volume : volumes) {
327329
StoragePoolVO storagePoolVO = storagePool.findById(volume.getPoolId());
330+
if (storagePoolVO.isManaged() && ONTAP_PROVIDER_NAME.equals(storagePoolVO.getStorageProviderName())) {
331+
logger.debug(String.format("%s as the VM has a volume on ONTAP managed storage pool [%s]. " +
332+
"ONTAP managed storage has its own dedicated VM snapshot strategy.", cantHandleLog, storagePoolVO.getName()));
333+
return StrategyPriority.CANT_HANDLE;
334+
}
328335
if (!supportedStoragePoolTypes.contains(storagePoolVO.getPoolType())) {
329336
logger.debug(String.format("%s as the VM has a volume that is in a storage with unsupported type [%s].", cantHandleLog, storagePoolVO.getPoolType()));
330337
return StrategyPriority.CANT_HANDLE;
@@ -503,8 +510,9 @@ protected VMSnapshot takeVmSnapshotInternal(VMSnapshot vmSnapshot, Map<VolumeInf
503510
return processCreateVmSnapshotAnswer(vmSnapshot, volumeInfoToSnapshotObjectMap, createDiskOnlyVMSnapshotAnswer, userVm, vmSnapshotVO, virtualSize, parentSnapshotVo);
504511
}
505512

506-
logger.error("Disk-only VM snapshot for VM [{}] failed{}.", userVm.getUuid(), answer != null ? " due to" + answer.getDetails() : "");
507-
throw new CloudRuntimeException(String.format("Disk-only VM snapshot for VM [%s] failed.", userVm.getUuid()));
513+
String details = answer != null ? answer.getDetails() : String.format("No answer received from host [%s]. The host may be unreachable.", hostId);
514+
logger.error("Disk-only VM snapshot for VM [{}] failed due to: {}.", userVm.getUuid(), details);
515+
throw new CloudRuntimeException(String.format("Disk-only VM snapshot for VM [%s] failed due to: %s.", userVm.getUuid(), details));
508516
}
509517

510518
/**

plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreateDiskOnlyVMSnapshotCommandWrapper.java

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ protected Answer takeDiskOnlyVmSnapshotOfRunningVm(CreateDiskOnlyVmSnapshotComma
106106
return new CreateDiskOnlyVmSnapshotAnswer(cmd, false, errorMsg, null);
107107
}
108108
return new CreateDiskOnlyVmSnapshotAnswer(cmd, false, e.getMessage(), null);
109+
} catch (Exception e) {
110+
String errorMsg = String.format("Creation of disk-only VM snapshot for VM [%s] failed due to %s.", vmName, e.getMessage());
111+
logger.error(errorMsg, e);
112+
return new CreateDiskOnlyVmSnapshotAnswer(cmd, false, errorMsg, null);
109113
} finally {
110114
if (dm != null) {
111115
try {
@@ -146,21 +150,13 @@ protected Answer takeDiskOnlyVmSnapshotOfStoppedVm(CreateDiskOnlyVmSnapshotComma
146150
}
147151
} catch (LibvirtException | QemuImgException e) {
148152
logger.error("Exception while creating disk-only VM snapshot for VM [{}]. Deleting leftover deltas.", vmName, e);
149-
for (VolumeObjectTO volumeObjectTO : volumeObjectTos) {
150-
Pair<Long, String> volSizeAndNewPath = mapVolumeToSnapshotSizeAndNewVolumePath.get(volumeObjectTO.getUuid());
151-
PrimaryDataStoreTO primaryDataStoreTO = (PrimaryDataStoreTO) volumeObjectTO.getDataStore();
152-
KVMStoragePool kvmStoragePool = storagePoolMgr.getStoragePool(primaryDataStoreTO.getPoolType(), primaryDataStoreTO.getUuid());
153-
154-
if (volSizeAndNewPath == null) {
155-
continue;
156-
}
157-
try {
158-
Files.deleteIfExists(Path.of(kvmStoragePool.getLocalPathFor(volSizeAndNewPath.second())));
159-
} catch (IOException ex) {
160-
logger.warn("Tried to delete leftover snapshot at [{}] failed.", volSizeAndNewPath.second(), ex);
161-
}
162-
}
153+
cleanupLeftoverDeltas(volumeObjectTos, mapVolumeToSnapshotSizeAndNewVolumePath, storagePoolMgr);
163154
return new Answer(cmd, e);
155+
} catch (Exception e) {
156+
logger.error("Unexpected exception while creating disk-only VM snapshot for VM [{}]. Deleting leftover deltas.", vmName, e);
157+
cleanupLeftoverDeltas(volumeObjectTos, mapVolumeToSnapshotSizeAndNewVolumePath, storagePoolMgr);
158+
return new CreateDiskOnlyVmSnapshotAnswer(cmd, false,
159+
String.format("Creation of disk-only VM snapshot for VM [%s] failed due to %s.", vmName, e.getMessage()), null);
164160
}
165161

166162
return new CreateDiskOnlyVmSnapshotAnswer(cmd, true, null, mapVolumeToSnapshotSizeAndNewVolumePath);
@@ -192,6 +188,23 @@ protected Pair<String, Map<String, Pair<Long, String>>> createSnapshotXmlAndNewV
192188
return new Pair<>(snapshotXml, volumeObjectToNewPathMap);
193189
}
194190

191+
protected void cleanupLeftoverDeltas(List<VolumeObjectTO> volumeObjectTos, Map<String, Pair<Long, String>> mapVolumeToSnapshotSizeAndNewVolumePath, KVMStoragePoolManager storagePoolMgr) {
192+
for (VolumeObjectTO volumeObjectTO : volumeObjectTos) {
193+
Pair<Long, String> volSizeAndNewPath = mapVolumeToSnapshotSizeAndNewVolumePath.get(volumeObjectTO.getUuid());
194+
PrimaryDataStoreTO primaryDataStoreTO = (PrimaryDataStoreTO) volumeObjectTO.getDataStore();
195+
KVMStoragePool kvmStoragePool = storagePoolMgr.getStoragePool(primaryDataStoreTO.getPoolType(), primaryDataStoreTO.getUuid());
196+
197+
if (volSizeAndNewPath == null) {
198+
continue;
199+
}
200+
try {
201+
Files.deleteIfExists(Path.of(kvmStoragePool.getLocalPathFor(volSizeAndNewPath.second())));
202+
} catch (IOException ex) {
203+
logger.warn("Tried to delete leftover snapshot at [{}] failed.", volSizeAndNewPath.second(), ex);
204+
}
205+
}
206+
}
207+
195208
protected long getFileSize(String path) {
196209
return new File(path).length();
197210
}

plugins/storage/volume/ontap/pom.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,16 @@
8484
<artifactId>cloud-engine-storage-volume</artifactId>
8585
<version>${project.version}</version>
8686
</dependency>
87+
<dependency>
88+
<groupId>org.apache.cloudstack</groupId>
89+
<artifactId>cloud-engine-storage-snapshot</artifactId>
90+
<version>${project.version}</version>
91+
</dependency>
92+
<dependency>
93+
<groupId>org.apache.cloudstack</groupId>
94+
<artifactId>cloud-server</artifactId>
95+
<version>${project.version}</version>
96+
</dependency>
8797
<dependency>
8898
<groupId>io.swagger</groupId>
8999
<artifactId>swagger-annotations</artifactId>

0 commit comments

Comments
 (0)