You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ed...@apache.org on 2013/04/30 04:38:11 UTC

[2/5] git commit: updated refs/heads/object_store to 99dcb23

refactor snapshot


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/37cbe889
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/37cbe889
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/37cbe889

Branch: refs/heads/object_store
Commit: 37cbe8890faf2a445b6c34b7220978e982651481
Parents: 35264f7
Author: Edison Su <ed...@citrix.com>
Authored: Mon Apr 29 09:31:52 2013 -0700
Committer: Edison Su <su...@gmail.com>
Committed: Mon Apr 29 18:51:13 2013 -0700

----------------------------------------------------------------------
 api/src/com/cloud/storage/Snapshot.java            |    7 +-
 api/src/com/cloud/storage/VolumeApiService.java    |    3 +
 core/src/com/cloud/storage/SnapshotVO.java         |   61 +----
 core/src/com/cloud/storage/VMTemplateHostVO.java   |    6 +
 .../com/cloud/storage/VMTemplateStoragePoolVO.java |    5 +
 core/src/com/cloud/storage/VolumeHostVO.java       |    6 +
 .../subsystem/api/storage/DataObjectInStore.java   |    1 +
 .../subsystem/api/storage/SnapshotDataFactory.java |    4 +-
 .../engine/subsystem/api/storage/SnapshotInfo.java |    3 +
 .../subsystem/api/storage/SnapshotResult.java      |   25 ++
 .../subsystem/api/storage/SnapshotService.java     |    3 +-
 .../subsystem/api/storage/SnapshotStrategy.java    |   11 +
 .../subsystem/api/storage/VolumeService.java       |    2 +
 .../storage/command/CreateObjectAnswer.java        |   27 +-
 .../storage/command/CreateObjectCommand.java       |   12 +-
 .../storage/datastore/db/SnapshotDataStoreDao.java |    9 +-
 .../storage/datastore/db/SnapshotDataStoreVO.java  |   47 ++-
 .../storage/datastore/db/TemplateDataStoreVO.java  |    6 +-
 .../storage/datastore/db/VolumeDataStoreVO.java    |    6 +
 .../cloudstack/storage/to/SnapshotObjectTO.java    |   30 ++
 .../storage/motion/AncientDataMotionStrategy.java  |   57 +---
 engine/storage/snapshot/pom.xml                    |    5 +
 .../storage/snapshot/SnapshotDataFactoryImpl.java  |   37 +-
 .../storage/snapshot/SnapshotObject.java           |   51 ++-
 .../storage/snapshot/SnapshotServiceImpl.java      |  275 +++------------
 .../storage/snapshot/SnapshotStrategyBase.java     |   24 ++
 .../snapshot/XenserverSnapshotStrategy.java        |  200 +++++++++++
 .../datastore/ObjectInDataStoreManagerImpl.java    |   22 +-
 .../cloudstack/storage/db/ObjectInDataStoreVO.java |    6 +
 .../storage/image/db/SnapshotDataStoreDaoImpl.java |   45 +--
 .../storage/snapshot/SnapshotService.java          |   27 --
 .../storage/datastore/PrimaryDataStoreImpl.java    |    3 +-
 .../storage/volume/VolumeServiceImpl.java          |   21 ++
 .../xen/resource/XenServerStorageResource.java     |   86 ++---
 .../driver/SampleImageStoreDriverImpl.java         |    4 +-
 .../CloudStackPrimaryDataStoreDriverImpl.java      |   48 +--
 .../com/cloud/storage/CreateSnapshotPayload.java   |   14 +
 .../src/com/cloud/storage/StorageManagerImpl.java  |    2 +-
 .../src/com/cloud/storage/VolumeManagerImpl.java   |   44 +++
 server/src/com/cloud/storage/dao/SnapshotDao.java  |    3 +-
 .../src/com/cloud/storage/dao/SnapshotDaoImpl.java |    7 +-
 .../cloud/storage/snapshot/SnapshotManager.java    |    6 +-
 .../storage/snapshot/SnapshotManagerImpl.java      |  196 +++++++----
 43 files changed, 775 insertions(+), 682 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/37cbe889/api/src/com/cloud/storage/Snapshot.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/storage/Snapshot.java b/api/src/com/cloud/storage/Snapshot.java
