Skip to content

Commit ae7693f

Browse files
[KVM] Fix revert volume snapshot after volume migration
1 parent 85df82c commit ae7693f

4 files changed

Lines changed: 33 additions & 10 deletions

File tree

engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotResult;
3737
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotService;
3838
import org.apache.cloudstack.engine.subsystem.api.storage.StorageCacheManager;
39+
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
3940
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
4041
import org.apache.cloudstack.framework.async.AsyncCallFuture;
4142
import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher;
@@ -79,6 +80,8 @@ public class SnapshotServiceImpl implements SnapshotService {
7980
StorageCacheManager _cacheMgr;
8081
@Inject
8182
private SnapshotDetailsDao _snapshotDetailsDao;
83+
@Inject
84+
VolumeDataFactory volFactory;
8285

8386
static private class CreateSnapshotContext<T> extends AsyncRpcContext<T> {
8487
final SnapshotInfo snapshot;
@@ -428,11 +431,15 @@ public boolean deleteSnapshot(SnapshotInfo snapInfo) {
428431

429432
@Override
430433
public boolean revertSnapshot(SnapshotInfo snapshot) {
434+
PrimaryDataStore store = null;
435+
VolumeInfo volumeInfo = volFactory.getVolume(snapshot.getVolumeId(), DataStoreRole.Primary);
431436
SnapshotInfo snapshotOnPrimaryStore = _snapshotFactory.getSnapshot(snapshot.getId(), DataStoreRole.Primary);
432437
if (snapshotOnPrimaryStore == null) {
433-
throw new CloudRuntimeException("Cannot find an entry for snapshot " + snapshot.getId() + " on primary storage pools");
438+
s_logger.warn("Cannot find an entry for snapshot " + snapshot.getId() + " on primary storage pools, searching with volume's primary storage pool");
439+
store = (PrimaryDataStore)volumeInfo.getDataStore();
440+
} else {
441+
store = (PrimaryDataStore)snapshotOnPrimaryStore.getDataStore();
434442
}
435-
PrimaryDataStore store = (PrimaryDataStore)snapshotOnPrimaryStore.getDataStore();
436443

437444
AsyncCallFuture<SnapshotResult> future = new AsyncCallFuture<SnapshotResult>();
438445
RevertSnapshotContext<CommandResult> context = new RevertSnapshotContext<CommandResult>(null, snapshot, future);

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

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -178,19 +178,21 @@ protected void revertVolumeToSnapshot(SnapshotObjectTO snapshotOnPrimaryStorage,
178178
* and the snapshot path from the primary storage.
179179
*/
180180
protected Pair<String, SnapshotObjectTO> getSnapshot(SnapshotObjectTO snapshotOnPrimaryStorage, SnapshotObjectTO snapshotOnSecondaryStorage,
181-
KVMStoragePool kvmStoragePoolPrimary, KVMStoragePool kvmStoragePoolSecondary){
182-
String snapshotPath = snapshotOnPrimaryStorage.getPath();
183-
184-
if (Files.exists(Paths.get(snapshotPath))) {
185-
return new Pair<>(snapshotPath, snapshotOnPrimaryStorage);
181+
KVMStoragePool kvmStoragePoolPrimary, KVMStoragePool kvmStoragePoolSecondary) {
182+
String snapshotPath = null;
183+
if (snapshotOnPrimaryStorage != null) {
184+
snapshotPath = snapshotOnPrimaryStorage.getPath();
185+
if (Files.exists(Paths.get(snapshotPath))) {
186+
return new Pair<>(snapshotPath, snapshotOnPrimaryStorage);
187+
}
186188
}
187189

188190
if (kvmStoragePoolSecondary == null) {
189191
throw new CloudRuntimeException(String.format("Snapshot [%s] does not exists on secondary storage, unable to revert volume [%s] to it.",
190192
snapshotOnSecondaryStorage, snapshotOnSecondaryStorage.getVolume()));
191193
}
192194

193-
s_logger.trace(String.format("Snapshot [%s] does not exists on primary storage [%s], searching snapshot [%s] on secondary storage [%s].", snapshotOnPrimaryStorage,
195+
s_logger.trace(String.format("Snapshot does not exists on primary storage [%s], searching snapshot [%s] on secondary storage [%s].",
194196
kvmStoragePoolPrimary, snapshotOnSecondaryStorage, kvmStoragePoolSecondary));
195197

196198
String snapshotPathOnSecondaryStorage = snapshotOnSecondaryStorage.getPath();

plugins/storage/volume/datera/src/main/java/org/apache/cloudstack/storage/datastore/driver/DateraPrimaryDataStoreDriver.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1536,6 +1536,7 @@ private void deleteTemplate(TemplateInfo templateInfo, long storagePoolId)
15361536

15371537
/**
15381538
* Revert snapshot for a volume
1539+
*
15391540
* @param snapshotInfo Information about volume snapshot
15401541
* @param snapshotOnPrimaryStore Not used
15411542
* @throws CloudRuntimeException

plugins/storage/volume/default/src/main/java/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import org.apache.cloudstack.engine.subsystem.api.storage.StorageAction;
4242
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory;
4343
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
44+
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
4445
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
4546
import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
4647
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
@@ -121,6 +122,8 @@ public Map<String, String> getCapabilities() {
121122
TemplateManager templateManager;
122123
@Inject
123124
TemplateDataFactory templateDataFactory;
125+
@Inject
126+
VolumeDataFactory volFactory;
124127

125128
@Override
126129
public DataTO getTO(DataObject data) {
@@ -379,11 +382,21 @@ public void takeSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback<CreateCm
379382

380383
@Override
381384
public void revertSnapshot(SnapshotInfo snapshot, SnapshotInfo snapshotOnPrimaryStore, AsyncCompletionCallback<CommandResult> callback) {
382-
RevertSnapshotCommand cmd = new RevertSnapshotCommand((SnapshotObjectTO)snapshot.getTO(), (SnapshotObjectTO)snapshotOnPrimaryStore.getTO());
385+
SnapshotObjectTO dataOnPrimaryStorage = null;
386+
if (snapshotOnPrimaryStore != null) {
387+
dataOnPrimaryStorage = (SnapshotObjectTO)snapshotOnPrimaryStore.getTO();
388+
}
389+
RevertSnapshotCommand cmd = new RevertSnapshotCommand((SnapshotObjectTO)snapshot.getTO(), dataOnPrimaryStorage);
383390

384391
CommandResult result = new CommandResult();
385392
try {
386-
EndPoint ep = epSelector.select(snapshotOnPrimaryStore);
393+
EndPoint ep = null;
394+
if (snapshotOnPrimaryStore != null) {
395+
ep = epSelector.select(snapshotOnPrimaryStore);
396+
} else {
397+
VolumeInfo volumeInfo = volFactory.getVolume(snapshot.getVolumeId(), DataStoreRole.Primary);
398+
ep = epSelector.select(volumeInfo);
399+
}
387400
if ( ep == null ){
388401
String errMsg = "No remote endpoint to send RevertSnapshotCommand, check if host or ssvm is down?";
389402
s_logger.error(errMsg);

0 commit comments

Comments
 (0)