You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by bf...@apache.org on 2013/10/07 20:30:36 UTC

[11/27] git commit: updated refs/heads/ui-restyle to 205f22b

Refactor Storage Related Resource Code
These changes are a joint effort between Edison and I to refactor some
of the code around snapshotting VM volumes and creating
templates/volumes from VM volume snapshots. In general, we were working
towards allowing PrimaryDataStoreDrivers to create snapshots on primary
storage and not requiring the snapshots to be transferred to secondary
storage.

High level changes:
-Added uuid to NfsTO, SwiftTO & S3TO to cut down on the requirement of
PrimaryDataStoreTO and ImageStoreTO which don't really serve much of a
purpose
-Initial work towards enable reverting VM volume from snapshots
-Added hypervisor commands for introducing and forgetting new hypervisor
objects (snapshots, templates & volumes)

Signed-off-by: Edison Su <su...@gmail.com>


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

Branch: refs/heads/ui-restyle
Commit: 180cfa19e87b909cb1c8a738359e31a6111b11c5
Parents: c9f41d4
Author: Chris Suich <ch...@netapp.com>
Authored: Fri Oct 4 10:45:47 2013 -0700
Committer: Edison Su <su...@gmail.com>
Committed: Fri Oct 4 13:06:42 2013 -0700

----------------------------------------------------------------------
 api/src/com/cloud/agent/api/to/DataStoreTO.java |   2 +-
 api/src/com/cloud/agent/api/to/NfsTO.java       |   9 +-
 api/src/com/cloud/agent/api/to/SwiftTO.java     |  11 +-
 api/src/com/cloud/event/EventTypes.java         |   5 +-
 .../storage/snapshot/SnapshotApiService.java    |   2 +
 .../admin/storage/ListStoragePoolsCmd.java      |   3 +-
 .../storage/resource/StorageProcessor.java      |   6 +
 .../StorageSubsystemCommandHandlerBase.java     |  22 +-
 .../cloudstack/storage/to/ImageStoreTO.java     |  10 +
 .../storage/to/PrimaryDataStoreTO.java          |   1 +
 .../subsystem/api/storage/EndPointSelector.java |   2 +
 .../subsystem/api/storage/SnapshotService.java  |   2 +-
 .../subsystem/api/storage/SnapshotStrategy.java |   4 +-
 .../motion/AncientDataMotionStrategy.java       |  29 ++-
 .../storage/image/store/ImageStoreImpl.java     |  14 +-
 .../storage/test/SnapshotTestWithFakeData.java  |  96 ++++---
 .../storage/snapshot/SnapshotServiceImpl.java   |  42 +--
 .../storage/snapshot/SnapshotStrategyBase.java  |   7 +-
 .../snapshot/XenserverSnapshotStrategy.java     |  20 +-
 .../endpoint/DefaultEndPointSelector.java       |  10 +-
 .../kvm/storage/KVMStorageProcessor.java        |  43 ++--
 .../resource/SimulatorStorageProcessor.java     |  35 ++-
 .../resource/VmwareStorageProcessor.java        | 257 ++++++++++---------
 .../xen/resource/XenServerStorageProcessor.java | 103 +++++---
 .../storage/snapshot/SnapshotManagerImpl.java   | 209 ++++++++-------
 .../resource/NfsSecondaryStorageResource.java   |  75 ++++--
 26 files changed, 604 insertions(+), 415 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/180cfa19/api/src/com/cloud/agent/api/to/DataStoreTO.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/agent/api/to/DataStoreTO.java b/api/src/com/cloud/agent/api/to/DataStoreTO.java
index 9014f8e..b79ba7d 100644
--- a/api/src/com/cloud/agent/api/to/DataStoreTO.java
+++ b/api/src/com/cloud/agent/api/to/DataStoreTO.java
@@ -20,7 +20,7 @@ package com.cloud.agent.api.to;
 
 import com.cloud.storage.DataStoreRole;
 