index f71265c..0d58a14 100644
--- a/api/src/com/cloud/storage/Snapshot.java
+++ b/api/src/com/cloud/storage/Snapshot.java
@@ -18,12 +18,13 @@ package com.cloud.storage;
 
 import java.util.Date;
 
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.utils.fsm.StateObject;
 import org.apache.cloudstack.acl.ControlledEntity;
 import org.apache.cloudstack.api.Identity;
 import org.apache.cloudstack.api.InternalIdentity;
 
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.utils.fsm.StateObject;
+
 public interface Snapshot extends ControlledEntity, Identity, InternalIdentity, StateObject<Snapshot.State> {
     public enum Type {
         MANUAL,
@@ -85,8 +86,6 @@ public interface Snapshot extends ControlledEntity, Identity, InternalIdentity,
 
     long getVolumeId();
 
-    String getPath();
-
     String getName();
 
     Date getCreated();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/37cbe889/api/src/com/cloud/storage/VolumeApiService.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/storage/VolumeApiService.java b/api/src/com/cloud/storage/VolumeApiService.java
index 09a07d4..2f5364f 100644
--- a/api/src/com/cloud/storage/VolumeApiService.java
+++ b/api/src/com/cloud/storage/VolumeApiService.java
@@ -79,4 +79,7 @@ public interface VolumeApiService {
     Volume attachVolumeToVM(AttachVolumeCmd command);
 
     Volume detachVolumeFromVM(DetachVolumeCmd cmmd);
+
+	Snapshot takeSnapshot(Long volumeId, Long policyId)
+			throws ResourceAllocationException;
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/37cbe889/core/src/com/cloud/storage/SnapshotVO.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/storage/SnapshotVO.java b/core/src/com/cloud/storage/SnapshotVO.java
index dbfd7ba..4fc195c 100644
--- a/core/src/com/cloud/storage/SnapshotVO.java
+++ b/core/src/com/cloud/storage/SnapshotVO.java
@@ -49,10 +49,6 @@ public class SnapshotVO implements Snapshot {
     Long diskOfferingId;
 
     @Expose
-    @Column(name="path")
-    String path;
-
-    @Expose
     @Column(name="name")
     String name;
 
@@ -76,18 +72,6 @@ public class SnapshotVO implements Snapshot {
     @Column(name=GenericDao.REMOVED_COLUMN)
     Date removed;
 
-    @Column(name="backup_snap_id")
-    String backupSnapshotId;
-
-    @Column(name="swift_id")
-    Long swiftId;
-
-    @Column(name="s3_id")
-    Long s3Id;
-
-    @Column(name="prev_snap_id")
-    long prevSnapshotId;
-
     @Column(name="hypervisor_type")
     @Enumerated(value=EnumType.STRING)
     HypervisorType  hypervisorType;
@@ -103,19 +87,17 @@ public class SnapshotVO implements Snapshot {
         this.uuid = UUID.randomUUID().toString();
     }
 
-    public SnapshotVO(long dcId, long accountId, long domainId, Long volumeId, Long diskOfferingId, String path, String name, short snapshotType, String typeDescription, long size, HypervisorType hypervisorType ) {
+    public SnapshotVO(long dcId, long accountId, long domainId, Long volumeId, Long diskOfferingId, String name, short snapshotType, String typeDescription, long size, HypervisorType hypervisorType ) {
         this.dataCenterId = dcId;
         this.accountId = accountId;
         this.domainId = domainId;
         this.volumeId = volumeId;
         this.diskOfferingId = diskOfferingId;
-        this.path = path;
         this.name = name;
         this.snapshotType = snapshotType;
         this.typeDescription = typeDescription;
         this.size = size;
         this.state = State.Allocated;
-        this.prevSnapshotId = 0;
         this.hypervisorType = hypervisorType;
         this.version = "2.2";
         this.uuid = UUID.randomUUID().toString();
@@ -153,14 +135,6 @@ public class SnapshotVO implements Snapshot {
         this.volumeId = volumeId;
     }
 
-    @Override
-    public String getPath() {
-        return path;
-    }
-
-    public void setPath(String path) {
-        this.path = path;
-    }
 
     @Override
     public String getName() {
@@ -179,14 +153,6 @@ public class SnapshotVO implements Snapshot {
         return Type.values()[snapshotType];
     }
 
-    public Long getSwiftId() {
-        return swiftId;
-    }
-
-    public void setSwiftId(Long swiftId) {
-        this.swiftId = swiftId;
-    }
-
     @Override
     public HypervisorType getHypervisorType() {
         return hypervisorType;
@@ -242,22 +208,6 @@ public class SnapshotVO implements Snapshot {
         this.state = state;
     }
 
-    public String getBackupSnapshotId(){
-        return backupSnapshotId;
-    }
-
-    public long getPrevSnapshotId(){
-        return prevSnapshotId;
-    }
-
-    public void setBackupSnapshotId(String backUpSnapshotId){
-        this.backupSnapshotId = backUpSnapshotId;
-    }
-
-    public void setPrevSnapshotId(long prevSnapshotId){
-        this.prevSnapshotId = prevSnapshotId;
-    }
-
     public static Type getSnapshotType(String snapshotType) {
         for ( Type type : Type.values()) {
             if ( type.equals(snapshotType)) {
@@ -275,13 +225,4 @@ public class SnapshotVO implements Snapshot {
     public void setUuid(String uuid) {
         this.uuid = uuid;
     }
-
-    public Long getS3Id() {
-        return s3Id;
-    }
-
-    public void setS3Id(Long s3Id) {
-        this.s3Id = s3Id;
-    }
-
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/37cbe889/core/src/com/cloud/storage/VMTemplateHostVO.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/storage/VMTemplateHostVO.java b/core/src/com/cloud/storage/VMTemplateHostVO.java
index 8b25759..2273942 100755
--- a/core/src/com/cloud/storage/VMTemplateHostVO.java
+++ b/core/src/com/cloud/storage/VMTemplateHostVO.java
@@ -31,6 +31,7 @@ import javax.persistence.TemporalType;
 
 import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore;
 import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
+import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State;
 
 import com.cloud.utils.db.GenericDaoBase;
 
@@ -329,5 +330,10 @@ public class VMTemplateHostVO implements VMTemplateStorageResourceAssoc, DataObj
         return this.getHostId();
     }
 
+    @Override
+    public State getObjectInStoreState() {
+        return this.state;
+    }
+
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/37cbe889/core/src/com/cloud/storage/VMTemplateStoragePoolVO.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/storage/VMTemplateStoragePoolVO.java b/core/src/com/cloud/storage/VMTemplateStoragePoolVO.java
index 638ddd0..4c6a758 100644
--- a/core/src/com/cloud/storage/VMTemplateStoragePoolVO.java
+++ b/core/src/com/cloud/storage/VMTemplateStoragePoolVO.java
@@ -281,5 +281,10 @@ public class VMTemplateStoragePoolVO implements VMTemplateStorageResourceAssoc,
         return this.getPoolId();
     }
 
+    @Override
+    public State getObjectInStoreState() {
+        return this.state;
+    }
+
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/37cbe889/core/src/com/cloud/storage/VolumeHostVO.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/storage/VolumeHostVO.java b/core/src/com/cloud/storage/VolumeHostVO.java
index 63b1091..a6cd457 100755
--- a/core/src/com/cloud/storage/VolumeHostVO.java
+++ b/core/src/com/cloud/storage/VolumeHostVO.java
@@ -32,6 +32,7 @@ import javax.persistence.TemporalType;
 import org.apache.cloudstack.api.InternalIdentity;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore;
 import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
+import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State;
 
 import com.cloud.storage.Storage.ImageFormat;
 import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
@@ -354,5 +355,10 @@ public class VolumeHostVO implements InternalIdentity, DataObjectInStore {
         return this.getHostId();
     }
 
+    @Override
+    public State getObjectInStoreState() {
+        return this.state;
+    }
+
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/37cbe889/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObjectInStore.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObjectInStore.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObjectInStore.java
index ded2640..0bfbd9a 100644
--- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObjectInStore.java
+++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObjectInStore.java
@@ -26,4 +26,5 @@ public interface DataObjectInStore extends StateObject<ObjectInDataStoreStateMac
     public void setInstallPath(String path);
     public long getObjectId();
     public long getDataStoreId();
+    public ObjectInDataStoreStateMachine.State getObjectInStoreState();
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/37cbe889/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotDataFactory.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotDataFactory.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotDataFactory.java
index 1ff3ff2..0e9e3b3 100644
--- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotDataFactory.java
+++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotDataFactory.java
@@ -18,9 +18,11 @@
  */
 package org.apache.cloudstack.engine.subsystem.api.storage;
 
+import com.cloud.storage.DataStoreRole;
+
 
 public interface SnapshotDataFactory {
     public SnapshotInfo getSnapshot(long snapshotId, DataStore store);
     public SnapshotInfo getSnapshot(DataObject obj, DataStore store);
-    public SnapshotInfo getSnapshot(long snapshotId);
+    public SnapshotInfo getSnapshot(long snapshotId, DataStoreRole role);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/37cbe889/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotInfo.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotInfo.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotInfo.java
index b90404c..2973a54 100644
--- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotInfo.java
+++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotInfo.java
@@ -21,8 +21,11 @@ import com.cloud.storage.Snapshot;
 
 public interface SnapshotInfo extends DataObject, Snapshot {
 	public SnapshotInfo getParent();
+	public String getPath();
 	public SnapshotInfo getChild();
 	public VolumeInfo getBaseVolume();
+	public void addPayload(Object data);
     Long getDataCenterId();
     public Long getPrevSnapshotId();
+    ObjectInDataStoreStateMachine.State getStatus();
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/37cbe889/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotResult.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotResult.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotResult.java
new file mode 100644
index 0000000..29d094f
--- /dev/null
+++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotResult.java
@@ -0,0 +1,25 @@
+package org.apache.cloudstack.engine.subsystem.api.storage;
+
+
+import com.cloud.agent.api.Answer;
+
+public class SnapshotResult extends CommandResult {
+	private SnapshotInfo snashot;
+	private Answer answer;
+	public SnapshotResult(SnapshotInfo snapshot, Answer answer) {
+		this.setSnashot(snapshot);
+		this.setAnswer(answer);
+	}
+	public SnapshotInfo getSnashot() {
+		return snashot;
+	}
+	public void setSnashot(SnapshotInfo snashot) {
+		this.snashot = snashot;
+	}
+	public Answer getAnswer() {
+		return answer;
+	}
+	public void setAnswer(Answer answer) {
+		this.answer = answer;
+	}
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/37cbe889/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotService.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotService.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotService.java
index 68dc55f..b248054 100644
--- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotService.java
+++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotService.java
@@ -18,8 +18,9 @@
 package org.apache.cloudstack.engine.subsystem.api.storage;
 
 
+
 public interface SnapshotService {
-	public SnapshotInfo takeSnapshot(VolumeInfo volume, Long snapshotId);
+	public SnapshotResult takeSnapshot(SnapshotInfo snapshot);
 	public SnapshotInfo backupSnapshot(SnapshotInfo snapshot);
 	public boolean deleteSnapshot(SnapshotInfo snapshot);
 	public boolean revertSnapshot(SnapshotInfo snapshot);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/37cbe889/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotStrategy.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotStrategy.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotStrategy.java
new file mode 100644
index 0000000..a642b5e
--- /dev/null
+++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotStrategy.java
@@ -0,0 +1,11 @@
+package org.apache.cloudstack.engine.subsystem.api.storage;
+
+import com.cloud.storage.Snapshot;
+
+
+public interface SnapshotStrategy {
+	public SnapshotInfo takeSnapshot(SnapshotInfo snapshot);
+	public SnapshotInfo backupSnapshot(SnapshotInfo snapshot);
+	public boolean deleteSnapshot(Long snapshotId);
+	public boolean canHandle(Snapshot snapshot);
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/37cbe889/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeService.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeService.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeService.java
index 7175524..8bca479 100644
--- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeService.java
+++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeService.java
@@ -79,4 +79,6 @@ public interface VolumeService {
 
     void handleVolumeSync(DataStore store);
 
+	SnapshotInfo takeSnapshot(VolumeInfo volume);
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/37cbe889/engine/api/src/org/apache/cloudstack/storage/command/CreateObjectAnswer.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/storage/command/CreateObjectAnswer.java b/engine/api/src/org/apache/cloudstack/storage/command/CreateObjectAnswer.java
index 43540de..ddd678a 100644
--- a/engine/api/src/org/apache/cloudstack/storage/command/CreateObjectAnswer.java
+++ b/engine/api/src/org/apache/cloudstack/storage/command/CreateObjectAnswer.java
@@ -18,31 +18,26 @@
  */
 package org.apache.cloudstack.storage.command;
 
+import org.apache.cloudstack.engine.subsystem.api.storage.DataTO;
+
 import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.Command;
 
 public class CreateObjectAnswer extends Answer {
-    private String path;
-    private Long size;
+    private DataTO data;
     protected CreateObjectAnswer() {
         super();
     }
 
-    public CreateObjectAnswer(Command cmd, String path, Long size) {
-        super(cmd);
-        this.path = path;
-        this.size = size;
+    public CreateObjectAnswer(DataTO data) {
+        super();
+        this.data = data;
     }
     
-    public CreateObjectAnswer(Command cmd, boolean status, String result) {
-        super(cmd, status, result);
-    }
-
-    public String getPath() {
-        return this.path;
+    public DataTO getData() {
+        return this.data;
     }
     
-    public Long getSize() {
-        return this.size;
-    }
+    public CreateObjectAnswer(String errMsg) {
+        super(null, false, errMsg);
+    } 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/37cbe889/engine/api/src/org/apache/cloudstack/storage/command/CreateObjectCommand.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/storage/command/CreateObjectCommand.java b/engine/api/src/org/apache/cloudstack/storage/command/CreateObjectCommand.java
index 86d3bd4..6a72277 100644
--- a/engine/api/src/org/apache/cloudstack/storage/command/CreateObjectCommand.java
+++ b/engine/api/src/org/apache/cloudstack/storage/command/CreateObjectCommand.java
@@ -18,14 +18,16 @@
  */
 package org.apache.cloudstack.storage.command;
 
+import org.apache.cloudstack.engine.subsystem.api.storage.DataTO;
+
 import com.cloud.agent.api.Command;
 
 public class CreateObjectCommand extends Command implements StorageSubSystemCommand {
-    protected String objectUri;
+    private DataTO data;
 
-    public CreateObjectCommand(String objectUri) {
+    public CreateObjectCommand(DataTO obj) {
         super();
-        this.objectUri = objectUri;
+        this.data = obj;
     }
 
     protected CreateObjectCommand() {
@@ -38,8 +40,8 @@ public class CreateObjectCommand extends Command implements StorageSubSystemComm
         return false;
     }
     
-    public String getObjectUri() {
-        return this.objectUri;
+    public DataTO getData() {
+        return this.data;
     }
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/37cbe889/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java
index b4e5022..5f5c586 100644
--- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java
+++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java
@@ -23,20 +23,19 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore;
 import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
 
 
+import com.cloud.storage.DataStoreRole;
 import com.cloud.utils.db.GenericDao;
 import com.cloud.utils.fsm.StateDao;
 
 public interface SnapshotDataStoreDao extends GenericDao<SnapshotDataStoreVO, Long>, StateDao<ObjectInDataStoreStateMachine.State, ObjectInDataStoreStateMachine.Event, DataObjectInStore>  {
 
-    public List<SnapshotDataStoreVO> listByStoreId(long id);
+    public List<SnapshotDataStoreVO> listByStoreId(long id, DataStoreRole role);
 
     public void deletePrimaryRecordsForStore(long id);
 
-    public SnapshotDataStoreVO findByStoreSnapshot(long storeId, long snapshotId);
+    public SnapshotDataStoreVO findByStoreSnapshot(DataStoreRole role, long storeId, long snapshotId);
 
     public SnapshotDataStoreVO findByStoreSnapshot(long storeId, long snapshotId, boolean lock);
 
-    public SnapshotDataStoreVO findBySnapshot(long snapshotId);
-
-    public List<SnapshotDataStoreVO> listDestroyed(long storeId);
+    public SnapshotDataStoreVO findBySnapshot(long snapshotId, DataStoreRole role);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/37cbe889/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java
index e4c4942..af478ab 100644
--- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java
+++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java
@@ -31,10 +31,10 @@ import javax.persistence.TemporalType;
 
 import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore;
 import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
+import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State;
 
-import com.cloud.storage.Storage;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.utils.db.GenericDao;
 import com.cloud.utils.db.GenericDaoBase;
 import com.cloud.utils.fsm.StateObject;
 
@@ -51,6 +51,10 @@ public class SnapshotDataStoreVO implements StateObject<ObjectInDataStoreStateMa
 
 	@Column(name="store_id")
 	private long dataStoreId;
+	
+	@Column(name="store_role")
+	@Enumerated(EnumType.STRING)
+	private DataStoreRole role;
 
 	@Column(name="snapshot_id")
 	private long snapshotId;
@@ -62,23 +66,23 @@ public class SnapshotDataStoreVO implements StateObject<ObjectInDataStoreStateMa
 	@Temporal(value=TemporalType.TIMESTAMP)
 	private Date lastUpdated = null;
 
-
 	@Column (name="size")
 	private long size;
 
 	@Column (name="physical_size")
 	private long physicalSize;
 
-
+	@Column(name="parent_snapshot_id")
+	private long parentSnapshotId;
+	
 	@Column (name="job_id")
 	private String jobId;
 
 	@Column (name="install_path")
     private String installPath;
 
-
-    @Column(name="destroyed")
-    boolean destroyed = false;
+    @Column(name = GenericDao.REMOVED_COLUMN)
+    Date removed;
 
     @Column(name="update_count", updatable = true, nullable=false)
     protected long updatedCount;
@@ -201,14 +205,6 @@ public class SnapshotDataStoreVO implements StateObject<ObjectInDataStoreStateMa
         return physicalSize;
     }
 
-    public void setDestroyed(boolean destroyed) {
-    	this.destroyed = destroyed;
-    }
-
-    public boolean getDestroyed() {
-    	return destroyed;
-    }
-
 	public long getVolumeSize() {
 	    return -1;
 	}
@@ -245,5 +241,24 @@ public class SnapshotDataStoreVO implements StateObject<ObjectInDataStoreStateMa
         return this.getSnapshotId();
     }
 
+    public DataStoreRole getRole() {
+        return role;
+    }
+
+    public void setRole(DataStoreRole role) {
+        this.role = role;
+    }
+
+    @Override
+    public State getObjectInStoreState() {
+       return this.state;
+    }
+
+	public long getParentSnapshotId() {
+		return parentSnapshotId;
+	}
 
+	public void setParentSnapshotId(long parentSnapshotId) {
+		this.parentSnapshotId = parentSnapshotId;
+	}
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/37cbe889/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java
index 62b5c877..7d64544 100755
--- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java
+++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java
@@ -31,6 +31,7 @@ import javax.persistence.TemporalType;
 
 import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore;
 import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
+import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State;
 
 import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
 
@@ -320,5 +321,8 @@ public class TemplateDataStoreVO implements StateObject<ObjectInDataStoreStateMa
         return this.getTemplateId();
     }
 
-
+    @Override
+    public State getObjectInStoreState() {
+       return this.state;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/37cbe889/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java
index d589b5c..7593e2c 100755
--- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java
+++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java
@@ -31,6 +31,7 @@ import javax.persistence.TemporalType;
 
 import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore;
 import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
+import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State;
 
 import com.cloud.storage.Storage;
 import com.cloud.storage.Storage.ImageFormat;
@@ -351,5 +352,10 @@ public class VolumeDataStoreVO implements StateObject<ObjectInDataStoreStateMach
         return this.getVolumeId();
     }
 
+    @Override
+    public State getObjectInStoreState() {
+        return this.state;
+    }
+
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/37cbe889/engine/api/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java b/engine/api/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java
new file mode 100644
index 0000000..38fea16
--- /dev/null
+++ b/engine/api/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java
@@ -0,0 +1,30 @@
+package org.apache.cloudstack.storage.to;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataTO;
+
+import com.cloud.agent.api.to.DataStoreTO;
+
+public class SnapshotObjectTO implements DataTO {
+	private String path;
+	@Override
+	public DataObjectType getObjectType() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public DataStoreTO getDataStore() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public String getPath() {
+		return this.path;
+	}
+	
+	public void setPath(String path) {
+		this.path = path;
+	}
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/37cbe889/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java
----------------------------------------------------------------------
diff --git a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java
index 6a37c9d..79ae289 100644
--- a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java
+++ b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java
@@ -398,62 +398,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy {
         StoragePoolVO poolvo = pools.get(0);
         StoragePool pool = (StoragePool) this.dataStoreMgr.getDataStore(
                 poolvo.getId(), DataStoreRole.Primary);
-        if (snapshot.getVersion() != null
-                && snapshot.getVersion().equalsIgnoreCase("2.1")) {
-            VolumeVO volume = this.volDao.findByIdIncludingRemoved(volumeId);
-            if (volume == null) {
-                throw new CloudRuntimeException("failed to upgrade snapshot "
-                        + snapshotId + " due to unable to find orignal volume:"
-                        + volumeId + ", try it later ");
-            }
-            if (volume.getTemplateId() == null) {
-                snapshotDao.updateSnapshotVersion(volumeId, "2.1", "2.2");
-            } else {
-                template = templateDao.findByIdIncludingRemoved(volume
-                        .getTemplateId());
-                if (template == null) {
-                    throw new CloudRuntimeException(
-                            "failed to upgrade snapshot "
-                                    + snapshotId
-                                    + " due to unalbe to find orignal template :"
-                                    + volume.getTemplateId()
-                                    + ", try it later ");
-                }
-                Long origTemplateId = template.getId();
-                Long origTmpltAccountId = template.getAccountId();
-                if (!this.volDao.lockInLockTable(volumeId.toString(), 10)) {
-                    throw new CloudRuntimeException(
-                            "failed to upgrade snapshot " + snapshotId
-                                    + " due to volume:" + volumeId
-                                    + " is being used, try it later ");
-                }
-                UpgradeSnapshotCommand cmd = new UpgradeSnapshotCommand(null,
-                        secondaryStorageURL, dcId, accountId, volumeId,
-                        origTemplateId, origTmpltAccountId, null,
-                        snapshot.getBackupSnapshotId(), snapshot.getName(),
-                        "2.1");
-                if (!this.volDao.lockInLockTable(volumeId.toString(), 10)) {
-                    throw new CloudRuntimeException(
-                            "Creating template failed due to volume:"
-                                    + volumeId
-                                    + " is being used, try it later ");
-                }
-                Answer answer = null;
-                try {
-                    answer = this.storageMgr.sendToPool(pool, cmd);
-                    cmd = null;
-                } catch (StorageUnavailableException e) {
-                } finally {
-                    this.volDao.unlockFromLockTable(volumeId.toString());
-                }
-                if ((answer != null) && answer.getResult()) {
-                    snapshotDao.updateSnapshotVersion(volumeId, "2.1", "2.2");
-                } else {
-                    throw new CloudRuntimeException(
-                            "Unable to upgrade snapshot");
-                }
-            }
-        }
+        
         if (snapshot.getSwiftId() != null && snapshot.getSwiftId() != 0) {
             snapshotMgr.downloadSnapshotsFromSwift(snapshot);
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/37cbe889/engine/storage/snapshot/pom.xml
----------------------------------------------------------------------
diff --git a/engine/storage/snapshot/pom.xml b/engine/storage/snapshot/pom.xml
index 211cdac..350a9a9 100644
--- a/engine/storage/snapshot/pom.xml
+++ b/engine/storage/snapshot/pom.xml
@@ -26,6 +26,11 @@
       <version>${project.version}</version>
     </dependency>
     <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-engine-api</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
       <groupId>mysql</groupId>
       <artifactId>mysql-connector-java</artifactId>
       <version>${cs.mysql.version}</version>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/37cbe889/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotDataFactoryImpl.java
----------------------------------------------------------------------
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 a647715..c530e4a 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
@@ -35,6 +35,9 @@ import com.cloud.storage.DataStoreRole;
 import com.cloud.storage.Snapshot;
 import com.cloud.storage.SnapshotVO;
 import com.cloud.storage.dao.SnapshotDao;
+import com.cloud.utils.db.SearchCriteria2;
+import com.cloud.utils.db.SearchCriteriaService;
+import com.cloud.utils.db.SearchCriteria.Op;
 import com.cloud.utils.exception.CloudRuntimeException;
 
 @Component
@@ -49,36 +52,30 @@ public class SnapshotDataFactoryImpl implements SnapshotDataFactory {
     VolumeDataFactory volumeFactory;
     @Override
     public SnapshotInfo getSnapshot(long snapshotId, DataStore store) {
-        SnapshotVO snapshot = snapshotDao.findByIdIncludingRemoved(snapshotId);
+        SnapshotVO snapshot = snapshotDao.findById(snapshotId);
         SnapshotObject so =  SnapshotObject.getSnapshotObject(snapshot, store);
         return so;
     }
 
     @Override
-    public SnapshotInfo getSnapshot(long snapshotId) {
-    	SnapshotVO snapshot = snapshotDao.findByIdIncludingRemoved(snapshotId);
-    	SnapshotObject so = null;
-    	if (snapshot.getState() == Snapshot.State.BackedUp) {
-    	    DataStore store = null;
-    	    SnapshotDataStoreVO snapshotStore = snapshotStoreDao.findBySnapshot(snapshotId);
-    	    if ( snapshotStore != null ){
-    	        store = this.storeMgr.getDataStore(snapshotStore.getDataStoreId(), DataStoreRole.Image);
-    	    }
-    		so =  SnapshotObject.getSnapshotObject(snapshot, store);
-    	} else {
-    		VolumeInfo volume = this.volumeFactory.getVolume(snapshot.getVolumeId());
-    		so = SnapshotObject.getSnapshotObject(snapshot, volume.getDataStore());
-    	}
-    	return so;
-    }
-
-    @Override
     public SnapshotInfo getSnapshot(DataObject obj, DataStore store) {
-        SnapshotVO snapshot = snapshotDao.findByIdIncludingRemoved(obj.getId());
+        SnapshotVO snapshot = snapshotDao.findById(obj.getId());
         if (snapshot == null) {
             throw new CloudRuntimeException("Can't find snapshot: " + obj.getId());
         }
         SnapshotObject so =  SnapshotObject.getSnapshotObject(snapshot, store);
         return so;
     }
+
+    @Override
+    public SnapshotInfo getSnapshot(long snapshotId, DataStoreRole role) {
+        SnapshotVO snapshot = snapshotDao.findById(snapshotId);
+        SnapshotDataStoreVO snapshotStore = snapshotStoreDao.findBySnapshot(snapshotId, role);
+        if (snapshotStore == null) {
+            return null;
+        }
+        DataStore store = this.storeMgr.getDataStore(snapshotStore.getDataStoreId(), role);
+        SnapshotObject so =  SnapshotObject.getSnapshotObject(snapshot, store);
+        return so;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/37cbe889/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java
----------------------------------------------------------------------
diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java
index e22cfb9..50f3819 100644
--- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java
+++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java
@@ -30,7 +30,11 @@ import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
 import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat;
+import org.apache.cloudstack.storage.command.CreateObjectAnswer;
 import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager;
+import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
+import org.apache.cloudstack.storage.to.SnapshotObjectTO;
 import org.apache.log4j.Logger;
 
 import com.cloud.agent.api.Answer;
@@ -55,6 +59,8 @@ public class SnapshotObject implements SnapshotInfo {
     @Inject protected SnapshotStateMachineManager stateMachineMgr;
     @Inject
     ObjectInDataStoreManager ojbectInStoreMgr;
+    @Inject
+    SnapshotDataStoreDao snapshotStore;
     public SnapshotObject() {
 
     }
@@ -76,6 +82,7 @@ public class SnapshotObject implements SnapshotInfo {
 
     @Override
     public SnapshotInfo getParent() {
+    	
         // TODO Auto-generated method stub
         return null;
     }
@@ -149,11 +156,7 @@ public class SnapshotObject implements SnapshotInfo {
 
 	@Override
 	public String getPath() {
-		return this.snapshot.getPath();
-	}
-
-	public void setPath(String path) {
-		this.snapshot.setPath(path);
+		return this.ojbectInStoreMgr.findObject(this, getDataStore()).getInstallPath();
 	}
 
 	@Override
@@ -196,9 +199,6 @@ public class SnapshotObject implements SnapshotInfo {
 		return this.snapshot.getDomainId();
 	}
 
-	public void setPrevSnapshotId(Long id) {
-		this.snapshot.setPrevSnapshotId(id);
-	}
 
 	@Override
 	public Long getDataCenterId() {
@@ -212,15 +212,8 @@ public class SnapshotObject implements SnapshotInfo {
 
 	@Override
 	public Long getPrevSnapshotId() {
-		return this.snapshot.getPrevSnapshotId();
-	}
-
-	public void setBackupSnapshotId(String id) {
-		this.snapshot.setBackupSnapshotId(id);
-	}
-
-	public String getBackupSnapshotId() {
-		return this.snapshot.getBackupSnapshotId();
+		SnapshotDataStoreVO snapshotStoreVO = this.snapshotStore.findBySnapshot(this.getId(), this.getDataStore().getRole());
+		return snapshotStoreVO.getParentSnapshotId();
 	}
 
 	public SnapshotVO getSnapshotVO(){
@@ -234,8 +227,28 @@ public class SnapshotObject implements SnapshotInfo {
     }
 
     @Override
-    public void processEvent(org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event event, Answer answer) {
-        // TODO Auto-generated method stub
+    public void processEvent(ObjectInDataStoreStateMachine.Event event, Answer answer) {
+    	SnapshotDataStoreVO snapshotStore = this.snapshotStore.findByStoreSnapshot(this.getDataStore().getRole(), 
+    		   this.getDataStore().getId(), this.getId());
+    	if (answer instanceof CreateObjectAnswer) {
+    		SnapshotObjectTO snapshotTO = (SnapshotObjectTO)((CreateObjectAnswer) answer).getData();
+    		snapshotStore.setInstallPath(snapshotTO.getPath());
+    		this.snapshotStore.update(snapshotStore.getId(), snapshotStore);
+    	} else {
+    		throw new CloudRuntimeException("Unknown answer: " + answer.getClass());
+    	}
+    	this.processEvent(event);
+    }
 
+    @Override
+    public ObjectInDataStoreStateMachine.State getStatus() {
+       return this.ojbectInStoreMgr.findObject(this, store).getObjectInStoreState();
     }
+
+	@Override
+	public void addPayload(Object data) {
+		// TODO Auto-generated method stub
+		
+	}
+    
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/37cbe889/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java
index 6674880..2fb4609 100644
--- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java
+++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java
@@ -27,7 +27,6 @@ import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
 import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
 import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
@@ -38,6 +37,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
 import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotService;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
 import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
+import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotResult;
 import org.apache.cloudstack.framework.async.AsyncCallFuture;
 import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher;
 import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
@@ -51,30 +51,19 @@ import org.springframework.stereotype.Component;
 
 import com.cloud.agent.api.BackupSnapshotAnswer;
 import com.cloud.configuration.dao.ConfigurationDao;
-import com.cloud.dc.ClusterVO;
 import com.cloud.dc.dao.ClusterDao;
 import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.host.HostVO;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.resource.ResourceManager;
 import com.cloud.storage.DataStoreRole;
 import com.cloud.storage.Snapshot;
 import com.cloud.storage.SnapshotVO;
-import com.cloud.storage.StoragePool;
 import com.cloud.storage.VolumeManager;
-import com.cloud.storage.VolumeVO;
 import com.cloud.storage.dao.SnapshotDao;
 import com.cloud.storage.dao.VolumeDao;
 import com.cloud.storage.snapshot.SnapshotManager;
-import com.cloud.utils.NumbersUtil;
 import com.cloud.utils.db.DB;
 import com.cloud.utils.exception.CloudRuntimeException;
 import com.cloud.utils.fsm.NoTransitionException;
-import com.cloud.vm.UserVmVO;
-import com.cloud.vm.VirtualMachine.State;
 import com.cloud.vm.dao.UserVmDao;
-import com.cloud.vm.snapshot.VMSnapshot;
-import com.cloud.vm.snapshot.VMSnapshotVO;
 import com.cloud.vm.snapshot.dao.VMSnapshotDao;
 
 @Component
@@ -92,8 +81,7 @@ public class SnapshotServiceImpl implements SnapshotService {
 	protected SnapshotDao _snapshotDao;
 	@Inject
 	protected SnapshotDataStoreDao _snapshotStoreDao;
-	@Inject
-	private ResourceManager _resourceMgr;
+
 	@Inject
 	protected SnapshotManager snapshotMgr;
 	@Inject
@@ -164,81 +152,24 @@ public class SnapshotServiceImpl implements SnapshotService {
 			CreateSnapshotContext<CreateCmdResult> context) {
 		CreateCmdResult result = callback.getResult();
 		SnapshotObject snapshot = (SnapshotObject)context.snapshot;
-		VolumeInfo volume = context.volume;
 		AsyncCallFuture<SnapshotResult> future = context.future;
-		SnapshotResult snapResult = new SnapshotResult(snapshot);
+		SnapshotResult snapResult = new SnapshotResult(snapshot, result.getAnswer());
 		if (result.isFailed()) {
 			s_logger.debug("create snapshot " + context.snapshot.getName() + " failed: " + result.getResult());
 			try {
 				snapshot.processEvent(Snapshot.Event.OperationFailed);
-			} catch (NoTransitionException nte) {
-				s_logger.debug("Failed to update snapshot state due to " + nte.getMessage());
+				snapshot.processEvent(Event.OperationFailed);
+			} catch (Exception e) {
+				s_logger.debug("Failed to update snapshot state due to " + e.getMessage());
 			}
-
-
+			
 			snapResult.setResult(result.getResult());
 			future.complete(snapResult);
 			return null;
 		}
 
 		try {
-			SnapshotVO preSnapshotVO = this.snapshotMgr.getParentSnapshot(volume, snapshot);
-			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())) {
-				// empty snapshot
-				s_logger.debug("CreateSnapshot: this is empty snapshot ");
-
-				snapshotVO.setPath(preSnapshotPath);
-				snapshotVO.setBackupSnapshotId(preSnapshotVO.getBackupSnapshotId());
-				snapshotVO.setPrevSnapshotId(preSnapshotVO.getId());
-				snapshot.processEvent(Snapshot.Event.OperationNotPerformed);
-			} else {
-				long preSnapshotId = 0;
-
-				if (preSnapshotVO != null && preSnapshotVO.getBackupSnapshotId() != null) {
-					preSnapshotId = preSnapshotVO.getId();
-					int _deltaSnapshotMax = NumbersUtil.parseInt(_configDao.getValue("snapshot.delta.max"), SnapshotManager.DELTAMAX);
-					int deltaSnap = _deltaSnapshotMax;
-
-					int i;
-					for (i = 1; i < deltaSnap; i++) {
-						String prevBackupUuid = preSnapshotVO.getBackupSnapshotId();
-						// previous snapshot doesn't have backup, create a full snapshot
-						if (prevBackupUuid == null) {
-							preSnapshotId = 0;
-							break;
-						}
-						long preSSId = preSnapshotVO.getPrevSnapshotId();
-						if (preSSId == 0) {
-							break;
-						}
-						preSnapshotVO = _snapshotDao.findByIdIncludingRemoved(preSSId);
-					}
-					if (i >= deltaSnap) {
-						preSnapshotId = 0;
-					}
-				}
-
-				//If the volume is moved around, backup a full snapshot to secondary storage
-				if (volume.getLastPoolId() != null && !volume.getLastPoolId().equals(volume.getPoolId())) {
-					preSnapshotId = 0;
-					//TODO: fix this hack
-					VolumeVO volumeVO = this.volumeDao.findById(volume.getId());
-					volumeVO.setLastPoolId(volume.getPoolId());
-					this.volumeDao.update(volume.getId(), volumeVO);
-				}
-
-				snapshot.setPath(result.getPath());
-				snapshot.setPrevSnapshotId(preSnapshotId);
-
-				snapshot.processEvent(Snapshot.Event.OperationSucceeded);
-				snapResult = new SnapshotResult(this.snapshotfactory.getSnapshot(snapshot.getId()));
-			}
+			snapshot.processEvent(Event.OperationSuccessed, result.getAnswer());
 		} catch (Exception e) {
 			s_logger.debug("Failed to create snapshot: ", e);
 			snapResult.setResult(e.toString());
@@ -253,36 +184,49 @@ public class SnapshotServiceImpl implements SnapshotService {
 		return null;
 	}
 
-	class SnapshotResult extends CommandResult {
-		SnapshotInfo snashot;
-		public SnapshotResult(SnapshotInfo snapshot) {
-			this.snashot = snapshot;
+	
+
+	@Override
+	public SnapshotResult takeSnapshot(SnapshotInfo snap) {
+		SnapshotObject snapshot = (SnapshotObject)snap;
+		
+		SnapshotObject snapshotOnPrimary = null;
+		try {
+		    snapshotOnPrimary = (SnapshotObject)snap.getDataStore().create(snapshot);
+		} catch(Exception e) {
+		    s_logger.debug("Failed to create snapshot state on data store due to " + e.getMessage());
+		    throw new CloudRuntimeException(e);
 		}
-	}
 
-	protected SnapshotInfo createSnapshotOnPrimary(VolumeInfo volume, Long snapshotId) {
-		SnapshotObject snapshot = (SnapshotObject)this.snapshotfactory.getSnapshot(snapshotId);
-		if (snapshot == null) {
-			throw new CloudRuntimeException("Can not find snapshot " + snapshotId);
+		try {
+		    snapshotOnPrimary.processEvent(Snapshot.Event.CreateRequested);
+		} catch (NoTransitionException e) {
+		    s_logger.debug("Failed to change snapshot state: " + e.toString());
+		    throw new CloudRuntimeException(e);
 		}
 
 		try {
-			snapshot.processEvent(Snapshot.Event.CreateRequested);
-		} catch (NoTransitionException nte) {
-			s_logger.debug("Failed to update snapshot state due to " + nte.getMessage());
-			throw new CloudRuntimeException("Failed to update snapshot state due to " + nte.getMessage());
+		    snapshotOnPrimary.processEvent(Event.CreateOnlyRequested);
+		} catch (Exception e) {
+		    s_logger.debug("Failed to change snapshot state: " + e.toString());
+		    try {
+		        snapshotOnPrimary.processEvent(Snapshot.Event.OperationFailed);
+		    } catch (NoTransitionException e1) {
+		        s_logger.debug("Failed to change snapshot state: " + e1.toString());
+		    }
+		    throw new CloudRuntimeException(e);
 		}
 
 		AsyncCallFuture<SnapshotResult> future = new AsyncCallFuture<SnapshotResult>();
 		try {
 		    CreateSnapshotContext<CommandResult> context = new CreateSnapshotContext<CommandResult>(
-		            null, volume, snapshot, future);
+		            null, snap.getBaseVolume(), snapshotOnPrimary, future);
 		    AsyncCallbackDispatcher<SnapshotServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher
 		            .create(this);
 		    caller.setCallback(
 		            caller.getTarget().createSnapshotAsyncCallback(null, null))
 		            .setContext(context);
-		    PrimaryDataStoreDriver primaryStore = (PrimaryDataStoreDriver)volume.getDataStore().getDriver();
+		    PrimaryDataStoreDriver primaryStore = (PrimaryDataStoreDriver)snapshotOnPrimary.getDataStore().getDriver();
 		    primaryStore.takeSnapshot(snapshot, caller);
 		} catch (Exception e) {
 		    s_logger.debug("Failed to take snapshot: " + snapshot.getId(), e);
@@ -302,7 +246,7 @@ public class SnapshotServiceImpl implements SnapshotService {
 				s_logger.debug("Failed to create snapshot:" + result.getResult());
 				throw new CloudRuntimeException(result.getResult());
 			}
-			return result.snashot;
+			return result;
 		} catch (InterruptedException e) {
 			s_logger.debug("Failed to create snapshot", e);
 			throw new CloudRuntimeException("Failed to create snapshot", e);
@@ -313,78 +257,11 @@ public class SnapshotServiceImpl implements SnapshotService {
 
 	}
 
-	private boolean hostSupportSnapsthot(HostVO host) {
-		if (host.getHypervisorType() != HypervisorType.KVM) {
-			return true;
-		}
-		// Determine host capabilities
-		String caps = host.getCapabilities();
-
-		if (caps != null) {
-			String[] tokens = caps.split(",");
-			for (String token : tokens) {
-				if (token.contains("snapshot")) {
-					return true;
-				}
-			}
-		}
-		return false;
-	}
-
-	protected boolean supportedByHypervisor(VolumeInfo volume) {
-		if (volume.getHypervisorType().equals(HypervisorType.KVM)) {
-			StoragePool storagePool = (StoragePool)volume.getDataStore();
-			ClusterVO cluster = _clusterDao.findById(storagePool.getClusterId());
-			List<HostVO> hosts = _resourceMgr.listAllHostsInCluster(cluster.getId());
-			if (hosts != null && !hosts.isEmpty()) {
-				HostVO host = hosts.get(0);
-				if (!hostSupportSnapsthot(host)) {
-					throw new CloudRuntimeException("KVM Snapshot is not supported on cluster: " + host.getId());
-				}
-			}
-		}
-
-		// if volume is attached to a vm in destroyed or expunging state; disallow
-		if (volume.getInstanceId() != null) {
-			UserVmVO userVm = _vmDao.findById(volume.getInstanceId());
-			if (userVm != null) {
-				if (userVm.getState().equals(State.Destroyed) || userVm.getState().equals(State.Expunging)) {
-					throw new CloudRuntimeException("Creating snapshot failed due to volume:" + volume.getId() + " is associated with vm:" + userVm.getInstanceName() + " is in "
-							+ userVm.getState().toString() + " state");
-				}
-
-				if(userVm.getHypervisorType() == HypervisorType.VMware || userVm.getHypervisorType() == HypervisorType.KVM) {
-					List<SnapshotVO> activeSnapshots = _snapshotDao.listByInstanceId(volume.getInstanceId(), Snapshot.State.Creating,  Snapshot.State.CreatedOnPrimary,  Snapshot.State.BackingUp);
-					if(activeSnapshots.size() > 1)
-						throw new CloudRuntimeException("There is other active snapshot tasks on the instance to which the volume is attached, please try again later");
-				}
-
-				List<VMSnapshotVO> activeVMSnapshots = _vmSnapshotDao.listByInstanceId(userVm.getId(),
-                        VMSnapshot.State.Creating, VMSnapshot.State.Reverting, VMSnapshot.State.Expunging);
-                if (activeVMSnapshots.size() > 0) {
-                    throw new CloudRuntimeException(
-                            "There is other active vm snapshot tasks on the instance to which the volume is attached, please try again later");
-                }
-			}
-		}
-
-		return true;
-	}
-
-	@Override
-	public SnapshotInfo takeSnapshot(VolumeInfo volume, Long snapshotId) {
-
-		supportedByHypervisor(volume);
-
-		SnapshotInfo snapshot = createSnapshotOnPrimary(volume, snapshotId);
-		return snapshot;
-	}
-
 	@Override
 	public SnapshotInfo backupSnapshot(SnapshotInfo snapshot) {
 		SnapshotObject snapObj = (SnapshotObject)snapshot;
 		AsyncCallFuture<SnapshotResult> future = new AsyncCallFuture<SnapshotResult>();
-		SnapshotResult result = new SnapshotResult(snapshot);
+		SnapshotResult result = new SnapshotResult(snapshot, null);
 		try {
 
 			snapObj.processEvent(Snapshot.Event.BackupToSecondary);
@@ -420,7 +297,7 @@ public class SnapshotServiceImpl implements SnapshotService {
 
 		try {
 			SnapshotResult res = future.get();
-			SnapshotInfo destSnapshot = res.snashot;
+			SnapshotInfo destSnapshot = res.getSnashot();
 			return destSnapshot;
 		} catch (InterruptedException e) {
 			s_logger.debug("failed copy snapshot", e);
@@ -438,7 +315,7 @@ public class SnapshotServiceImpl implements SnapshotService {
 		SnapshotInfo destSnapshot = context.destSnapshot;
 		SnapshotObject srcSnapshot = (SnapshotObject)context.srcSnapshot;
 		AsyncCallFuture<SnapshotResult> future = context.future;
-		SnapshotResult snapResult = new SnapshotResult(destSnapshot);
+		SnapshotResult snapResult = new SnapshotResult(destSnapshot, result.getAnswer());
 		if (result.isFailed()) {
 			snapResult.setResult(result.getResult());
 			future.complete(snapResult);
@@ -453,7 +330,7 @@ public class SnapshotServiceImpl implements SnapshotService {
 			objInStoreMgr.update(destSnapshot, Event.OperationSuccessed);
 
 			srcSnapshot.processEvent(Snapshot.Event.OperationSucceeded);
-			snapResult = new SnapshotResult(this.snapshotfactory.getSnapshot(destSnapshot.getId()));
+			snapResult = new SnapshotResult(this.snapshotfactory.getSnapshot(destSnapshot.getId(), destSnapshot.getDataStore()), answer);
 			future.complete(snapResult);
 		} catch (Exception e) {
 			s_logger.debug("Failed to update snapshot state", e);
@@ -465,7 +342,7 @@ public class SnapshotServiceImpl implements SnapshotService {
 
 	@DB
 	protected boolean destroySnapshotBackUp(SnapshotVO snapshot) {
-	    SnapshotDataStoreVO snapshotStore = this._snapshotStoreDao.findBySnapshot(snapshot.getId());
+	    SnapshotDataStoreVO snapshotStore = this._snapshotStoreDao.findBySnapshot(snapshot.getId(), DataStoreRole.Image);
 	    if ( snapshotStore == null ){
             s_logger.debug("Can't find snapshot" + snapshot.getId() + " backed up into image store");
             return false;
@@ -510,81 +387,19 @@ public class SnapshotServiceImpl implements SnapshotService {
 		if (result.isFailed()) {
 			s_logger.debug("delete snapshot failed" + result.getResult());
 			snapshot.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed);
-			SnapshotResult res = new SnapshotResult(context.snapshot);
+			SnapshotResult res = new SnapshotResult(context.snapshot, null);
 			future.complete(res);
 			return null;
 		}
 		snapshot.processEvent(ObjectInDataStoreStateMachine.Event.OperationSuccessed);
-		SnapshotResult res = new SnapshotResult(context.snapshot);
+		SnapshotResult res = new SnapshotResult(context.snapshot, null);
 		future.complete(res);
 		return null;
 	}
 
 	@Override
 	public boolean deleteSnapshot(SnapshotInfo snapInfo) {
-		Long snapshotId = snapInfo.getId();
-		SnapshotObject snapshot = (SnapshotObject)snapInfo;
-
-		if (!Snapshot.State.BackedUp.equals(snapshot.getState())) {
-			throw new InvalidParameterValueException("Can't delete snapshotshot " + snapshotId + " due to it is not in BackedUp Status");
-		}
-
-		if (s_logger.isDebugEnabled()) {
-			s_logger.debug("Calling deleteSnapshot for snapshotId: " + snapshotId);
-		}
-		SnapshotVO lastSnapshot = null;
-		if (snapshot.getBackupSnapshotId() != null) {
-			List<SnapshotVO> snaps = _snapshotDao.listByBackupUuid(snapshot.getVolumeId(), snapshot.getBackupSnapshotId());
-			if (snaps != null && snaps.size() > 1) {
-				snapshot.setBackupSnapshotId(null);
-				SnapshotVO snapshotVO = this._snapshotDao.findById(snapshotId);
-				_snapshotDao.update(snapshot.getId(), snapshotVO);
-			}
-		}
-
-		_snapshotDao.remove(snapshotId);
-
-		long lastId = snapshotId;
-		boolean destroy = false;
-		while (true) {
-			lastSnapshot = _snapshotDao.findNextSnapshot(lastId);
-			if (lastSnapshot == null) {
-				// if all snapshots after this snapshot in this chain are removed, remove those snapshots.
-				destroy = true;
-				break;
-			}
-			if (lastSnapshot.getRemoved() == null) {
-				// if there is one child not removed, then can not remove back up snapshot.
-				break;
-			}
-			lastId = lastSnapshot.getId();
-		}
-		if (destroy) {
-			lastSnapshot = _snapshotDao.findByIdIncludingRemoved(lastId);
-			while (lastSnapshot.getRemoved() != null) {
-				String BackupSnapshotId = lastSnapshot.getBackupSnapshotId();
-				if (BackupSnapshotId != null) {
-					List<SnapshotVO> snaps = _snapshotDao.listByBackupUuid(lastSnapshot.getVolumeId(), BackupSnapshotId);
-					if (snaps != null && snaps.size() > 1) {
-						lastSnapshot.setBackupSnapshotId(null);
-						_snapshotDao.update(lastSnapshot.getId(), lastSnapshot);
-					} else {
-						if (destroySnapshotBackUp(lastSnapshot)) {
-
-						} else {
-							s_logger.debug("Destroying snapshot backup failed " + lastSnapshot);
-							break;
-						}
-					}
-				}
-				lastId = lastSnapshot.getPrevSnapshotId();
-				if (lastId == 0) {
-					break;
-				}
-				lastSnapshot = _snapshotDao.findByIdIncludingRemoved(lastId);
-			}
-		}
-		return true;
+		
 
 	}
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/37cbe889/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStrategyBase.java
----------------------------------------------------------------------
diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStrategyBase.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStrategyBase.java
new file mode 100644
index 0000000..70c30a0
--- /dev/null
+++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStrategyBase.java
@@ -0,0 +1,24 @@
+package org.apache.cloudstack.storage.snapshot;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotService;
+import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy;
+
+public abstract class SnapshotStrategyBase implements SnapshotStrategy {
+	@Inject
+	SnapshotService snapshotSvr;
+	//the default strategy is:
+	//create snapshot,
+	//backup, then delete snapshot on primary storage
+	@Override
+	public SnapshotInfo takeSnapshot(SnapshotInfo snapshot) {
+		return snapshotSvr.takeSnapshot(snapshot).getSnashot();
+	}
+
+	@Override
+	public SnapshotInfo backupSnapshot(SnapshotInfo snapshot) {
+		return snapshotSvr.backupSnapshot(snapshot);
+	}
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/37cbe889/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java
----------------------------------------------------------------------
diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java
new file mode 100644
index 0000000..0fa044b
--- /dev/null
+++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java
@@ -0,0 +1,200 @@
+package org.apache.cloudstack.storage.snapshot;
+
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
+import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State;
+import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory;
+import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotResult;
+import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event;
+import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotService;
+import org.apache.cloudstack.storage.command.CreateObjectAnswer;
+import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
+import org.apache.cloudstack.storage.to.SnapshotObjectTO;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.cloud.configuration.dao.ConfigurationDao;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.Snapshot;
+import com.cloud.storage.SnapshotVO;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.snapshot.SnapshotManager;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.fsm.NoTransitionException;
+
+@Component
+public class XenserverSnapshotStrategy extends SnapshotStrategyBase {
+	private static final Logger s_logger = Logger
+			.getLogger(XenserverSnapshotStrategy.class);
+
+	@Inject
+	SnapshotManager snapshotMgr;
+	@Inject
+	SnapshotService snapshotSvr;
+	@Inject
+	DataStoreManager dataStoreMgr;
+	@Inject
+	SnapshotDataStoreDao snapshotStoreDao;
+	@Inject
+	ConfigurationDao configDao;
+	@Inject
+	SnapshotDataFactory snapshotDataFactory;
+
+	@Override
+	public SnapshotInfo backupSnapshot(SnapshotInfo snapshot) {
+		SnapshotInfo parentSnapshot = snapshot.getParent();
+		if (parentSnapshot.getPath().equalsIgnoreCase(snapshot.getPath())) {
+			s_logger.debug("backup an empty snapshot");
+			//don't need to backup this snapshot
+			SnapshotDataStoreVO parentSnapshotOnBackupStore = this.snapshotStoreDao.findBySnapshot(parentSnapshot.getId(), DataStoreRole.Image);
+			if (parentSnapshotOnBackupStore != null && 
+					parentSnapshotOnBackupStore.getState() == State.Ready) {
+				DataStore store = dataStoreMgr.getDataStore(parentSnapshotOnBackupStore.getDataStoreId(), 
+						parentSnapshotOnBackupStore.getRole());
+
+				SnapshotInfo snapshotOnImageStore =  (SnapshotInfo)store.create(snapshot);
+				snapshotOnImageStore.processEvent(Event.CreateOnlyRequested);
+
+				SnapshotObjectTO snapTO = new SnapshotObjectTO();
+				snapTO.setPath(parentSnapshotOnBackupStore.getInstallPath());
+				CreateObjectAnswer createSnapshotAnswer = new CreateObjectAnswer(snapTO);
+
+				snapshotOnImageStore.processEvent(Event.OperationSuccessed, createSnapshotAnswer);
+				SnapshotObject snapObj = (SnapshotObject)snapshot;
+				try {
+					snapObj.processEvent(Snapshot.Event.OperationNotPerformed);
+				} catch (NoTransitionException e) {
+					s_logger.debug("Failed to change state: " + snapshot.getId() + ": " +e.toString());
+					throw new CloudRuntimeException(e.toString());
+				}
+				return this.snapshotDataFactory.getSnapshot(snapObj.getId(), store);
+			} else {
+				s_logger.debug("parent snapshot hasn't been backed up yet");
+			}
+		}
+
+		//determine full snapshot backup or not
+
+		boolean fullBackup = false;
+		long preSnapshotId = 0;
+		if (parentSnapshot != null) {
+
+			preSnapshotId = parentSnapshot.getId();
+			int _deltaSnapshotMax = NumbersUtil.parseInt(configDao.getValue("snapshot.delta.max"), SnapshotManager.DELTAMAX);
+			int deltaSnap = _deltaSnapshotMax;
+
+			int i;
+			SnapshotDataStoreVO parentSnapshotOnBackupStore = null;
+			for (i = 1; i < deltaSnap; i++) {
+				parentSnapshotOnBackupStore = this.snapshotStoreDao.findBySnapshot(parentSnapshot.getId(), DataStoreRole.Image);
+
+				Long prevBackupId = parentSnapshotOnBackupStore.getParentSnapshotId();
+
+				if (prevBackupId == 0) {
+					break;
+				}
+
+				parentSnapshotOnBackupStore = this.snapshotStoreDao.findBySnapshot(prevBackupId, DataStoreRole.Image);
+			}
+			if (i >= deltaSnap) {
+				fullBackup = true;
+			}
+		}
+		
+		snapshot.addPayload(fullBackup);
+		return this.snapshotSvr.backupSnapshot(snapshot);
+	}
+
+	@Override
+	public boolean deleteSnapshot(SnapshotInfo snapshot) {
+		Long snapshotId = snapshot.getId();
+		SnapshotObject snapObj = (SnapshotObject)snapshot;
+
+		if (!Snapshot.State.BackedUp.equals(snapshot.getState()) || !Snapshot) {
+			throw new InvalidParameterValueException("Can't delete snapshotshot " + snapshotId + " due to it is not in BackedUp Status");
+		}
+
+		if (s_logger.isDebugEnabled()) {
+			s_logger.debug("Calling deleteSnapshot for snapshotId: " + snapshotId);
+		}
+		SnapshotVO lastSnapshot = null;
+		if (snapshot.getPrevSnapshotId() != null) {
+			List<SnapshotVO> snaps = _snapshotDao.listByBackupUuid(snapshot.getVolumeId(), snapshot.getBackupSnapshotId());
+			if (snaps != null && snaps.size() > 1) {
+				snapshot.setBackupSnapshotId(null);
+				SnapshotVO snapshotVO = this._snapshotDao.findById(snapshotId);
+				_snapshotDao.update(snapshot.getId(), snapshotVO);
+			}
+		}
+
+		_snapshotDao.remove(snapshotId);
+
+		long lastId = snapshotId;
+		boolean destroy = false;
+		while (true) {
+			lastSnapshot = _snapshotDao.findNextSnapshot(lastId);
+			if (lastSnapshot == null) {
+				// if all snapshots after this snapshot in this chain are removed, remove those snapshots.
+				destroy = true;
+				break;
+			}
+			if (lastSnapshot.getRemoved() == null) {
+				// if there is one child not removed, then can not remove back up snapshot.
+				break;
+			}
+			lastId = lastSnapshot.getId();
+		}
+		if (destroy) {
+			lastSnapshot = _snapshotDao.findByIdIncludingRemoved(lastId);
+			while (lastSnapshot.getRemoved() != null) {
+				String BackupSnapshotId = lastSnapshot.getBackupSnapshotId();
+				if (BackupSnapshotId != null) {
+					List<SnapshotVO> snaps = _snapshotDao.listByBackupUuid(lastSnapshot.getVolumeId(), BackupSnapshotId);
+					if (snaps != null && snaps.size() > 1) {
+						lastSnapshot.setBackupSnapshotId(null);
+						_snapshotDao.update(lastSnapshot.getId(), lastSnapshot);
+					} else {
+						if (destroySnapshotBackUp(lastSnapshot)) {
+
+						} else {
+							s_logger.debug("Destroying snapshot backup failed " + lastSnapshot);
+							break;
+						}
+					}
+				}
+				lastId = lastSnapshot.getPrevSnapshotId();
+				if (lastId == 0) {
+					break;
+				}
+				lastSnapshot = _snapshotDao.findByIdIncludingRemoved(lastId);
+			}
+		}
+		return true;
+	}
+
+	@Override
+	public boolean canHandle(SnapshotInfo snapshot) {
+		if (snapshot.getHypervisorType() == HypervisorType.XenServer) {
+			return true;
+		} else {
+			return false;
+		}
+	}
+	
+	@Override
+	public SnapshotInfo takeSnapshot(SnapshotInfo snapshot) {
+		snapshot = snapshotSvr.takeSnapshot(snapshot).getSnashot();
+		//TODO: add async
+		return this.backupSnapshot(snapshot);
+	}
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/37cbe889/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java
index b00d152..7ff22c6 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java
@@ -120,6 +120,12 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager {
             if ( obj.getType() == DataObjectType.TEMPLATE){
                 VMTemplateStoragePoolVO vo = new VMTemplateStoragePoolVO(dataStore.getId(), obj.getId());
                 vo = templatePoolDao.persist(vo);
+            } else if (obj.getType() == DataObjectType.SNAPSHOT) {
+                SnapshotDataStoreVO ss = new SnapshotDataStoreVO();
+                ss.setSnapshotId(obj.getId());
+                ss.setDataStoreId(dataStore.getId());
+                ss.setRole(dataStore.getRole());
+                ss = snapshotDataStoreDao.persist(ss);
             }
         } else {
             // Image store
@@ -137,6 +143,7 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager {
                 SnapshotDataStoreVO ss = new SnapshotDataStoreVO();
                 ss.setSnapshotId(obj.getId());
                 ss.setDataStoreId(dataStore.getId());
+                ss.setRole(dataStore.getRole());
                 if (dataStore.getRole() == DataStoreRole.ImageCache) {
                 	ss.setInstallPath("/snapshots/" + snapshotDao.findById(obj.getId()).getAccountId() + "/" + obj.getId());
                 }
@@ -185,7 +192,7 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager {
                     return true;
                 }
             case SNAPSHOT:
-                SnapshotDataStoreVO destSnapshotStore = snapshotDataStoreDao.findByStoreSnapshot(dataStore.getId(), objId);
+                SnapshotDataStoreVO destSnapshotStore = snapshotDataStoreDao.findByStoreSnapshot(dataStore.getRole(), dataStore.getId(), objId);
                 if ( destSnapshotStore != null ){
                     return snapshotDataStoreDao.remove(destSnapshotStore.getId());
                 }
@@ -262,24 +269,17 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager {
     public DataObjectInStore findObject(long objId, DataObjectType type,
             long dataStoreId, DataStoreRole role) {
         DataObjectInStore vo = null;
-        if (role == DataStoreRole.Image) {
+        if (role == DataStoreRole.Image || role == DataStoreRole.ImageCache) {
             switch (type){
             case TEMPLATE:
                 vo = templateDataStoreDao.findByStoreTemplate(dataStoreId, objId);
             case SNAPSHOT:
-                vo = snapshotDataStoreDao.findByStoreSnapshot(dataStoreId, objId);
+                vo = snapshotDataStoreDao.findByStoreSnapshot(role, dataStoreId, objId);
             case VOLUME:
                 vo = volumeDataStoreDao.findByStoreVolume(dataStoreId, objId);
             }
         } else if (type == DataObjectType.TEMPLATE && role == DataStoreRole.Primary) {
             vo = templatePoolDao.findByPoolTemplate(dataStoreId, objId);
-        } else if (role == DataStoreRole.ImageCache) {
-        	SearchCriteriaService<ObjectInDataStoreVO, ObjectInDataStoreVO> sc = SearchCriteria2.create(ObjectInDataStoreVO.class);
-        	sc.addAnd(sc.getEntity().getObjectId(), Op.EQ, objId);
-        	sc.addAnd(sc.getEntity().getObjectType(), Op.EQ, type);
-        	sc.addAnd(sc.getEntity().getDataStoreId(), Op.EQ, dataStoreId);
-        	sc.addAnd(sc.getEntity().getDataStoreRole(), Op.EQ, role);
-        	vo = sc.find();
         } else {
             s_logger.debug("Invalid data or store type: " + type + " " + role);
             throw new CloudRuntimeException("Invalid data or store type: " + type + " " + role);
@@ -298,7 +298,7 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager {
             case TEMPLATE:
                 vo = templateDataStoreDao.findByTemplate(objId);
             case SNAPSHOT:
-                vo = snapshotDataStoreDao.findBySnapshot(objId);
+                vo = snapshotDataStoreDao.findBySnapshot(objId, role);
             case VOLUME:
                 vo = volumeDataStoreDao.findByVolume(objId);
             }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/37cbe889/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreVO.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreVO.java b/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreVO.java
index 44b9174..5b69251 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreVO.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreVO.java
@@ -32,6 +32,7 @@ import javax.persistence.TemporalType;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType;
 import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
+import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State;
 
 import com.cloud.storage.DataStoreRole;
 import com.cloud.storage.Storage;
@@ -191,4 +192,9 @@ public class ObjectInDataStoreVO implements StateObject<ObjectInDataStoreStateMa
 	public void setDataStoreId(long dataStoreId) {
 		this.dataStoreId = dataStoreId;
 	}
+
+    @Override
+    public State getObjectInStoreState() {
+       return this.state;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/37cbe889/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java
index 92e7d28..e95a1f3 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java
@@ -30,6 +30,7 @@ import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
 import org.apache.log4j.Logger;
 import org.springframework.stereotype.Component;
 
+import com.cloud.storage.DataStoreRole;
 import com.cloud.storage.StoragePoolHostVO;
 import com.cloud.utils.db.GenericDaoBase;
 import com.cloud.utils.db.SearchBuilder;
@@ -52,7 +53,8 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase<SnapshotDataStoreVO
 
         storeSearch = createSearchBuilder();
         storeSearch.and("store_id", storeSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ);
-        storeSearch.and("destroyed", storeSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
+        storeSearch.and("store_role", storeSearch.entity().getRole(), SearchCriteria.Op.EQ);
+
         storeSearch.done();
 
         updateStateSearch = this.createSearchBuilder();
@@ -63,13 +65,13 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase<SnapshotDataStoreVO
 
         snapshotSearch = createSearchBuilder();
         snapshotSearch.and("snapshot_id", snapshotSearch.entity().getSnapshotId(), SearchCriteria.Op.EQ);
-        snapshotSearch.and("destroyed", snapshotSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
+        snapshotSearch.and("store_role", storeSearch.entity().getRole(), SearchCriteria.Op.EQ);
         snapshotSearch.done();
 
         storeSnapshotSearch = createSearchBuilder();
         storeSnapshotSearch.and("snapshot_id", storeSnapshotSearch.entity().getSnapshotId(), SearchCriteria.Op.EQ);
         storeSnapshotSearch.and("store_id", storeSnapshotSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ);
-        storeSnapshotSearch.and("destroyed", storeSnapshotSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
+        storeSnapshotSearch.and("store_role", storeSearch.entity().getRole(), SearchCriteria.Op.EQ);
         storeSnapshotSearch.done();
 
         return true;
@@ -114,11 +116,11 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase<SnapshotDataStoreVO
 
 
     @Override
-    public List<SnapshotDataStoreVO> listByStoreId(long id) {
+    public List<SnapshotDataStoreVO> listByStoreId(long id, DataStoreRole role) {
         SearchCriteria<SnapshotDataStoreVO> sc = storeSearch.create();
         sc.setParameters("store_id", id);
-        sc.setParameters("destroyed", false);
-        return listIncludingRemovedBy(sc);
+        sc.setParameters("store_role", role);
+        return listBy(sc);
     }
 
     @Override
@@ -132,40 +134,19 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase<SnapshotDataStoreVO
     }
 
     @Override
-    public SnapshotDataStoreVO findByStoreSnapshot(long storeId, long snapshotId) {
+    public SnapshotDataStoreVO findByStoreSnapshot(DataStoreRole role, long storeId, long snapshotId) {
         SearchCriteria<SnapshotDataStoreVO> sc = storeSnapshotSearch.create();
         sc.setParameters("store_id", storeId);
         sc.setParameters("snapshot_id", snapshotId);
-        sc.setParameters("destroyed", false);
+        sc.setParameters("store_role", role);
         return findOneIncludingRemovedBy(sc);
     }
 
-
-    @Override
-    public SnapshotDataStoreVO findByStoreSnapshot(long storeId, long snapshotId, boolean lock) {
-        SearchCriteria<SnapshotDataStoreVO> sc = storeSnapshotSearch.create();
-        sc.setParameters("store_id", storeId);
-        sc.setParameters("snapshot_id", snapshotId);
-        sc.setParameters("destroyed", false);
-        if (!lock)
-            return findOneIncludingRemovedBy(sc);
-        else
-            return lockOneRandomRow(sc, true);
-    }
-
     @Override
-    public SnapshotDataStoreVO findBySnapshot(long snapshotId) {
+    public SnapshotDataStoreVO findBySnapshot(long snapshotId, DataStoreRole role) {
         SearchCriteria<SnapshotDataStoreVO> sc = snapshotSearch.create();
         sc.setParameters("snapshot_id", snapshotId);
-        sc.setParameters("destroyed", false);
-        return findOneIncludingRemovedBy(sc);
-    }
-
-    @Override
-    public List<SnapshotDataStoreVO> listDestroyed(long id) {
-        SearchCriteria<SnapshotDataStoreVO> sc = storeSearch.create();
-        sc.setParameters("store_id", id);
-        sc.setParameters("destroyed", true);
-        return listIncludingRemovedBy(sc);
+        sc.setParameters("store_role", role);
+        return findOneBy(sc);
     }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/37cbe889/engine/storage/src/org/apache/cloudstack/storage/snapshot/SnapshotService.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/snapshot/SnapshotService.java b/engine/storage/src/org/apache/cloudstack/storage/snapshot/SnapshotService.java
deleted file mode 100644
index f3e5c4a..0000000
--- a/engine/storage/src/org/apache/cloudstack/storage/snapshot/SnapshotService.java
+++ /dev/null
@@ -1,27 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.storage.snapshot;
-
-import org.apache.cloudstack.engine.cloud.entity.api.SnapshotEntity;
-import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
-
-public interface SnapshotService {
-	public SnapshotEntity getSnapshotEntity(long snapshotId);
-	public boolean takeSnapshot(SnapshotInfo snapshot);
-	public boolean revertSnapshot(SnapshotInfo snapshot);
-	public boolean deleteSnapshot(SnapshotInfo snapshot);
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/37cbe889/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java
index 4c214c1..8b20b22 100644
--- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java
+++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java
@@ -245,7 +245,8 @@ public class PrimaryDataStoreImpl implements PrimaryDataStore {
                     }
                 }
             }
-
+        } else if (obj.getType() == DataObjectType.SNAPSHOT) {
+            return objectInStoreMgr.create(obj, this);
         }
 
         return objectInStoreMgr.get(obj, this);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/37cbe889/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
index 47d99bd..e5876b2 100644
--- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
+++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
@@ -840,5 +840,26 @@ public class VolumeServiceImpl implements VolumeService {
 
         return null;
     }
+    
+    @Override
+    public SnapshotInfo takeSnapshot(VolumeInfo volume) {
+    	VolumeObject vol = (VolumeObject)volume;
+    	vol.stateTransit(Volume.Event.SnapshotRequested);
+    	
+    	SnapshotInfo snapshot = null;
+    	try {
+    		snapshot = this.snapshotMgr.takeSnapshot(volume);
+		} catch (Exception e) {
+			s_logger.debug("Take snapshot: " + volume.getId() + " failed: " + e.toString());
+		} finally {
+			if (snapshot != null) {
+				vol.stateTransit(Volume.Event.OperationSucceeded);
+			} else {
+				vol.stateTransit(Volume.Event.OperationFailed);
+			}
+		}
+ 
+    	return snapshot;
+    }
 
 }