diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotDataFactoryImpl.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotDataFactoryImpl.java index 5af5260c340..fa7772a979d 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotDataFactoryImpl.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotDataFactoryImpl.java @@ -74,6 +74,11 @@ public class SnapshotDataFactoryImpl implements SnapshotDataFactory { @Override public SnapshotInfo getSnapshot(DataObject obj, DataStore store) { - throw new CloudRuntimeException("not implemented yet"); + SnapshotVO snapshot = snapshotDao.findByIdIncludingRemoved(obj.getId()); + if (snapshot == null) { + throw new CloudRuntimeException("Can't find snapshot: " + obj.getId()); + } + SnapshotObject so = SnapshotObject.getSnapshotObject(snapshot, store); + return so; } } diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStateMachineManagerImpl.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStateMachineManagerImpl.java index ad65deb43fd..c2213b67cf7 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStateMachineManagerImpl.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStateMachineManagerImpl.java @@ -26,7 +26,7 @@ SnapshotStateMachineManager { stateMachine.addTransition(Snapshot.State.Creating, Event.OperationFailed, Snapshot.State.Error); stateMachine.addTransition(Snapshot.State.CreatedOnPrimary, Event.BackupToSecondary, Snapshot.State.BackingUp); stateMachine.addTransition(Snapshot.State.BackingUp, Event.OperationSucceeded, Snapshot.State.BackedUp); - stateMachine.addTransition(Snapshot.State.BackingUp, Event.OperationFailed, Snapshot.State.Error); + stateMachine.addTransition(Snapshot.State.BackingUp, Event.OperationFailed, Snapshot.State.CreatedOnPrimary); stateMachine.registerListener(new SnapshotStateListener()); } diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/strategy/AncientSnasphotStrategy.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/strategy/AncientSnasphotStrategy.java index 8d72be2098f..b2a58a4b9f1 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/strategy/AncientSnasphotStrategy.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/strategy/AncientSnasphotStrategy.java @@ -180,7 +180,10 @@ public class AncientSnasphotStrategy implements SnapshotStrategy { try { SnapshotVO preSnapshotVO = this.snapshotMgr.getParentSnapshot(volume, snapshot); - String preSnapshotPath = preSnapshotVO.getPath(); + String preSnapshotPath = null; + if (preSnapshotVO != null) { + preSnapshotPath = preSnapshotVO.getPath(); + } SnapshotVO snapshotVO = this.snapshotDao.findById(snapshot.getId()); // The snapshot was successfully created if (preSnapshotPath != null && preSnapshotPath.equals(result.getPath())) { @@ -238,6 +241,11 @@ public class AncientSnasphotStrategy implements SnapshotStrategy { } catch (Exception e) { s_logger.debug("Failed to create snapshot: ", e); snapResult.setResult(e.toString()); + try { + snapshot.processEvent(Snapshot.Event.OperationFailed); + } catch (NoTransitionException e1) { + s_logger.debug("Failed to change snapshot state: " + e1.toString()); + } } future.complete(snapResult); @@ -263,19 +271,30 @@ public class AncientSnasphotStrategy implements SnapshotStrategy { s_logger.debug("Failed to update snapshot state due to " + nte.getMessage()); throw new CloudRuntimeException("Failed to update snapshot state due to " + nte.getMessage()); } + AsyncCallFuture future = new AsyncCallFuture(); - - CreateSnapshotContext context = new CreateSnapshotContext( - null, volume, snapshot, future); - AsyncCallbackDispatcher caller = AsyncCallbackDispatcher - .create(this); - caller.setCallback( - caller.getTarget().createSnapshotAsyncCallback(null, null)) - .setContext(context); - PrimaryDataStoreDriver primaryStore = (PrimaryDataStoreDriver)volume.getDataStore().getDriver(); - - primaryStore.takeSnapshot(snapshot, caller); + try { + CreateSnapshotContext context = new CreateSnapshotContext( + null, volume, snapshot, future); + AsyncCallbackDispatcher caller = AsyncCallbackDispatcher + .create(this); + caller.setCallback( + caller.getTarget().createSnapshotAsyncCallback(null, null)) + .setContext(context); + PrimaryDataStoreDriver primaryStore = (PrimaryDataStoreDriver)volume.getDataStore().getDriver(); + primaryStore.takeSnapshot(snapshot, caller); + } catch (Exception e) { + s_logger.debug("Failed to take snapshot: " + snapshot.getId(), e); + try { + snapshot.processEvent(Snapshot.Event.OperationFailed); + } catch (NoTransitionException e1) { + s_logger.debug("Failed to change state for event: OperationFailed" , e); + } + throw new CloudRuntimeException("Failed to take snapshot" + snapshot.getId()); + } + SnapshotResult result; + try { result = future.get(); if (result.isFailed()) { @@ -390,6 +409,11 @@ public class AncientSnasphotStrategy implements SnapshotStrategy { } catch (Exception e) { s_logger.debug("Failed to copy snapshot", e); result.setResult("Failed to copy snapshot:" +e.toString()); + try { + snapObj.processEvent(Snapshot.Event.OperationFailed); + } catch (NoTransitionException e1) { + s_logger.debug("Failed to change state: " + e1.toString()); + } future.complete(result); } diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/AncientPrimaryDataStoreDriverImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/AncientPrimaryDataStoreDriverImpl.java index 657ba80e971..440cb8c5ea0 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/AncientPrimaryDataStoreDriverImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/AncientPrimaryDataStoreDriverImpl.java @@ -288,22 +288,31 @@ public class AncientPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver @Override public void takeSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback callback) { - VolumeInfo volume = snapshot.getBaseVolume(); - String vmName = this.volumeMgr.getVmNameOnVolume(volume); - SnapshotVO preSnapshotVO = this.snapshotMgr.getParentSnapshot(volume, snapshot); - StoragePool srcPool = (StoragePool)volume.getDataStore(); + CreateCmdResult result = null; + try { + VolumeInfo volume = snapshot.getBaseVolume(); + String vmName = this.volumeMgr.getVmNameOnVolume(volume); + SnapshotVO preSnapshotVO = this.snapshotMgr.getParentSnapshot(volume, snapshot); + String parentSnapshotPath = null; + if (preSnapshotVO != null) { + parentSnapshotPath = preSnapshotVO.getPath(); + } + StoragePool srcPool = (StoragePool)volume.getDataStore(); + + ManageSnapshotCommand cmd = new ManageSnapshotCommand(snapshot.getId(), volume.getPath(), srcPool, parentSnapshotPath, snapshot.getName(), vmName); - ManageSnapshotCommand cmd = new ManageSnapshotCommand(snapshot.getId(), volume.getPath(), srcPool, preSnapshotVO.getPath(), snapshot.getName(), vmName); - - ManageSnapshotAnswer answer = (ManageSnapshotAnswer) this.snapshotMgr.sendToPool(volume, cmd); - - CreateCmdResult result = null; - if ((answer != null) && answer.getResult()) { - result = new CreateCmdResult(answer.getSnapshotPath(), null); - } else { - result = new CreateCmdResult(null, null); - } - + ManageSnapshotAnswer answer = (ManageSnapshotAnswer) this.snapshotMgr.sendToPool(volume, cmd); + + if ((answer != null) && answer.getResult()) { + result = new CreateCmdResult(answer.getSnapshotPath(), null); + } else { + result = new CreateCmdResult(null, null); + } + } catch (Exception e) { + s_logger.debug("Failed to take snapshot: " + snapshot.getId(), e); + result = new CreateCmdResult(null, null); + result.setResult(e.toString()); + } callback.complete(result); } diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java index 7df99d67be2..ed48bd1b45b 100755 --- a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java @@ -351,6 +351,10 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, throw new CloudRuntimeException("Can't find snapshot:" + snapshotId); } + if (snapshot.getState() == Snapshot.State.BackedUp) { + return snapshot; + } + SnapshotStrategy strategy = null; for (SnapshotStrategy st : snapshotStrategies) { if (st.canHandle(snapshot)) {