-
 public interface DataStoreTO {
     public DataStoreRole getRole();
+    public String getUuid();
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/180cfa19/api/src/com/cloud/agent/api/to/NfsTO.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/agent/api/to/NfsTO.java b/api/src/com/cloud/agent/api/to/NfsTO.java
index 415c95c..54683c7 100644
--- a/api/src/com/cloud/agent/api/to/NfsTO.java
+++ b/api/src/com/cloud/agent/api/to/NfsTO.java
@@ -22,6 +22,7 @@ public class NfsTO implements DataStoreTO {
 
     private String _url;
     private DataStoreRole _role;
+    private String uuid;
 
     public NfsTO() {
 
@@ -55,6 +56,12 @@ public class NfsTO implements DataStoreTO {
         this._role = _role;
     }
 
+    @Override
+    public String getUuid() {
+        return uuid;
+    }
 
-
+    public void setUuid(String uuid) {
+        this.uuid = uuid;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/180cfa19/api/src/com/cloud/agent/api/to/SwiftTO.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/agent/api/to/SwiftTO.java b/api/src/com/cloud/agent/api/to/SwiftTO.java
index 7349d77..3ad131a 100644
--- a/api/src/com/cloud/agent/api/to/SwiftTO.java
+++ b/api/src/com/cloud/agent/api/to/SwiftTO.java
@@ -29,8 +29,7 @@ public class SwiftTO implements DataStoreTO, SwiftUtil.SwiftClientCfg {
 
     public SwiftTO() { }
 
-    public SwiftTO(Long id, String url, String account, String userName, String key
-                  ) {
+    public SwiftTO(Long id, String url, String account, String userName, String key) {
         this.id = id;
         this.url = url;
         this.account = account;
@@ -46,14 +45,17 @@ public class SwiftTO implements DataStoreTO, SwiftUtil.SwiftClientCfg {
         return url;
     }
 
+    @Override
     public String getAccount() {
         return account;
     }
 
+    @Override
     public String getUserName() {
         return userName;
     }
 
+    @Override
     public String getKey() {
         return key;
     }
@@ -67,4 +69,9 @@ public class SwiftTO implements DataStoreTO, SwiftUtil.SwiftClientCfg {
     public String getEndPoint() {
         return this.url;
     }
+
+    @Override
+    public String getUuid() {
+        return null;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/180cfa19/api/src/com/cloud/event/EventTypes.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/event/EventTypes.java b/api/src/com/cloud/event/EventTypes.java
index ec9604e..a762606 100755
--- a/api/src/com/cloud/event/EventTypes.java
+++ b/api/src/com/cloud/event/EventTypes.java
@@ -199,6 +199,7 @@ public class EventTypes {
     // Snapshots
     public static final String EVENT_SNAPSHOT_CREATE = "SNAPSHOT.CREATE";
     public static final String EVENT_SNAPSHOT_DELETE = "SNAPSHOT.DELETE";
+    public static final String EVENT_SNAPSHOT_REVERT = "SNAPSHOT.REVERT";
     public static final String EVENT_SNAPSHOT_POLICY_CREATE = "SNAPSHOTPOLICY.CREATE";
     public static final String EVENT_SNAPSHOT_POLICY_UPDATE = "SNAPSHOTPOLICY.UPDATE";
     public static final String EVENT_SNAPSHOT_POLICY_DELETE = "SNAPSHOTPOLICY.DELETE";
@@ -387,7 +388,7 @@ public class EventTypes {
     public static final String EVENT_RESOURCE_DETAILS_CREATE = "CREATE_RESOURCE_DETAILS";
     public static final String EVENT_RESOURCE_DETAILS_DELETE = "DELETE_RESOURCE_DETAILS";
 
-	// vm snapshot events
+    // vm snapshot events
     public static final String EVENT_VM_SNAPSHOT_CREATE = "VMSNAPSHOT.CREATE";
     public static final String EVENT_VM_SNAPSHOT_DELETE = "VMSNAPSHOT.DELETE";
     public static final String EVENT_VM_SNAPSHOT_REVERT = "VMSNAPSHOT.REVERTTO";
@@ -444,7 +445,7 @@ public class EventTypes {
     public static final String EVENT_DEDICATE_RESOURCE_RELEASE = "DEDICATE.RESOURCE.RELEASE";
 
     public static final String EVENT_CLEANUP_VM_RESERVATION = "VM.RESERVATION.CLEANUP";
-    
+
     public static final String EVENT_UCS_ASSOCIATED_PROFILE = "UCS.ASSOCIATEPROFILE";
 
     static {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/180cfa19/api/src/com/cloud/storage/snapshot/SnapshotApiService.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/storage/snapshot/SnapshotApiService.java b/api/src/com/cloud/storage/snapshot/SnapshotApiService.java
index 23e6522..4f13510 100644
--- a/api/src/com/cloud/storage/snapshot/SnapshotApiService.java
+++ b/api/src/com/cloud/storage/snapshot/SnapshotApiService.java
@@ -106,4 +106,6 @@ public interface SnapshotApiService {
      * @return
      */
     Long getHostIdForSnapshotOperation(Volume vol);
+
+    boolean revertSnapshot(Long snapshotId);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/180cfa19/api/src/org/apache/cloudstack/api/command/admin/storage/ListStoragePoolsCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/admin/storage/ListStoragePoolsCmd.java b/api/src/org/apache/cloudstack/api/command/admin/storage/ListStoragePoolsCmd.java
index 26351bb..ddf0391 100644
--- a/api/src/org/apache/cloudstack/api/command/admin/storage/ListStoragePoolsCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/admin/storage/ListStoragePoolsCmd.java
@@ -59,7 +59,7 @@ public class ListStoragePoolsCmd extends BaseListCmd {
     @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.UUID, entityType = ZoneResponse.class,
             description="the Zone ID for the storage pool")
     private Long zoneId;
-    
+
     @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType = StoragePoolResponse.class,
             description="the ID of the storage pool")
     private Long id;
@@ -109,6 +109,7 @@ public class ListStoragePoolsCmd extends BaseListCmd {
         return s_name;
     }
 
+    @Override
     public ApiCommandJobType getInstanceType() {
         return ApiCommandJobType.StoragePool;
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/180cfa19/core/src/com/cloud/storage/resource/StorageProcessor.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/storage/resource/StorageProcessor.java b/core/src/com/cloud/storage/resource/StorageProcessor.java
index 5fa9f8a..29f4a67 100644
--- a/core/src/com/cloud/storage/resource/StorageProcessor.java
+++ b/core/src/com/cloud/storage/resource/StorageProcessor.java
@@ -23,8 +23,12 @@ import org.apache.cloudstack.storage.command.CopyCommand;
 import org.apache.cloudstack.storage.command.CreateObjectCommand;
 import org.apache.cloudstack.storage.command.DeleteCommand;
 import org.apache.cloudstack.storage.command.DettachCommand;
+import org.apache.cloudstack.storage.command.ForgetObjectCmd;
+import org.apache.cloudstack.storage.command.IntroduceObjectCmd;
 
 import com.cloud.agent.api.Answer;
+import org.apache.cloudstack.storage.command.ForgetObjectCmd;
+import org.apache.cloudstack.storage.command.IntroduceObjectCmd;
 
 public interface StorageProcessor {
     public Answer copyTemplateToPrimaryStorage(CopyCommand cmd);
@@ -43,4 +47,6 @@ public interface StorageProcessor {
     public Answer deleteVolume(DeleteCommand cmd);
     public Answer createVolumeFromSnapshot(CopyCommand cmd);
     public Answer deleteSnapshot(DeleteCommand cmd);
+    Answer introduceObject(IntroduceObjectCmd cmd);
+    Answer forgetObject(ForgetObjectCmd cmd);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/180cfa19/core/src/com/cloud/storage/resource/StorageSubsystemCommandHandlerBase.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/storage/resource/StorageSubsystemCommandHandlerBase.java b/core/src/com/cloud/storage/resource/StorageSubsystemCommandHandlerBase.java
index ab9aa2a..002143f 100644
--- a/core/src/com/cloud/storage/resource/StorageSubsystemCommandHandlerBase.java
+++ b/core/src/com/cloud/storage/resource/StorageSubsystemCommandHandlerBase.java
@@ -24,6 +24,7 @@ import org.apache.cloudstack.storage.command.CreateObjectAnswer;
 import org.apache.cloudstack.storage.command.CreateObjectCommand;
 import org.apache.cloudstack.storage.command.DeleteCommand;
 import org.apache.cloudstack.storage.command.DettachCommand;
+import org.apache.cloudstack.storage.command.IntroduceObjectCmd;
 import org.apache.cloudstack.storage.command.StorageSubSystemCommand;
 import org.apache.log4j.Logger;
 
@@ -55,6 +56,8 @@ public class StorageSubsystemCommandHandlerBase implements StorageSubsystemComma
             return execute((AttachCommand)command);
         } else if (command instanceof DettachCommand) {
             return execute((DettachCommand)command);
+        } else if (command instanceof IntroduceObjectCmd) {
+            return processor.introduceObject((IntroduceObjectCmd)command);
         }
         return new Answer((Command)command, false, "not implemented yet");
     }
@@ -65,7 +68,7 @@ public class StorageSubsystemCommandHandlerBase implements StorageSubsystemComma
         DataStoreTO srcDataStore = srcData.getDataStore();
         DataStoreTO destDataStore = destData.getDataStore();
 
-        if ((srcData.getObjectType() == DataObjectType.TEMPLATE) && (srcDataStore instanceof NfsTO)  && (destData.getDataStore().getRole() == DataStoreRole.Primary)) {
+        if ((srcData.getObjectType() == DataObjectType.TEMPLATE) && (destData.getObjectType() == DataObjectType.TEMPLATE && destData.getDataStore().getRole() == DataStoreRole.Primary)) {
             //copy template to primary storage
             return processor.copyTemplateToPrimaryStorage(cmd);
         } else if (srcData.getObjectType() == DataObjectType.TEMPLATE && srcDataStore.getRole() == DataStoreRole.Primary && destDataStore.getRole() == DataStoreRole.Primary) {
@@ -80,18 +83,19 @@ public class StorageSubsystemCommandHandlerBase implements StorageSubsystemComma
             } else if (destData.getObjectType() == DataObjectType.TEMPLATE) {
                 return processor.createTemplateFromVolume(cmd);
             }
-        } else if (srcData.getObjectType() == DataObjectType.SNAPSHOT && srcData.getDataStore().getRole() == DataStoreRole.Primary) {
+        } else if (srcData.getObjectType() == DataObjectType.SNAPSHOT && destData.getObjectType() == DataObjectType.SNAPSHOT &&
+                destData.getDataStore().getRole() == DataStoreRole.Primary) {
             return processor.backupSnapshot(cmd);
         } else if (srcData.getObjectType() == DataObjectType.SNAPSHOT && destData.getObjectType() == DataObjectType.VOLUME) {
-        	return processor.createVolumeFromSnapshot(cmd);
+            return processor.createVolumeFromSnapshot(cmd);
         } else if (srcData.getObjectType() == DataObjectType.SNAPSHOT && destData.getObjectType() == DataObjectType.TEMPLATE) {
             return processor.createTemplateFromSnapshot(cmd);
         }
 
         return new Answer(cmd, false, "not implemented yet");
     }
-    
-    
+
+
     protected Answer execute(CreateObjectCommand cmd) {
         DataTO data = cmd.getData();
         try {
@@ -106,21 +110,21 @@ public class StorageSubsystemCommandHandlerBase implements StorageSubsystemComma
             return new CreateObjectAnswer(e.toString());
         }
     }
-    
+
     protected Answer execute(DeleteCommand cmd) {
         DataTO data = cmd.getData();
         Answer answer = null;
         if (data.getObjectType() == DataObjectType.VOLUME) {
             answer = processor.deleteVolume(cmd);
         } else if (data.getObjectType() == DataObjectType.SNAPSHOT) {
-        	answer = processor.deleteSnapshot(cmd);
+            answer = processor.deleteSnapshot(cmd);
         } else {
             answer = new Answer(cmd, false, "unsupported type");
         }
 
         return answer;
     }
-    
+
     protected Answer execute(AttachCommand cmd) {
         DiskTO disk = cmd.getDisk();
         if (disk.getType() == Volume.Type.ISO) {
@@ -129,7 +133,7 @@ public class StorageSubsystemCommandHandlerBase implements StorageSubsystemComma
             return processor.attachVolume(cmd);
         }
     }
-    
+
     protected Answer execute(DettachCommand cmd) {
         DiskTO disk = cmd.getDisk();
         if (disk.getType() == Volume.Type.ISO) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/180cfa19/core/src/org/apache/cloudstack/storage/to/ImageStoreTO.java
----------------------------------------------------------------------
diff --git a/core/src/org/apache/cloudstack/storage/to/ImageStoreTO.java b/core/src/org/apache/cloudstack/storage/to/ImageStoreTO.java
index 0037ea5..ec6c240 100644
--- a/core/src/org/apache/cloudstack/storage/to/ImageStoreTO.java
+++ b/core/src/org/apache/cloudstack/storage/to/ImageStoreTO.java
@@ -26,6 +26,7 @@ public class ImageStoreTO implements DataStoreTO {
     private String uri;
     private String providerName;
     private DataStoreRole role;
+    private String uuid;
 
     public ImageStoreTO() {
 
@@ -76,4 +77,13 @@ public class ImageStoreTO implements DataStoreTO {
         return new StringBuilder("ImageStoreTO[type=").append(type).append("|provider=").append(providerName)
                 .append("|role=").append(role).append("|uri=").append(uri).append("]").toString();
     }
+
+    @Override
+    public String getUuid() {
+        return uuid;
+    }
+
+    public void setUuid(String uuid) {
+        this.uuid = uuid;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/180cfa19/core/src/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java
----------------------------------------------------------------------
diff --git a/core/src/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java b/core/src/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java
index 5e870df..91d78a4 100644
--- a/core/src/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java
+++ b/core/src/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java
@@ -46,6 +46,7 @@ public class PrimaryDataStoreTO implements DataStoreTO {
         return this.id;
     }
 
+    @Override
     public String getUuid() {
         return this.uuid;
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/180cfa19/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPointSelector.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPointSelector.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPointSelector.java
index ca0cc2c..b812f6e 100644
--- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPointSelector.java
+++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPointSelector.java
@@ -28,4 +28,6 @@ public interface EndPointSelector {
     EndPoint select(DataStore store);
 
     List<EndPoint> selectAll(DataStore store);
+
+    EndPoint select(Scope scope, Long storeId);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/180cfa19/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 d594a07..e953eb6 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
@@ -24,5 +24,5 @@ public interface SnapshotService {
 
     boolean deleteSnapshot(SnapshotInfo snapshot);
 
-    boolean revertSnapshot(SnapshotInfo snapshot);
+    boolean revertSnapshot(Long snapshotId);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/180cfa19/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
index 86ae532..47e595b 100644
--- 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
@@ -11,7 +11,7 @@
 // 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 
+// KIND, either express or implied.  See the License for the
 // specific language governing permissions and limitations
 // under the License.
 package org.apache.cloudstack.engine.subsystem.api.storage;
@@ -25,5 +25,7 @@ public interface SnapshotStrategy {
 
     boolean deleteSnapshot(Long snapshotId);
 
+    boolean revertSnapshot(Long snapshotId);
+
     boolean canHandle(Snapshot snapshot);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/180cfa19/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 96d1f5a..fb6962a 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
@@ -47,7 +47,7 @@ import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
 import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity;
-
+import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
 import org.apache.log4j.Logger;
 import org.springframework.stereotype.Component;
 
@@ -62,9 +62,9 @@ import com.cloud.agent.api.to.VirtualMachineTO;
 import com.cloud.configuration.Config;
 import com.cloud.host.Host;
 import com.cloud.host.dao.HostDao;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
 import com.cloud.server.ManagementService;
 import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.Storage.StoragePoolType;
 import com.cloud.storage.StorageManager;
 import com.cloud.storage.StoragePool;
 import com.cloud.storage.VolumeVO;
@@ -81,7 +81,7 @@ import com.cloud.utils.exception.CloudRuntimeException;
 
 @Component
 public class
-        AncientDataMotionStrategy implements DataMotionStrategy {
+AncientDataMotionStrategy implements DataMotionStrategy {
     private static final Logger s_logger = Logger.getLogger(AncientDataMotionStrategy.class);
     @Inject
     EndPointSelector selector;
@@ -138,7 +138,8 @@ public class
         DataTO destTO = destData.getTO();
         DataStoreTO srcStoreTO = srcTO.getDataStore();
         DataStoreTO destStoreTO = destTO.getDataStore();
-        if (srcStoreTO instanceof NfsTO || srcStoreTO.getRole() == DataStoreRole.ImageCache) {
+        if (srcStoreTO instanceof NfsTO || srcStoreTO.getRole() == DataStoreRole.ImageCache ||
+                (srcStoreTO instanceof PrimaryDataStoreTO && ((PrimaryDataStoreTO)srcStoreTO).getPoolType() == StoragePoolType.NetworkFilesystem)) {
             return false;
         }
 
@@ -264,8 +265,14 @@ public class
             int _createVolumeFromSnapshotWait = NumbersUtil.parseInt(value,
                     Integer.parseInt(Config.CreateVolumeFromSnapshotWait.getDefaultValue()));
 
+            EndPoint ep = null;
+            if (srcData.getDataStore().getRole() == DataStoreRole.Primary) {
+                ep = selector.select(volObj);
+            } else {
+                ep = selector.select(snapObj, volObj);
+            }
+
             CopyCommand cmd = new CopyCommand(srcData.getTO(), volObj.getTO(), _createVolumeFromSnapshotWait, _mgmtServer.getExecuteInSequence());
-            EndPoint ep = selector.select(snapObj, volObj);
             Answer answer = ep.sendMessage(cmd);
 
             return answer;
@@ -433,11 +440,17 @@ public class
             srcData = cacheSnapshotChain(snapshot);
         }
 
+        EndPoint ep = null;
+        if (srcData.getDataStore().getRole() == DataStoreRole.Primary) {
+            ep = selector.select(destData);
+        } else {
+            ep = selector.select(srcData, destData);
+        }
+
         CopyCommand cmd = new CopyCommand(srcData.getTO(), destData.getTO(), _createprivatetemplatefromsnapshotwait, _mgmtServer.getExecuteInSequence());
-        EndPoint ep = selector.select(srcData, destData);
         Answer answer = ep.sendMessage(cmd);
-        
-        // clean up snapshot copied to staging 
+
+        // clean up snapshot copied to staging
         if (needCache && srcData != null) {
             cacheMgr.deleteCacheObject(srcData);
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/180cfa19/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java
index 855d8cb..d77658b 100644
--- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java
+++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java
@@ -24,7 +24,6 @@ import java.util.concurrent.ExecutionException;
 
 import javax.inject.Inject;
 
-import com.cloud.capacity.dao.CapacityDao;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver;
 import org.apache.cloudstack.engine.subsystem.api.storage.ImageStoreProvider;
@@ -39,9 +38,11 @@ import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager;
 import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
 import org.apache.cloudstack.storage.image.ImageStoreDriver;
 import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity;
+import org.apache.cloudstack.storage.to.ImageStoreTO;
 import org.apache.log4j.Logger;
 
 import com.cloud.agent.api.to.DataStoreTO;
+import com.cloud.capacity.dao.CapacityDao;
 import com.cloud.storage.DataStoreRole;
 import com.cloud.storage.Storage.ImageFormat;
 import com.cloud.storage.dao.VMTemplateDao;
@@ -181,7 +182,16 @@ public class ImageStoreImpl implements ImageStoreEntity {
 
     @Override
     public DataStoreTO getTO() {
-        return getDriver().getStoreTO(this);
+        DataStoreTO to = getDriver().getStoreTO(this);
+        if (to == null) {
+            ImageStoreTO primaryTO = new ImageStoreTO();
+            primaryTO.setProviderName(getProviderName());
+            primaryTO.setRole(getRole());
+            primaryTO.setType(getProtocol());
+            primaryTO.setUri(getUri());
+            return primaryTO;
+        }
+        return to;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/180cfa19/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTestWithFakeData.java
----------------------------------------------------------------------
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTestWithFakeData.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTestWithFakeData.java
index 2aaabda..c73d167 100644
--- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTestWithFakeData.java
+++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTestWithFakeData.java
@@ -18,7 +18,50 @@
  */
 package org.apache.cloudstack.storage.test;
 
-import com.cloud.cluster.LockMasterListener;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+import javax.inject.Inject;
+
+import junit.framework.Assert;
+
+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.DataStoreProvider;
+import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
+import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreProvider;
+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.SnapshotService;
+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.VolumeService;
+import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
+import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.cloudstack.storage.volume.VolumeObject;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
 import com.cloud.dc.ClusterVO;
 import com.cloud.dc.DataCenter;
 import com.cloud.dc.DataCenterVO;
@@ -29,6 +72,7 @@ import com.cloud.dc.dao.HostPodDao;
 import com.cloud.hypervisor.Hypervisor;
 import com.cloud.org.Cluster;
 import com.cloud.org.Managed;
+import com.cloud.server.LockMasterListener;
 import com.cloud.storage.CreateSnapshotPayload;
 import com.cloud.storage.DataStoreRole;
 import com.cloud.storage.ScopeType;
@@ -47,53 +91,7 @@ import com.cloud.user.AccountManager;
 import com.cloud.user.User;
 import com.cloud.utils.DateUtil;
 import com.cloud.utils.component.ComponentContext;
-import com.cloud.utils.db.DB;
 import com.cloud.utils.db.Merovingian2;
-import junit.framework.Assert;
-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.DataStoreProvider;
-import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
-import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver;
-import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreProvider;
-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.SnapshotService;
-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.VolumeService;
-import org.apache.cloudstack.storage.datastore.PrimaryDataStore;
-import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
-import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-import org.apache.cloudstack.storage.volume.VolumeObject;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mockito;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-
-import javax.inject.Inject;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.UUID;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Executor;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
 
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
@@ -317,7 +315,7 @@ public class SnapshotTestWithFakeData  {
         final VolumeInfo volumeInfo = createVolume(1L, store);
         Assert.assertTrue(volumeInfo.getState() == Volume.State.Ready);
         vol = volumeInfo;
-       // final SnapshotPolicyVO policyVO = createSnapshotPolicy(vol.getId());
+        // final SnapshotPolicyVO policyVO = createSnapshotPolicy(vol.getId());
 
 
         ExecutorService pool = Executors.newFixedThreadPool(2);
@@ -325,7 +323,7 @@ public class SnapshotTestWithFakeData  {
         List<Future<Boolean>> future = new ArrayList<Future<Boolean>>();
         for(int i = 0; i < 12; i++) {
             final int cnt = i;
-           Future<Boolean> task =  pool.submit(new Callable<Boolean>() {
+            Future<Boolean> task =  pool.submit(new Callable<Boolean>() {
                 @Override
                 public Boolean call() throws Exception {
                     boolean r = true;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/180cfa19/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 3ead93f..c09adca 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
@@ -17,20 +17,24 @@
 
 package org.apache.cloudstack.storage.snapshot;
 
-import com.cloud.dc.dao.ClusterDao;
-import com.cloud.storage.DataStoreRole;
-import com.cloud.storage.Snapshot;
-import com.cloud.storage.dao.SnapshotDao;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.storage.snapshot.SnapshotManager;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.fsm.NoTransitionException;
-import com.cloud.vm.dao.UserVmDao;
-import com.cloud.vm.snapshot.dao.VMSnapshotDao;
+import java.util.concurrent.ExecutionException;
+
+import javax.inject.Inject;
 
 import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
-import org.apache.cloudstack.engine.subsystem.api.storage.*;
+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.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.Event;
+import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver;
+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.SnapshotService;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
 import org.apache.cloudstack.framework.async.AsyncCallFuture;
 import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher;
 import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
@@ -41,13 +45,19 @@ import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager;
 import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
-
 import org.apache.log4j.Logger;
 import org.springframework.stereotype.Component;
 
-import javax.inject.Inject;
-
-import java.util.concurrent.ExecutionException;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.Snapshot;
+import com.cloud.storage.dao.SnapshotDao;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.storage.snapshot.SnapshotManager;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.fsm.NoTransitionException;
+import com.cloud.vm.dao.UserVmDao;
+import com.cloud.vm.snapshot.dao.VMSnapshotDao;
 
 @Component
 public class SnapshotServiceImpl implements SnapshotService {
@@ -383,7 +393,7 @@ public class SnapshotServiceImpl implements SnapshotService {
     }
 
     @Override
-    public boolean revertSnapshot(SnapshotInfo snapshot) {
+    public boolean revertSnapshot(Long snapshotId) {
         return false;
     }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/180cfa19/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
index 1b57922..6db8343 100644
--- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStrategyBase.java
+++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStrategyBase.java
@@ -11,7 +11,7 @@
 // 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 
+// 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;
@@ -35,4 +35,9 @@ public abstract class SnapshotStrategyBase implements SnapshotStrategy {
     public SnapshotInfo backupSnapshot(SnapshotInfo snapshot) {
         return snapshotSvr.backupSnapshot(snapshot);
     }
+
+    @Override
+    public boolean revertSnapshot(Long snapshotId) {
+        return snapshotSvr.revertSnapshot(snapshotId);
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/180cfa19/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
index 60d9407..aae4cde 100644
--- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java
+++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java
@@ -11,24 +11,27 @@
 // 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 
+// 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 javax.inject.Inject;
 
-import com.cloud.storage.Volume;
-import com.cloud.utils.db.DB;
-import org.apache.cloudstack.engine.subsystem.api.storage.*;
+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.Event;
 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.SnapshotService;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
 import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
 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;
 
@@ -36,9 +39,11 @@ import com.cloud.exception.InvalidParameterValueException;
 import com.cloud.storage.DataStoreRole;
 import com.cloud.storage.Snapshot;
 import com.cloud.storage.SnapshotVO;
+import com.cloud.storage.Volume;
 import com.cloud.storage.dao.SnapshotDao;
 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;
 
@@ -237,6 +242,11 @@ public class XenserverSnapshotStrategy extends SnapshotStrategyBase {
     }
 
     @Override
+    public boolean revertSnapshot(Long snapshotId) {
+        throw new CloudRuntimeException("revert Snapshot is not supported");
+    }
+
+    @Override
     @DB
     public SnapshotInfo takeSnapshot(SnapshotInfo snapshot) {
         SnapshotVO snapshotVO = snapshotDao.acquireInLockTable(snapshot.getId());

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/180cfa19/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java b/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java
index fdc12bf..e7c6627 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java
@@ -27,9 +27,6 @@ import java.util.List;
 
 import javax.inject.Inject;
 
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
 import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
 import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
@@ -37,6 +34,8 @@ import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
 import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
 import org.apache.cloudstack.storage.LocalHostEndpoint;
 import org.apache.cloudstack.storage.RemoteHostEndPoint;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
 
 import com.cloud.host.Host;
 import com.cloud.host.HostVO;
@@ -251,6 +250,11 @@ public class DefaultEndPointSelector implements EndPointSelector {
     }
 
     @Override
+    public EndPoint select(Scope scope, Long storeId) {
+        return findEndPointInScope(scope, findOneHostOnPrimaryStorage, storeId);
+    }
+
+    @Override
     public List<EndPoint> selectAll(DataStore store) {
         List<EndPoint> endPoints = new ArrayList<EndPoint>();
         if (store.getScope().getScopeType() == ScopeType.HOST) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/180cfa19/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
index 82fd2ce..b1c8ec7 100644
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
@@ -18,10 +18,10 @@
  */
 package com.cloud.hypervisor.kvm.storage;
 
+import java.io.BufferedOutputStream;
 import java.io.File;
-import java.io.FileOutputStream;
 import java.io.FileNotFoundException;
-import java.io.BufferedOutputStream;
+import java.io.FileOutputStream;
 import java.io.IOException;
 import java.net.URISyntaxException;
 import java.text.DateFormat;
@@ -35,11 +35,6 @@ import java.util.UUID;
 
 import javax.naming.ConfigurationException;
 
-import com.cloud.agent.api.storage.CopyVolumeAnswer;
-import com.cloud.agent.api.to.DataObjectType;
-import com.cloud.agent.api.to.S3TO;
-import com.cloud.agent.api.to.StorageFilerTO;
-import com.cloud.utils.S3Utils;
 import org.apache.cloudstack.storage.command.AttachAnswer;
 import org.apache.cloudstack.storage.command.AttachCommand;
 import org.apache.cloudstack.storage.command.CopyCmdAnswer;
@@ -49,6 +44,8 @@ import org.apache.cloudstack.storage.command.CreateObjectCommand;
 import org.apache.cloudstack.storage.command.DeleteCommand;
 import org.apache.cloudstack.storage.command.DettachAnswer;
 import org.apache.cloudstack.storage.command.DettachCommand;
+import org.apache.cloudstack.storage.command.ForgetObjectCmd;
+import org.apache.cloudstack.storage.command.IntroduceObjectCmd;
 import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
 import org.apache.cloudstack.storage.to.SnapshotObjectTO;
 import org.apache.cloudstack.storage.to.TemplateObjectTO;
@@ -57,20 +54,28 @@ import org.apache.cloudstack.utils.qemu.QemuImg;
 import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
 import org.apache.cloudstack.utils.qemu.QemuImgException;
 import org.apache.cloudstack.utils.qemu.QemuImgFile;
-import org.apache.log4j.Logger;
 import org.apache.commons.io.FileUtils;
+import org.apache.log4j.Logger;
 import org.libvirt.Connect;
 import org.libvirt.Domain;
 import org.libvirt.DomainInfo;
 import org.libvirt.DomainSnapshot;
 import org.libvirt.LibvirtException;
 
+import com.ceph.rados.IoCTX;
+import com.ceph.rados.Rados;
+import com.ceph.rados.RadosException;
+import com.ceph.rbd.Rbd;
+import com.ceph.rbd.RbdException;
+import com.ceph.rbd.RbdImage;
 import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer;
+import com.cloud.agent.api.to.DataObjectType;
 import com.cloud.agent.api.to.DataStoreTO;
 import com.cloud.agent.api.to.DataTO;
 import com.cloud.agent.api.to.DiskTO;
 import com.cloud.agent.api.to.NfsTO;
+import com.cloud.agent.api.to.S3TO;
 import com.cloud.exception.InternalErrorException;
 import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
 import com.cloud.hypervisor.kvm.resource.LibvirtConnection;
@@ -87,16 +92,10 @@ import com.cloud.storage.template.Processor.FormatInfo;
 import com.cloud.storage.template.QCOW2Processor;
 import com.cloud.storage.template.TemplateLocation;
 import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.S3Utils;
 import com.cloud.utils.exception.CloudRuntimeException;
 import com.cloud.utils.script.Script;
 
-import com.ceph.rados.Rados;
-import com.ceph.rados.RadosException;
-import com.ceph.rados.IoCTX;
-import com.ceph.rbd.Rbd;
-import com.ceph.rbd.RbdImage;
-import com.ceph.rbd.RbdException;
-
 import static com.cloud.utils.S3Utils.putFile;
 
 public class KVMStorageProcessor implements StorageProcessor {
@@ -197,7 +196,7 @@ public class KVMStorageProcessor implements StorageProcessor {
                     primaryPool, cmd.getWaitInMillSeconds());
 
 
-             DataTO data = null;
+            DataTO data = null;
             /**
              * Force the ImageFormat for RBD templates to RAW
              *
@@ -370,7 +369,7 @@ public class KVMStorageProcessor implements StorageProcessor {
             String srcVolumeName = srcVolumePath.substring(index + 1);
             secondaryStoragePool = storagePoolMgr.getStoragePoolByURI(
                     secondaryStorageUrl + File.separator + volumeDir
-                           );
+                    );
             if (!srcVolumeName.endsWith(".qcow2") && srcFormat == ImageFormat.QCOW2) {
                 srcVolumeName = srcVolumeName + ".qcow2";
             }
@@ -1207,4 +1206,14 @@ public class KVMStorageProcessor implements StorageProcessor {
     public Answer deleteSnapshot(DeleteCommand cmd) {
         return new Answer(cmd);
     }
+
+    @Override
+    public Answer introduceObject(IntroduceObjectCmd cmd) {
+        return new Answer(cmd, false, "not implememented yet");
+    }
+
+    @Override
+    public Answer forgetObject(ForgetObjectCmd cmd) {
+        return new Answer(cmd, false, "not implememented yet");
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/180cfa19/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorStorageProcessor.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorStorageProcessor.java b/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorStorageProcessor.java
index c7768aa..1c99272 100644
--- a/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorStorageProcessor.java
+++ b/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorStorageProcessor.java
@@ -19,14 +19,9 @@
 
 package com.cloud.resource;
 
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.to.DataStoreTO;
-import com.cloud.agent.api.to.DataTO;
-import com.cloud.agent.api.to.DiskTO;
-import com.cloud.agent.api.to.NfsTO;
-import com.cloud.agent.manager.SimulatorManager;
-import com.cloud.storage.Storage;
-import com.cloud.storage.resource.StorageProcessor;
+import java.io.File;
+import java.util.UUID;
+
 import org.apache.cloudstack.storage.command.AttachAnswer;
 import org.apache.cloudstack.storage.command.AttachCommand;
 import org.apache.cloudstack.storage.command.CopyCmdAnswer;
@@ -36,13 +31,21 @@ import org.apache.cloudstack.storage.command.CreateObjectCommand;
 import org.apache.cloudstack.storage.command.DeleteCommand;
 import org.apache.cloudstack.storage.command.DettachAnswer;
 import org.apache.cloudstack.storage.command.DettachCommand;
+import org.apache.cloudstack.storage.command.ForgetObjectCmd;
+import org.apache.cloudstack.storage.command.IntroduceObjectCmd;
 import org.apache.cloudstack.storage.to.SnapshotObjectTO;
 import org.apache.cloudstack.storage.to.TemplateObjectTO;
 import org.apache.cloudstack.storage.to.VolumeObjectTO;
 import org.apache.log4j.Logger;
 
-import java.io.File;
-import java.util.UUID;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.to.DataStoreTO;
+import com.cloud.agent.api.to.DataTO;
+import com.cloud.agent.api.to.DiskTO;
+import com.cloud.agent.api.to.NfsTO;
+import com.cloud.agent.manager.SimulatorManager;
+import com.cloud.storage.Storage;
+import com.cloud.storage.resource.StorageProcessor;
 
 public class SimulatorStorageProcessor implements StorageProcessor {
 
@@ -214,4 +217,16 @@ public class SimulatorStorageProcessor implements StorageProcessor {
     public Answer deleteSnapshot(DeleteCommand cmd) {
         return new Answer(cmd);
     }
+
+    @Override
+    public Answer introduceObject(IntroduceObjectCmd cmd) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Answer forgetObject(ForgetObjectCmd cmd) {
+        // TODO Auto-generated method stub
+        return null;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/180cfa19/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java
index 4982d87..a14c403 100644
--- a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java
@@ -26,22 +26,6 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
-
-import org.apache.commons.lang.StringUtils;
-import org.apache.log4j.Logger;
-
-import com.google.gson.Gson;
-import com.vmware.vim25.ManagedObjectReference;
-import com.vmware.vim25.VirtualDeviceConfigSpec;
-import com.vmware.vim25.VirtualDeviceConfigSpecOperation;
-import com.vmware.vim25.VirtualDisk;
-import com.vmware.vim25.VirtualEthernetCard;
-import com.vmware.vim25.VirtualLsiLogicController;
-import com.vmware.vim25.VirtualMachineConfigSpec;
-import com.vmware.vim25.VirtualMachineFileInfo;
-import com.vmware.vim25.VirtualMachineGuestOsIdentifier;
-import com.vmware.vim25.VirtualSCSISharing;
-
 import org.apache.cloudstack.storage.command.AttachAnswer;
 import org.apache.cloudstack.storage.command.AttachCommand;
 import org.apache.cloudstack.storage.command.CopyCmdAnswer;
@@ -50,10 +34,14 @@ import org.apache.cloudstack.storage.command.CreateObjectAnswer;
 import org.apache.cloudstack.storage.command.CreateObjectCommand;
 import org.apache.cloudstack.storage.command.DeleteCommand;
 import org.apache.cloudstack.storage.command.DettachCommand;
+import org.apache.cloudstack.storage.command.ForgetObjectCmd;
+import org.apache.cloudstack.storage.command.IntroduceObjectCmd;
 import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
 import org.apache.cloudstack.storage.to.SnapshotObjectTO;
 import org.apache.cloudstack.storage.to.TemplateObjectTO;
 import org.apache.cloudstack.storage.to.VolumeObjectTO;
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
 
 import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.Command;
@@ -88,10 +76,13 @@ import com.cloud.utils.Pair;
 import com.cloud.utils.Ternary;
 import com.cloud.utils.script.Script;
 import com.cloud.vm.VirtualMachine.State;
+import com.google.gson.Gson;
+import com.vmware.vim25.ManagedObjectReference;
+import com.vmware.vim25.VirtualDisk;
 
 public class VmwareStorageProcessor implements StorageProcessor {
     private static final Logger s_logger = Logger.getLogger(VmwareStorageProcessor.class);
-    
+
     private VmwareHostService hostService;
     private boolean _fullCloneFlag;
     private VmwareStorageMount mountService;
@@ -128,9 +119,9 @@ public class VmwareStorageProcessor implements StorageProcessor {
         }
         return null;
     }
-    
+
     private void copyTemplateFromSecondaryToPrimary(VmwareHypervisorHost hyperHost, DatastoreMO datastoreMo, String secondaryStorageUrl,
-        String templatePathAtSecondaryStorage, String templateName, String templateUuid) throws Exception {
+            String templatePathAtSecondaryStorage, String templateName, String templateUuid) throws Exception {
 
         s_logger.info("Executing copyTemplateFromSecondaryToPrimary. secondaryStorage: "
                 + secondaryStorageUrl + ", templatePathAtSecondaryStorage: " + templatePathAtSecondaryStorage
@@ -140,9 +131,9 @@ public class VmwareStorageProcessor implements StorageProcessor {
         s_logger.info("Secondary storage mount point: " + secondaryMountPoint);
 
         String srcOVAFileName = VmwareStorageLayoutHelper.getTemplateOnSecStorageFilePath(
-        	secondaryMountPoint, templatePathAtSecondaryStorage,
-        	templateName, ImageFormat.OVA.getFileExtension());
-        		
+                secondaryMountPoint, templatePathAtSecondaryStorage,
+                templateName, ImageFormat.OVA.getFileExtension());
+
         String srcFileName = getOVFFilePath(srcOVAFileName);
         if(srcFileName == null) {
             Script command = new Script("tar", 0, s_logger);
@@ -178,8 +169,8 @@ public class VmwareStorageProcessor implements StorageProcessor {
         }
 
         if(vmMo.createSnapshot("cloud.template.base", "Base snapshot", false, false)) {
-        	// the same template may be deployed with multiple copies at per-datastore per-host basis,
-        	// save the original template name from CloudStack DB as the UUID to associate them.
+            // the same template may be deployed with multiple copies at per-datastore per-host basis,
+            // save the original template name from CloudStack DB as the UUID to associate them.
             vmMo.setCustomFieldValue(CustomFieldConstants.CLOUD_UUID, templateName);
             vmMo.markAsTemplate();
         } else {
@@ -197,7 +188,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
         DataStoreTO srcStore = srcData.getDataStore();
         if (!(srcStore instanceof NfsTO)) {
             return new CopyCmdAnswer("unsupported protocol");
-        	}
+        }
         NfsTO nfsImageStore = (NfsTO)srcStore;
         DataTO destData = cmd.getDestTO();
         DataStoreTO destStore = destData.getDataStore();
@@ -206,9 +197,9 @@ public class VmwareStorageProcessor implements StorageProcessor {
         assert (secondaryStorageUrl != null);
 
         String templateUrl = secondaryStorageUrl + "/" + srcData.getPath();
-        
+
         Pair<String, String> templateInfo = VmwareStorageLayoutHelper.decodeTemplateRelativePathAndNameFromUrl(
-        	secondaryStorageUrl, templateUrl, template.getName());
+                secondaryStorageUrl, templateUrl, template.getName());
 
         VmwareContext context = hostService.getServiceContext(cmd);
         try {
@@ -246,7 +237,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
             return new CopyCmdAnswer(msg);
         }
     }
-    
+
     private boolean createVMLinkedClone(VirtualMachineMO vmTemplate, DatacenterMO dcMo, DatastoreMO dsMo,
             String vmdkName, ManagedObjectReference morDatastore, ManagedObjectReference morPool) throws Exception {
 
@@ -265,16 +256,16 @@ public class VmwareStorageProcessor implements StorageProcessor {
         }
 
         s_logger.info("Move volume out of volume-wrapper VM ");
-        String[] vmwareLayoutFilePair = VmwareStorageLayoutHelper.getVmdkFilePairDatastorePath(dsMo, 
-        		vmdkName, vmdkName, VmwareStorageLayoutType.VMWARE, true);
-        String[] legacyCloudStackLayoutFilePair = VmwareStorageLayoutHelper.getVmdkFilePairDatastorePath(dsMo, 
-        		vmdkName, vmdkName, VmwareStorageLayoutType.CLOUDSTACK_LEGACY, true);
-        
+        String[] vmwareLayoutFilePair = VmwareStorageLayoutHelper.getVmdkFilePairDatastorePath(dsMo,
+                vmdkName, vmdkName, VmwareStorageLayoutType.VMWARE, true);
+        String[] legacyCloudStackLayoutFilePair = VmwareStorageLayoutHelper.getVmdkFilePairDatastorePath(dsMo,
+                vmdkName, vmdkName, VmwareStorageLayoutType.CLOUDSTACK_LEGACY, true);
+
         dsMo.moveDatastoreFile(vmwareLayoutFilePair[0],
                 dcMo.getMor(), dsMo.getMor(),
                 legacyCloudStackLayoutFilePair[0],
                 dcMo.getMor(), true);
-        
+
         dsMo.moveDatastoreFile(vmwareLayoutFilePair[1],
                 dcMo.getMor(), dsMo.getMor(),
                 legacyCloudStackLayoutFilePair[1],
@@ -292,18 +283,18 @@ public class VmwareStorageProcessor implements StorageProcessor {
             s_logger.error(msg);
             throw new Exception(msg);
         }
-        
+
         s_logger.info("Move volume out of volume-wrapper VM ");
-        String[] vmwareLayoutFilePair = VmwareStorageLayoutHelper.getVmdkFilePairDatastorePath(dsMo, 
-        		vmdkName, vmdkName, VmwareStorageLayoutType.VMWARE, false);
-        String[] legacyCloudStackLayoutFilePair = VmwareStorageLayoutHelper.getVmdkFilePairDatastorePath(dsMo, 
-        		vmdkName, vmdkName, VmwareStorageLayoutType.CLOUDSTACK_LEGACY, false);
-        
+        String[] vmwareLayoutFilePair = VmwareStorageLayoutHelper.getVmdkFilePairDatastorePath(dsMo,
+                vmdkName, vmdkName, VmwareStorageLayoutType.VMWARE, false);
+        String[] legacyCloudStackLayoutFilePair = VmwareStorageLayoutHelper.getVmdkFilePairDatastorePath(dsMo,
+                vmdkName, vmdkName, VmwareStorageLayoutType.CLOUDSTACK_LEGACY, false);
+
         dsMo.moveDatastoreFile(vmwareLayoutFilePair[0],
                 dcMo.getMor(), dsMo.getMor(),
                 legacyCloudStackLayoutFilePair[0],
                 dcMo.getMor(), true);
-        
+
         dsMo.moveDatastoreFile(vmwareLayoutFilePair[1],
                 dcMo.getMor(), dsMo.getMor(),
                 legacyCloudStackLayoutFilePair[1],
@@ -343,17 +334,17 @@ public class VmwareStorageProcessor implements StorageProcessor {
                         throw new Exception("Unable to create a dummy VM for volume creation");
                     }
 
-                    String vmdkFilePair[] = VmwareStorageLayoutHelper.getVmdkFilePairDatastorePath(dsMo, null, vmdkName, 
-                    	VmwareStorageLayoutType.CLOUDSTACK_LEGACY, 
-                    	true	// we only use the first file in the pair, linked or not will not matter
-                    	);
+                    String vmdkFilePair[] = VmwareStorageLayoutHelper.getVmdkFilePairDatastorePath(dsMo, null, vmdkName,
+                            VmwareStorageLayoutType.CLOUDSTACK_LEGACY,
+                            true	// we only use the first file in the pair, linked or not will not matter
+                            );
                     String volumeDatastorePath = vmdkFilePair[0];
                     synchronized (this) {
                         s_logger.info("Delete file if exists in datastore to clear the way for creating the volume. file: " + volumeDatastorePath);
                         VmwareStorageLayoutHelper.deleteVolumeVmdkFiles(dsMo, vmdkName, dcMo);
                         vmMo.createDisk(volumeDatastorePath, (int) (volume.getSize() / (1024L * 1024L)), morDatastore, -1);
                         vmMo.detachDisk(volumeDatastorePath, false);
-                    }	
+                    }
 
                     VolumeObjectTO newVol = new VolumeObjectTO();
                     newVol.setPath(vmdkName);
@@ -506,7 +497,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
 
         try {
             ManagedObjectReference morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, poolId);
-            
+
             if (morDs == null) {
                 String msg = "Unable to find volumes's storage pool for copy volume operation";
                 s_logger.error(msg);
@@ -518,7 +509,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
                 // create a dummy worker vm for attaching the volume
                 DatastoreMO dsMo = new DatastoreMO(hyperHost.getContext(), morDs);
                 workerVm = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, workerVmName);
-                
+
                 if (workerVm == null) {
                     String msg = "Unable to create worker VM to execute CopyVolumeCommand";
                     s_logger.error(msg);
@@ -657,7 +648,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
             Pair<VirtualMachineMO, String[]> cloneResult = vmMo.cloneFromCurrentSnapshot(workerVmName, 0, 4, volumeDeviceInfo.second(),
                     VmwareHelper.getDiskDeviceDatastore(volumeDeviceInfo.first()));
             clonedVm = cloneResult.first();
-            
+
             clonedVm.exportVm(secondaryMountPoint + "/" + installPath, templateUniqueName, true, false);
 
             long physicalSize = new File(installFullPath + "/" + templateUniqueName + ".ova").length();
@@ -960,7 +951,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
                     throw new Exception("unable to prepare snapshot backup directory");
                 }
             }
-        }	
+        }
 
         VirtualMachineMO clonedVm = null;
         try {
@@ -974,7 +965,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
 
             // 4 MB is the minimum requirement for VM memory in VMware
             Pair<VirtualMachineMO, String[]> cloneResult = vmMo.cloneFromCurrentSnapshot(workerVmName, 0, 4, volumeDeviceInfo.second(),
-                VmwareHelper.getDiskDeviceDatastore(volumeDeviceInfo.first()));
+                    VmwareHelper.getDiskDeviceDatastore(volumeDeviceInfo.first()));
             clonedVm = cloneResult.first();
             String disks[] = cloneResult.second();
 
@@ -998,7 +989,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
                 installPath, backupUuid, workerVmName);
         return new Ternary<String, String, String[]>(backupUuid + "/" + backupUuid, snapshotInfo.first(), snapshotInfo.second());
     }
-    
+
     @Override
     public Answer backupSnapshot(CopyCommand cmd) {
         SnapshotObjectTO srcSnapshot = (SnapshotObjectTO)cmd.getSrcTO();
@@ -1025,7 +1016,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
         String details = null;
         boolean success = false;
         String snapshotBackupUuid = null;
-        
+
         boolean hasOwnerVm = false;
         Ternary<String, String, String[]> backupResult = null;
 
@@ -1037,7 +1028,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
             morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, primaryStore.getUuid());
 
             CopyCmdAnswer answer = null;
-            
+
             try {
                 vmMo = hyperHost.findVmOnHyperHost(vmName);
                 if (vmMo == null) {
@@ -1050,7 +1041,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
                         dsMo = new DatastoreMO(hyperHost.getContext(), morDs);
 
                         workerVMName = hostService.getWorkerName(context, cmd, 0);
-                        
+
                         vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, workerVMName);
 
                         if (vmMo == null) {
@@ -1062,12 +1053,12 @@ public class VmwareStorageProcessor implements StorageProcessor {
                         String datastoreVolumePath = dsMo.getDatastorePath(volumePath + ".vmdk");
                         vmMo.attachDisk(new String[] { datastoreVolumePath }, morDs);
                     } else {
-                    	s_logger.info("Using owner VM " + vmName + " for snapshot operation");
-                    	hasOwnerVm = true;
+                        s_logger.info("Using owner VM " + vmName + " for snapshot operation");
+                        hasOwnerVm = true;
                     }
                 } else {
-                	s_logger.info("Using owner VM " + vmName + " for snapshot operation");
-                	hasOwnerVm = true;
+                    s_logger.info("Using owner VM " + vmName + " for snapshot operation");
+                    hasOwnerVm = true;
                 }
 
                 if (!vmMo.createSnapshot(snapshotUuid, "Snapshot taken for " + srcSnapshot.getName(), false, false)) {
@@ -1093,52 +1084,52 @@ public class VmwareStorageProcessor implements StorageProcessor {
                     ManagedObjectReference snapshotMor = vmMo.getSnapshotMor(snapshotUuid);
                     if (snapshotMor != null) {
                         vmMo.removeSnapshot(snapshotUuid, false);
-                        
+
                         // Snapshot operation may cause disk consolidation in VMware, when this happens
                         // we need to update CloudStack DB
                         //
                         // TODO: this post operation fixup is not atomic and not safe when management server stops
                         // in the middle
                         if(backupResult != null && hasOwnerVm) {
-                        	s_logger.info("Check if we have disk consolidation after snapshot operation");
-                        	
-                        	boolean chainConsolidated = false;
-                        	for(String vmdkDsFilePath : backupResult.third()) {
-                        		s_logger.info("Validate disk chain file:" + vmdkDsFilePath);
-                        		
-                        		if(vmMo.getDiskDevice(vmdkDsFilePath, false) == null) {
-                        			s_logger.info("" + vmdkDsFilePath + " no longer exists, consolidation detected");
-                        			chainConsolidated = true;
-                        			break;
-                        		} else {
-                        			s_logger.info("" + vmdkDsFilePath + " is found still in chain");
-                        		}
-                        	}
-                        	
-                        	if(chainConsolidated) {
-                        		String topVmdkFilePath = null;
-                        		try {
-                        			topVmdkFilePath = vmMo.getDiskCurrentTopBackingFileInChain(backupResult.second());
-                        		} catch(Exception e) {
-                        			s_logger.error("Unexpected exception", e);
-                        		}
-                        		
-                        		s_logger.info("Disk has been consolidated, top VMDK is now: " + topVmdkFilePath);
-                        		if(topVmdkFilePath != null) {
-	                        		DatastoreFile file = new DatastoreFile(topVmdkFilePath);
-	                        		
-	                        		SnapshotObjectTO snapshotInfo = (SnapshotObjectTO)answer.getNewData();
-	                        		VolumeObjectTO vol = new VolumeObjectTO();
-	                        		vol.setUuid(srcSnapshot.getVolume().getUuid());
-	                        		vol.setPath(file.getFileBaseName());
-	                        		snapshotInfo.setVolume(vol);
-                        		} else {
-                        			s_logger.error("Disk has been consolidated, but top VMDK is not found ?!");
-                        		}
-                        	}
+                            s_logger.info("Check if we have disk consolidation after snapshot operation");
+
+                            boolean chainConsolidated = false;
+                            for(String vmdkDsFilePath : backupResult.third()) {
+                                s_logger.info("Validate disk chain file:" + vmdkDsFilePath);
+
+                                if(vmMo.getDiskDevice(vmdkDsFilePath, false) == null) {
+                                    s_logger.info("" + vmdkDsFilePath + " no longer exists, consolidation detected");
+                                    chainConsolidated = true;
+                                    break;
+                                } else {
+                                    s_logger.info("" + vmdkDsFilePath + " is found still in chain");
+                                }
+                            }
+
+                            if(chainConsolidated) {
+                                String topVmdkFilePath = null;
+                                try {
+                                    topVmdkFilePath = vmMo.getDiskCurrentTopBackingFileInChain(backupResult.second());
+                                } catch(Exception e) {
+                                    s_logger.error("Unexpected exception", e);
+                                }
+
+                                s_logger.info("Disk has been consolidated, top VMDK is now: " + topVmdkFilePath);
+                                if(topVmdkFilePath != null) {
+                                    DatastoreFile file = new DatastoreFile(topVmdkFilePath);
+
+                                    SnapshotObjectTO snapshotInfo = (SnapshotObjectTO)answer.getNewData();
+                                    VolumeObjectTO vol = new VolumeObjectTO();
+                                    vol.setUuid(srcSnapshot.getVolume().getUuid());
+                                    vol.setPath(file.getFileBaseName());
+                                    snapshotInfo.setVolume(vol);
+                                } else {
+                                    s_logger.error("Disk has been consolidated, but top VMDK is not found ?!");
+                                }
+                            }
                         }
                     } else {
-                    	s_logger.error("Can not find the snapshot we just used ?!");
+                        s_logger.error("Can not find the snapshot we just used ?!");
                     }
                 }
 
@@ -1152,7 +1143,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
                     s_logger.warn("Failed to destroy worker VM: " + workerVMName);
                 }
             }
-            
+
             return answer;
         } catch (Throwable e) {
             if (e instanceof RemoteException) {
@@ -1205,7 +1196,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
             }
             else {
                 morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, isManaged ? VmwareResource.getDatastoreName(iScsiName) : primaryStore.getUuid());
-           }
+            }
 
             if (morDs == null) {
                 String msg = "Unable to find the mounted datastore to execute AttachVolumeCommand, vmName: " + vmName;
@@ -1217,30 +1208,30 @@ public class VmwareStorageProcessor implements StorageProcessor {
             String datastoreVolumePath;
 
             if(isAttach) {
-            	if(!isManaged)
-	            	datastoreVolumePath = VmwareStorageLayoutHelper.syncVolumeToVmDefaultFolder(dsMo.getOwnerDatacenter().first(), vmName, 
-		                dsMo, volumeTO.getPath());
-            	else 
-            		datastoreVolumePath = dsMo.getDatastorePath(dsMo.getName() + ".vmdk");
+                if(!isManaged)
+                    datastoreVolumePath = VmwareStorageLayoutHelper.syncVolumeToVmDefaultFolder(dsMo.getOwnerDatacenter().first(), vmName,
+                            dsMo, volumeTO.getPath());
+                else
+                    datastoreVolumePath = dsMo.getDatastorePath(dsMo.getName() + ".vmdk");
             } else {
-            	datastoreVolumePath = VmwareStorageLayoutHelper.getLegacyDatastorePathFromVmdkFileName(dsMo, volumeTO.getPath() + ".vmdk");
-            	if(!dsMo.fileExists(datastoreVolumePath))
-            		datastoreVolumePath = VmwareStorageLayoutHelper.getVmwareDatastorePathFromVmdkFileName(dsMo, vmName, volumeTO.getPath() + ".vmdk");
+                datastoreVolumePath = VmwareStorageLayoutHelper.getLegacyDatastorePathFromVmdkFileName(dsMo, volumeTO.getPath() + ".vmdk");
+                if(!dsMo.fileExists(datastoreVolumePath))
+                    datastoreVolumePath = VmwareStorageLayoutHelper.getVmwareDatastorePathFromVmdkFileName(dsMo, vmName, volumeTO.getPath() + ".vmdk");
             }
-            
+
             disk.setVdiUuid(datastoreVolumePath);
 
             AttachAnswer answer = new AttachAnswer(disk);
             if (isAttach) {
                 vmMo.attachDisk(new String[] { datastoreVolumePath }, morDs);
-            } else {	
+            } else {
                 vmMo.removeAllSnapshots();
                 vmMo.detachDisk(datastoreVolumePath, false);
 
                 if (isManaged) {
                     this.hostService.handleDatastoreAndVmdkDetach(iScsiName, storageHost, storagePort);
                 } else {
-                	VmwareStorageLayoutHelper.syncVolumeToRootFolder(dsMo.getOwnerDatacenter().first(), dsMo, volumeTO.getPath());
+                    VmwareStorageLayoutHelper.syncVolumeToRootFolder(dsMo.getOwnerDatacenter().first(), dsMo, volumeTO.getPath());
                 }
             }
 
@@ -1274,7 +1265,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
 
         return morDatastore;
     }
-    
+
     private Answer attachIso(DiskTO disk, boolean isAttach, String vmName) {
         try {
             VmwareHypervisorHost hyperHost = hostService.getHyperHost(hostService.getServiceContext(null), null);
@@ -1387,7 +1378,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
             String volumeDatastorePath = dsMo.getDatastorePath(volumeUuid + ".vmdk");
             String dummyVmName = this.hostService.getWorkerName(context, cmd, 0);
             try {
-            	s_logger.info("Create worker VM " + dummyVmName);
+                s_logger.info("Create worker VM " + dummyVmName);
                 vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, dummyVmName);
                 if (vmMo == null) {
                     throw new Exception("Unable to create a dummy VM for volume creation");
@@ -1408,8 +1399,8 @@ public class VmwareStorageProcessor implements StorageProcessor {
             } finally {
                 s_logger.info("Destroy dummy VM after volume creation");
                 if(vmMo != null) {
-	                vmMo.detachAllDisks();
-	                vmMo.destroy();
+                    vmMo.detachAllDisks();
+                    vmMo.destroy();
                 }
             }
         } catch (Throwable e) {
@@ -1460,7 +1451,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
             ClusterMO clusterMo = new ClusterMO(context, morCluster);
 
             if (vol.getVolumeType() == Volume.Type.ROOT) {
-            	
+
                 String vmName = vol.getVmName();
                 if (vmName != null) {
                     VirtualMachineMO vmMo = clusterMo.findVmOnHyperHost(vmName);
@@ -1471,12 +1462,12 @@ public class VmwareStorageProcessor implements StorageProcessor {
 
                         // Remove all snapshots to consolidate disks for removal
                         vmMo.removeAllSnapshots();
-                        
+
                         VirtualMachineDiskInfo diskInfo = null;
                         if(vol.getChainInfo() != null)
-                        	diskInfo = _gson.fromJson(vol.getChainInfo(), VirtualMachineDiskInfo.class);
-                        
-                        
+                            diskInfo = _gson.fromJson(vol.getChainInfo(), VirtualMachineDiskInfo.class);
+
+
                         HostMO hostMo = vmMo.getRunningHost();
                         List<NetworkDetails> networks = vmMo.getNetworksWithDetails();
 
@@ -1484,7 +1475,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
                         if (this.resource.getVmState(vmMo) != State.Stopped) {
                             vmMo.safePowerOff(_shutdown_waitMs);
                         }
-                        
+
                         List<String> detachedDisks = vmMo.detachAllDisksExcept(vol.getPath(), diskInfo != null ? diskInfo.getDiskDeviceBusName() : null);
                         VmwareStorageLayoutHelper.moveVolumeToRootFolder(new DatacenterMO(context, morDc), detachedDisks);
 
@@ -1501,13 +1492,13 @@ public class VmwareStorageProcessor implements StorageProcessor {
                         }
                     }
 
-/*                    
+                    /*
                     if (s_logger.isInfoEnabled()) {
                         s_logger.info("Destroy volume by original name: " + vol.getPath() + ".vmdk");
                     }
 
                     VmwareStorageLayoutHelper.deleteVolumeVmdkFiles(dsMo, vol.getPath(), new DatacenterMO(context, morDc));
-*/
+                     */
                     return new Answer(cmd, true, "Success");
                 }
 
@@ -1527,8 +1518,8 @@ public class VmwareStorageProcessor implements StorageProcessor {
                 }
             }
 
-            VmwareStorageLayoutHelper.deleteVolumeVmdkFiles(dsMo, vol.getPath(), new DatacenterMO(context, morDc));                   
-            
+            VmwareStorageLayoutHelper.deleteVolumeVmdkFiles(dsMo, vol.getPath(), new DatacenterMO(context, morDc));
+
             return new Answer(cmd, true, "Success");
         } catch (Throwable e) {
             if (e instanceof RemoteException) {
@@ -1672,10 +1663,20 @@ public class VmwareStorageProcessor implements StorageProcessor {
             return new Answer(cmd, false, "unsupported command");
         }
     }
-    
+
+    @Override
+    public Answer introduceObject(IntroduceObjectCmd cmd) {
+        return new Answer(cmd, false, "not implememented yet");
+    }
+
+    @Override
+    public Answer forgetObject(ForgetObjectCmd cmd) {
+        return new Answer(cmd, false, "not implememented yet");
+    }
+
     private static String deriveTemplateUuidOnHost(VmwareHypervisorHost hyperHost, String storeIdentifier, String templateName) {
-    	String templateUuid = UUID.nameUUIDFromBytes((templateName + "@" + storeIdentifier + "-" + hyperHost.getMor().getValue()).getBytes()).toString();
-    	templateUuid = templateUuid.replaceAll("-", "");
-    	return templateUuid;
+        String templateUuid = UUID.nameUUIDFromBytes((templateName + "@" + storeIdentifier + "-" + hyperHost.getMor().getValue()).getBytes()).toString();
+        templateUuid = templateUuid.replaceAll("-", "");
+        return templateUuid;
     }
 }