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/12/20 00:06:44 UTC

[01/10] git commit: updated refs/heads/master to 62bb5d8

Updated Branches:
  refs/heads/master 227567cf6 -> 62bb5d884


Fix snapshot details dao


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

Branch: refs/heads/master
Commit: a3fade86b24e85a136a4dbcc19bc5cef330528b0
Parents: 227567c
Author: edison su <su...@gmail.com>
Authored: Tue Dec 3 13:01:51 2013 -0800
Committer: Edison Su <su...@gmail.com>
Committed: Thu Dec 19 13:35:08 2013 -0800

----------------------------------------------------------------------
 .../cloudstack/core/spring-engine-schema-core-daos-context.xml   | 1 +
 engine/schema/src/com/cloud/storage/dao/SnapshotDetailsVO.java   | 4 ++++
 2 files changed, 5 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a3fade86/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml
----------------------------------------------------------------------
diff --git a/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml b/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml
index a3747c0..6ec63bc 100644
--- a/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml
+++ b/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml
@@ -251,6 +251,7 @@
   <bean id="site2SiteVpnConnectionDaoImpl" class="com.cloud.network.dao.Site2SiteVpnConnectionDaoImpl" />
   <bean id="site2SiteVpnGatewayDaoImpl" class="com.cloud.network.dao.Site2SiteVpnGatewayDaoImpl" />
   <bean id="snapshotDaoImpl" class="com.cloud.storage.dao.SnapshotDaoImpl" />
+  <bean id="snapshotDetailsDaoImpl" class="com.cloud.storage.dao.SnapshotDetailsDaoImpl" />
   <bean id="snapshotPolicyDaoImpl" class="com.cloud.storage.dao.SnapshotPolicyDaoImpl" />
   <bean id="snapshotScheduleDaoImpl" class="com.cloud.storage.dao.SnapshotScheduleDaoImpl" />
   <bean id="sslCertDao" class="com.cloud.network.dao.SslCertDaoImpl" />

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a3fade86/engine/schema/src/com/cloud/storage/dao/SnapshotDetailsVO.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/storage/dao/SnapshotDetailsVO.java b/engine/schema/src/com/cloud/storage/dao/SnapshotDetailsVO.java
index 9bc4b4c..35a7244 100644
--- a/engine/schema/src/com/cloud/storage/dao/SnapshotDetailsVO.java
+++ b/engine/schema/src/com/cloud/storage/dao/SnapshotDetailsVO.java
@@ -44,6 +44,10 @@ public class SnapshotDetailsVO implements ResourceDetail {
     @Column(name = "value")
     String value;
 
+    public SnapshotDetailsVO() {
+
+    }
+
     public SnapshotDetailsVO(Long resourceId, String name, String value) {
         this.resourceId = resourceId;
         this.name = name;


[08/10] git commit: updated refs/heads/master to 62bb5d8

Posted by ed...@apache.org.
add xenserver 6.2.0 hotfix support, to optimize vdi copy

add xenserver hot fix

Conflicts:

	api/src/com/cloud/vm/VirtualMachineName.java
	core/src/com/cloud/host/HostInfo.java
	core/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java
	deps/XenServerJava/src/com/xensource/xenapi/VDI.java
	engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java
	engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java
	engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java
	plugins/hypervisors/xen/src/com/cloud/hypervisor/XenServerGuru.java
	plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
	plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerPoolVms.java
	plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java
	server/src/com/cloud/configuration/Config.java


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

Branch: refs/heads/master
Commit: 8caf52c6bc1ea6ff6be17d4ce4da60460fa2663a
Parents: c40d03b
Author: Edison Su <su...@gmail.com>
Authored: Thu Dec 19 14:15:41 2013 -0800
Committer: Edison Su <su...@gmail.com>
Committed: Thu Dec 19 14:15:41 2013 -0800

----------------------------------------------------------------------
 api/src/com/cloud/vm/VirtualMachineName.java    |  13 +
 core/src/com/cloud/host/HostInfo.java           |   3 +-
 .../cloudstack/storage/command/CopyCommand.java |  12 +
 .../cloudstack/storage/to/SnapshotObjectTO.java |  17 +
 .../src/com/xensource/xenapi/Event.java         |  15 +
 .../src/com/xensource/xenapi/Types.java         |  50 ++
 .../src/com/xensource/xenapi/VDI.java           |  23 +
 .../subsystem/api/storage/EndPointSelector.java |   2 +
 .../orchestration/VolumeOrchestrator.java       |   8 +-
 .../datastore/db/SnapshotDataStoreDao.java      |   2 +
 .../motion/AncientDataMotionStrategy.java       |  16 +-
 .../snapshot/XenserverSnapshotStrategy.java     |  24 +-
 .../endpoint/DefaultEndPointSelector.java       |  49 ++
 .../image/db/SnapshotDataStoreDaoImpl.java      |  32 +
 .../src/com/cloud/hypervisor/XenServerGuru.java |  40 +-
 .../xen/discoverer/XcpServerDiscoverer.java     |  48 +-
 .../xen/resource/CitrixResourceBase.java        | 650 ++-------------
 .../xen/resource/XenServerPoolVms.java          |   5 +
 .../xen/resource/XenServerStorageProcessor.java |   2 +-
 .../xen/resource/Xenserver625Resource.java      | 112 +++
 .../resource/Xenserver625StorageProcessor.java  | 822 +++++++++++++++++++
 .../xenserver/XenServerResourceNewBase.java     | 340 ++++++++
 .../xenserver/xenserver62/cloud-plugin-storage  | 301 +++++++
 .../vm/hypervisor/xenserver/xenserver62/patch   |  74 ++
 server/src/com/cloud/configuration/Config.java  |   7 +
 25 files changed, 2036 insertions(+), 631 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8caf52c6/api/src/com/cloud/vm/VirtualMachineName.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/vm/VirtualMachineName.java b/api/src/com/cloud/vm/VirtualMachineName.java
index c5fc3de..d3b14c7 100755
--- a/api/src/com/cloud/vm/VirtualMachineName.java
+++ b/api/src/com/cloud/vm/VirtualMachineName.java
@@ -26,6 +26,19 @@ import com.cloud.dc.Vlan;
 public class VirtualMachineName {
     public static final String SEPARATOR = "-";
 
+    public static boolean isValidCloudStackVmName(String name, String instance) {
+        String[] parts = name.split(SEPARATOR);
+        if (parts.length <= 1) {
+            return false;
+        }
+
+        if (!parts[parts.length - 1].equals(instance)) {
+            return false;
+        }
+
+        return true;
+    }
+    
     public static String getVnetName(long vnetId) {
         StringBuilder vnet = new StringBuilder();
         Formatter formatter = new Formatter(vnet);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8caf52c6/core/src/com/cloud/host/HostInfo.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/host/HostInfo.java b/core/src/com/cloud/host/HostInfo.java
index 89fb806..4a95aa8 100644
--- a/core/src/com/cloud/host/HostInfo.java
+++ b/core/src/com/cloud/host/HostInfo.java
@@ -21,5 +21,6 @@ public final class HostInfo {
     public static final String HOST_OS = "Host.OS"; //Fedora, XenServer, Ubuntu, etc
     public static final String HOST_OS_VERSION = "Host.OS.Version"; //12, 5.5, 9.10, etc
     public static final String HOST_OS_KERNEL_VERSION = "Host.OS.Kernel.Version"; //linux-2.6.31 etc
-
+    public static final String XS620_SNAPSHOT_HOTFIX = "xs620_snapshot_hotfix";
 }
+

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8caf52c6/core/src/org/apache/cloudstack/storage/command/CopyCommand.java
----------------------------------------------------------------------
diff --git a/core/src/org/apache/cloudstack/storage/command/CopyCommand.java b/core/src/org/apache/cloudstack/storage/command/CopyCommand.java
index 7fcde1e..446c61f 100644
--- a/core/src/org/apache/cloudstack/storage/command/CopyCommand.java
+++ b/core/src/org/apache/cloudstack/storage/command/CopyCommand.java
@@ -16,6 +16,9 @@
 // under the License.
 package org.apache.cloudstack.storage.command;
 
+import java.util.HashMap;
+import java.util.Map;
+
 import com.cloud.agent.api.Command;
 import com.cloud.agent.api.to.DataTO;
 
@@ -24,6 +27,7 @@ public final class CopyCommand extends Command implements StorageSubSystemComman
     private DataTO destTO;
     private DataTO cacheTO;
     boolean executeInSequence = false;
+    Map<String, String> options = new HashMap<String, String>();
 
     public CopyCommand(DataTO srcData, DataTO destData, int timeout, boolean executeInSequence) {
         super();
@@ -66,4 +70,12 @@ public final class CopyCommand extends Command implements StorageSubSystemComman
         return this.getWait() * 1000;
     }
 
+    public void setOptions(Map<String, String> options) {
+        this.options = options;
+    }
+
+    public Map<String, String> getOptions() {
+        return options;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8caf52c6/core/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java
----------------------------------------------------------------------
diff --git a/core/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java b/core/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java
index 03b4609..51ecc5b 100644
--- a/core/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java
+++ b/core/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java
@@ -16,8 +16,11 @@
 // under the License.
 package org.apache.cloudstack.storage.to;
 
+import java.util.ArrayList;
+
 import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
+import org.apache.commons.lang.ArrayUtils;
 
 import com.cloud.agent.api.to.DataObjectType;
 import com.cloud.agent.api.to.DataStoreTO;
@@ -34,6 +37,8 @@ public class SnapshotObjectTO implements DataTO {
     private HypervisorType hypervisorType;
     private long id;
     private boolean quiescevm;
+    private String[] parents;
+
 
     public SnapshotObjectTO() {
 
@@ -49,9 +54,17 @@ public class SnapshotObjectTO implements DataTO {
         }
 
         SnapshotInfo parentSnapshot = snapshot.getParent();
+        ArrayList<String> parentsArry = new ArrayList<String>();
         if (parentSnapshot != null) {
             this.parentSnapshotPath = parentSnapshot.getPath();
+            while(parentSnapshot != null) {
+                parentsArry.add(parentSnapshot.getPath());
+                parentSnapshot = parentSnapshot.getParent();
+            }
+            parents =  parentsArry.toArray(new String[parentsArry.size()]);
+            ArrayUtils.reverse(parents);
         }
+
         this.dataStore = snapshot.getDataStore().getTO();
         this.setName(snapshot.getName());
         this.hypervisorType = snapshot.getHypervisorType();
@@ -139,6 +152,10 @@ public class SnapshotObjectTO implements DataTO {
         this.quiescevm = quiescevm;
     }
 
+    public String[] getParents() {
+        return parents;
+    }
+
     @Override
     public String toString() {
         return new StringBuilder("SnapshotTO[datastore=").append(dataStore).append("|volume=").append(volume).append("|path").append(path).append("]").toString();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8caf52c6/deps/XenServerJava/src/com/xensource/xenapi/Event.java
----------------------------------------------------------------------
diff --git a/deps/XenServerJava/src/com/xensource/xenapi/Event.java b/deps/XenServerJava/src/com/xensource/xenapi/Event.java
index 68594fb..ec43814 100644
--- a/deps/XenServerJava/src/com/xensource/xenapi/Event.java
+++ b/deps/XenServerJava/src/com/xensource/xenapi/Event.java
@@ -300,4 +300,19 @@ public class Event extends XenAPIObject {
         return Types.toString(result);
     }
 
+    public static Map properFrom(Connection c, Set<String> classes, String token, Double timeout) throws BadServerResponse, XenAPIException, XmlRpcException,
+            Types.SessionNotRegistered,
+            Types.EventsLost {
+        String method_call = "event.from";
+        String session = c.getSessionReference();
+        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(classes), Marshalling.toXMLRPC(token), Marshalling.toXMLRPC(timeout)};
+        Map response = c.dispatch(method_call, method_params);
+        Object result = response.get("Value");
+        Map value = (Map)result;
+        Map<String, Object> from = new HashMap<String, Object>();
+        from.put("token", value.get("token"));
+        from.put("events", Types.toSetOfEventRecord(value.get("events")));
+        return from;
+    }
+
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8caf52c6/deps/XenServerJava/src/com/xensource/xenapi/Types.java
----------------------------------------------------------------------
diff --git a/deps/XenServerJava/src/com/xensource/xenapi/Types.java b/deps/XenServerJava/src/com/xensource/xenapi/Types.java
index c6451ff..777d580 100644
--- a/deps/XenServerJava/src/com/xensource/xenapi/Types.java
+++ b/deps/XenServerJava/src/com/xensource/xenapi/Types.java
@@ -1279,6 +1279,17 @@ public class Types
                 String p1 = ErrorDescription.length > 1 ? ErrorDescription[1] : "";
                 throw new Types.CrlNameInvalid(p1);
             }
+            if (ErrorDescription[0].equals("VDI_NOT_SPARSE"))
+            {
+                String p1 = ErrorDescription.length > 1 ? ErrorDescription[1] : "";
+                throw new Types.VdiNotSparse(p1);
+            }
+            if (ErrorDescription[0].equals("VDI_TOO_SMALL"))
+            {
+                String p1 = ErrorDescription.length > 1 ? ErrorDescription[1] : "";
+                String p2 = ErrorDescription.length > 2 ? ErrorDescription[2] : "";
+                throw new Types.VdiTooSmall(p1, p2);
+            }
             if (ErrorDescription[0].equals("HOST_POWER_ON_MODE_DISABLED"))
             {
                 throw new Types.HostPowerOnModeDisabled();
@@ -7823,6 +7834,45 @@ public class Types
     }
 
     /**
+     * The VDI is too small. Please resize it to at least the minimum size.
+     */
+    public static class VdiTooSmall extends XenAPIException {
+        public final String vdi;
+        public final String minimumSize;
+
+        /**
+         * Create a new VdiTooSmall
+         *
+         * @param vdi
+         * @param minimumSize
+         */
+        public VdiTooSmall(String vdi, String minimumSize) {
+            super("The VDI is too small. Please resize it to at least the minimum size.");
+            this.vdi = vdi;
+            this.minimumSize = minimumSize;
+        }
+
+    }
+
+    /**
+     * The VDI is not stored using a sparse format. It is not possible to query and manipulate only the changed blocks (or 'block differences' or 'disk deltas') between two VDIs. Please select a VDI which uses a sparse-aware technology such as VHD.
+     */
+    public static class VdiNotSparse extends XenAPIException {
+        public final String vdi;
+
+        /**
+         * Create a new VdiNotSparse
+         *
+         * @param vdi
+         */
+        public VdiNotSparse(String vdi) {
+            super("The VDI is not stored using a sparse format. It is not possible to query and manipulate only the changed blocks (or 'block differences' or 'disk deltas') between two VDIs. Please select a VDI which uses a sparse-aware technology such as VHD.");
+            this.vdi = vdi;
+        }
+
+    }
+
+    /**
      * The hosts in this pool are not homogeneous.
      */
     public static class HostsNotHomogeneous extends XenAPIException {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8caf52c6/deps/XenServerJava/src/com/xensource/xenapi/VDI.java
----------------------------------------------------------------------
diff --git a/deps/XenServerJava/src/com/xensource/xenapi/VDI.java b/deps/XenServerJava/src/com/xensource/xenapi/VDI.java
index 2c32c84..992a6a6 100644
--- a/deps/XenServerJava/src/com/xensource/xenapi/VDI.java
+++ b/deps/XenServerJava/src/com/xensource/xenapi/VDI.java
@@ -1609,6 +1609,29 @@ public class VDI extends XenAPIObject {
     }
 
     /**
+     * Copy either a full VDI or the block differences between two VDIs into either a fresh VDI or an existing VDI.
+     *
+     * @param sr The destination SR (only required if the destination VDI is not specified
+     * @param baseVdi The base VDI (only required if copying only changed blocks, by default all blocks will be copied)
+     * @param intoVdi The destination VDI to copy blocks into (if omitted then a destination SR must be provided and a fresh VDI will be created)
+     * @return Task
+     */
+    public Task copyAsync2(Connection c, SR sr, VDI baseVdi, VDI intoVdi) throws
+        BadServerResponse,
+        XenAPIException,
+        XmlRpcException,
+        Types.VdiReadonly,
+        Types.VdiTooSmall,
+        Types.VdiNotSparse {
+        String method_call = "Async.VDI.copy";
+        String session = c.getSessionReference();
+        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref), Marshalling.toXMLRPC(sr), Marshalling.toXMLRPC(baseVdi), Marshalling.toXMLRPC(intoVdi)};
+        Map response = c.dispatch(method_call, method_params);
+        Object result = response.get("Value");
+        return Types.toTask(result);
+    }
+
+    /**
      * Make a fresh VDI in the specified SR and copy the supplied VDI's data to the new disk
      *
      * @param sr The destination SR

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8caf52c6/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 b812f6e..8f5921d 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
@@ -30,4 +30,6 @@ public interface EndPointSelector {
     List<EndPoint> selectAll(DataStore store);
 
     EndPoint select(Scope scope, Long storeId);
+
+    EndPoint selectHypervisorHost(Scope scope);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8caf52c6/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java
----------------------------------------------------------------------
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java
index 4243646..578a785 100644
--- a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java
+++ b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java
@@ -397,10 +397,6 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
         ServiceOffering offering, DiskOffering diskOffering, List<StoragePool> avoids, long size, HypervisorType hyperType) {
         StoragePool pool = null;
 
-        if (diskOffering != null && diskOffering.isCustomized()) {
-            diskOffering.setDiskSize(size);
-        }
-
         DiskProfile dskCh = null;
         if (volume.getVolumeType() == Type.ROOT && Storage.ImageFormat.ISO != template.getFormat()) {
             dskCh = createDiskCharacteristics(volume, template, dc, offering);
@@ -408,6 +404,10 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
             dskCh = createDiskCharacteristics(volume, template, dc, diskOffering);
         }
 
+        if (diskOffering != null && diskOffering.isCustomized()) {
+            dskCh.setSize(size);
+        }
+
         dskCh.setHyperType(hyperType);
 
         final HashSet<StoragePool> avoidPools = new HashSet<StoragePool>(avoids);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8caf52c6/engine/schema/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java b/engine/schema/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java
index 67ce558..83c337d 100644
--- a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java
+++ b/engine/schema/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java
@@ -52,4 +52,6 @@ public interface SnapshotDataStoreDao extends GenericDao<SnapshotDataStoreVO, Lo
     List<SnapshotDataStoreVO> listOnCache(long snapshotId);
 
     void updateStoreRoleToCache(long storeId);
+
+    SnapshotDataStoreVO findLatestSnapshotForVolume(Long volumeId, DataStoreRole role);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8caf52c6/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 48c39cd..3809722 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
@@ -18,13 +18,11 @@
  */
 package org.apache.cloudstack.storage.motion;
 
+import java.util.HashMap;
 import java.util.Map;
 
 import javax.inject.Inject;
 
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
 import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope;
 import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionStrategy;
@@ -46,6 +44,8 @@ import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
 import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
 import org.apache.cloudstack.storage.command.CopyCommand;
 import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
 
 import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.storage.MigrateVolumeAnswer;
@@ -470,6 +470,14 @@ public class AncientDataMotionStrategy implements DataMotionStrategy {
         int _backupsnapshotwait = NumbersUtil.parseInt(value, Integer.parseInt(Config.BackupSnapshotWait.getDefaultValue()));
 
         DataObject cacheData = null;
+        SnapshotInfo snapshotInfo = (SnapshotInfo)srcData;
+        Object payload = snapshotInfo.getPayload();
+        Boolean fullSnapshot = true;
+        if (payload != null) {
+            fullSnapshot = (Boolean)payload;
+        }
+        Map<String, String> options = new HashMap<String, String>();
+        options.put("fullSnapshot", fullSnapshot.toString());
         Answer answer = null;
         try {
             if (needCacheStorage(srcData, destData)) {
@@ -478,6 +486,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy {
 
                 CopyCommand cmd = new CopyCommand(srcData.getTO(), destData.getTO(), _backupsnapshotwait, VirtualMachineManager.ExecuteInSequence.value());
                 cmd.setCacheTO(cacheData.getTO());
+                cmd.setOptions(options);
                 EndPoint ep = selector.select(srcData, destData);
                 if (ep == null) {
                     String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
@@ -488,6 +497,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy {
                 }
             } else {
                 CopyCommand cmd = new CopyCommand(srcData.getTO(), destData.getTO(), _backupsnapshotwait, VirtualMachineManager.ExecuteInSequence.value());
+                cmd.setOptions(options);
                 EndPoint ep = selector.select(srcData, destData);
                 if (ep == null) {
                     String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8caf52c6/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 14fb618..bcae7b5 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
@@ -22,7 +22,6 @@ import javax.inject.Inject;
 
 import org.apache.log4j.Logger;
 import org.springframework.stereotype.Component;
-
 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;
@@ -104,29 +103,30 @@ public class XenserverSnapshotStrategy extends SnapshotStrategyBase {
 
         // determine full snapshot backup or not
 
-        boolean fullBackup = false;
 
-        if (parentSnapshot != null) {
-            int _deltaSnapshotMax = NumbersUtil.parseInt(configDao.getValue("snapshot.delta.max"), SnapshotManager.DELTAMAX);
+        boolean fullBackup = true;
+        SnapshotDataStoreVO parentSnapshotOnBackupStore = snapshotStoreDao.findLatestSnapshotForVolume(snapshot.getVolumeId(), DataStoreRole.Image);
+        if (parentSnapshotOnBackupStore != null) {
+            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 = snapshotStoreDao.findBySnapshot(parentSnapshot.getId(), DataStoreRole.Image);
-                if (parentSnapshotOnBackupStore == null) {
-                    break;
-                }
                 Long prevBackupId = parentSnapshotOnBackupStore.getParentSnapshotId();
-
                 if (prevBackupId == 0) {
                     break;
                 }
-
                 parentSnapshotOnBackupStore = snapshotStoreDao.findBySnapshot(prevBackupId, DataStoreRole.Image);
+                if (parentSnapshotOnBackupStore == null) {
+                    break;
+                }
             }
+
             if (i >= deltaSnap) {
                 fullBackup = true;
+            } else {
+                fullBackup = false;
             }
         }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8caf52c6/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 6560d2f..9f23940 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java
@@ -27,6 +27,7 @@ import java.util.List;
 
 import javax.inject.Inject;
 
+import com.cloud.utils.db.Transaction;
 import org.apache.log4j.Logger;
 import org.springframework.stereotype.Component;
 
@@ -60,6 +61,7 @@ public class DefaultEndPointSelector implements EndPointSelector {
     private final String findOneHostOnPrimaryStorage =
         "select h.id from host h, storage_pool_host_ref s  where h.status = 'Up' and h.type = 'Routing' and h.resource_state = 'Enabled' and"
             + " h.id = s.host_id and s.pool_id = ? ";
+    private String findOneHypervisorHostInScope = "select h.id from host h where h.status = 'Up' and h.hypervisor_type is not null ";
 
     protected boolean moveBetweenPrimaryImage(DataStore srcStore, DataStore destStore) {
         DataStoreRole srcRole = srcStore.getRole();
@@ -292,4 +294,51 @@ public class DefaultEndPointSelector implements EndPointSelector {
         }
         return endPoints;
     }
+
+    @Override
+    public EndPoint selectHypervisorHost(Scope scope) {
+        StringBuilder sbuilder = new StringBuilder();
+        sbuilder.append(findOneHypervisorHostInScope);
+        if (scope.getScopeType() == ScopeType.ZONE) {
+            sbuilder.append(" and h.data_center_id = ");
+            sbuilder.append(scope.getScopeId());
+        } else if (scope.getScopeType() == ScopeType.CLUSTER) {
+            sbuilder.append(" and h.cluster_id = ");
+            sbuilder.append(scope.getScopeId());
+        }
+        sbuilder.append(" ORDER by rand() limit 1");
+
+        String sql = sbuilder.toString();
+        PreparedStatement pstmt = null;
+        ResultSet rs = null;
+        HostVO host = null;
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+
+        try {
+            pstmt = txn.prepareStatement(sql);
+            rs = pstmt.executeQuery();
+            while (rs.next()) {
+                long id = rs.getLong(1);
+                host = hostDao.findById(id);
+            }
+        } catch (SQLException e) {
+            s_logger.warn("can't find endpoint", e);
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (pstmt != null) {
+                    pstmt.close();
+                }
+            } catch (SQLException e) {
+            }
+        }
+
+        if (host == null) {
+            return null;
+        }
+
+        return RemoteHostEndPoint.getHypervisorHostEndPoint(host);
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8caf52c6/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 e40cfd0..519d3db 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
@@ -54,8 +54,13 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase<SnapshotDataStoreVO
     private SearchBuilder<SnapshotDataStoreVO> snapshotSearch;
     private SearchBuilder<SnapshotDataStoreVO> storeSnapshotSearch;
     private SearchBuilder<SnapshotDataStoreVO> snapshotIdSearch;
+
     private final String parentSearch = "select store_id, store_role, snapshot_id from cloud.snapshot_store_ref where store_id = ? "
         + " and store_role = ? and volume_id = ? and state = 'Ready'" + " order by created DESC " + " limit 1";
+    private final String findLatestSnapshot = "select store_id, store_role, snapshot_id from cloud.snapshot_store_ref where " +
+            " store_role = ? and volume_id = ? and state = 'Ready'" +
+            " order by created DESC " +
+            " limit 1";
 
     @Override
     public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
@@ -204,6 +209,33 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase<SnapshotDataStoreVO
     }
 
     @Override
+    public SnapshotDataStoreVO findLatestSnapshotForVolume(Long volumeId, DataStoreRole role) {
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        PreparedStatement pstmt = null;
+        ResultSet rs = null;
+        try {
+            pstmt = txn.prepareStatement(findLatestSnapshot);
+            pstmt.setString(1, role.toString());
+            pstmt.setLong(2, volumeId);
+            rs = pstmt.executeQuery();
+            while (rs.next()) {
+                long sid = rs.getLong(1);
+                long snid = rs.getLong(3);
+                return findByStoreSnapshot(role, sid, snid);
+            }
+        } catch (SQLException e) {
+            s_logger.debug("Failed to find parent snapshot: " + e.toString());
+        } finally {
+            try {
+                if (pstmt != null)
+                    pstmt.close();
+            } catch (SQLException e) {
+            }
+        }
+        return null;
+    }
+
+    @Override
     @DB
     public SnapshotDataStoreVO findParent(DataStoreRole role, Long storeId, Long volumeId) {
         TransactionLegacy txn = TransactionLegacy.currentTxn();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8caf52c6/plugins/hypervisors/xen/src/com/cloud/hypervisor/XenServerGuru.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/XenServerGuru.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/XenServerGuru.java
index bd10cb0..89a727b 100644
--- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/XenServerGuru.java
+++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/XenServerGuru.java
@@ -19,17 +19,30 @@ package com.cloud.hypervisor;
 import javax.ejb.Local;
 import javax.inject.Inject;
 
-import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.to.*;
+import com.cloud.host.HostInfo;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
 import com.cloud.storage.GuestOSVO;
 import com.cloud.storage.dao.GuestOSDao;
 import com.cloud.template.VirtualMachineTemplate.BootloaderType;
+import com.cloud.utils.Pair;
 import com.cloud.vm.VirtualMachineProfile;
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
+import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
+import org.apache.cloudstack.storage.command.CopyCommand;
 
 @Local(value = HypervisorGuru.class)
 public class XenServerGuru extends HypervisorGuruBase implements HypervisorGuru {
     @Inject
     GuestOSDao _guestOsDao;
+    @Inject
+    EndPointSelector endPointSelector;
+    @Inject
+    HostDao hostDao;
 
     protected XenServerGuru() {
         super();
@@ -60,4 +73,29 @@ public class XenServerGuru extends HypervisorGuruBase implements HypervisorGuru
     public boolean trackVmHostChange() {
         return true;
     }
+
+    @Override
+    public Pair<Boolean, Long> getCommandHostDelegation(long hostId, Command cmd) {
+        if (cmd instanceof CopyCommand) {
+            CopyCommand cpyCommand = (CopyCommand)cmd;
+            DataTO srcData = cpyCommand.getSrcTO();
+            DataTO destData = cpyCommand.getDestTO();
+
+            if (srcData.getObjectType() == DataObjectType.SNAPSHOT && destData.getObjectType() == DataObjectType.TEMPLATE) {
+                DataStoreTO srcStore = srcData.getDataStore();
+                DataStoreTO destStore = destData.getDataStore();
+                if (srcStore instanceof NfsTO && destStore instanceof NfsTO) {
+                    HostVO host = hostDao.findById(hostId);
+                    EndPoint ep = endPointSelector.selectHypervisorHost(new ZoneScope(host.getDataCenterId()));
+                    host = hostDao.findById(ep.getId());
+                    hostDao.loadDetails(host);
+                    boolean snapshotHotFix = Boolean.parseBoolean(host.getDetail(HostInfo.XS620_SNAPSHOT_HOTFIX));
+                    if (snapshotHotFix) {
+                        return new Pair<Boolean, Long>(Boolean.TRUE, new Long(ep.getId()));
+                    }
+                }
+            }
+        }
+        return new Pair<Boolean, Long>(Boolean.FALSE, new Long(hostId));
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8caf52c6/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java
index ecdb821..cd1b30b 100755
--- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java
+++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java
@@ -34,13 +34,6 @@ import javax.persistence.EntityExistsException;
 import org.apache.log4j.Logger;
 import org.apache.xmlrpc.XmlRpcException;
 
-import com.xensource.xenapi.Connection;
-import com.xensource.xenapi.Host;
-import com.xensource.xenapi.Pool;
-import com.xensource.xenapi.Session;
-import com.xensource.xenapi.Types.SessionAuthenticationFailed;
-import com.xensource.xenapi.Types.XenAPIException;
-
 import com.cloud.agent.AgentManager;
 import com.cloud.agent.Listener;
 import com.cloud.agent.api.AgentControlAnswer;
@@ -82,6 +75,7 @@ import com.cloud.hypervisor.xen.resource.XenServer602Resource;
 import com.cloud.hypervisor.xen.resource.XenServer610Resource;
 import com.cloud.hypervisor.xen.resource.XenServer620Resource;
 import com.cloud.hypervisor.xen.resource.XenServerConnectionPool;
+import com.cloud.hypervisor.xen.resource.Xenserver625Resource;
 import com.cloud.resource.Discoverer;
 import com.cloud.resource.DiscovererBase;
 import com.cloud.resource.ResourceManager;
@@ -98,6 +92,12 @@ import com.cloud.utils.db.QueryBuilder;
 import com.cloud.utils.db.SearchCriteria.Op;
 import com.cloud.utils.exception.CloudRuntimeException;
 import com.cloud.utils.exception.HypervisorVersionChangedException;
+import com.xensource.xenapi.Connection;
+import com.xensource.xenapi.Host;
+import com.xensource.xenapi.Pool;
+import com.xensource.xenapi.Session;
+import com.xensource.xenapi.Types.SessionAuthenticationFailed;
+import com.xensource.xenapi.Types.XenAPIException;
 
 @Local(value = Discoverer.class)
 public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, Listener, ResourceStateAdapter {
@@ -112,6 +112,7 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L
     protected String _guestNic;
     protected boolean _setupMultipath;
     protected String _instance;
+    private String xs620snapshothotfix = "Xenserver-Vdi-Copy-HotFix";
 
     @Inject
     protected AlertManager _alertMgr;
@@ -149,6 +150,11 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L
         }
     }
 
+    protected boolean xenserverHotFixEnabled() {
+        //temporary fix, we should call xenserver api to get the hot fix is enabled or not.
+        return Boolean.parseBoolean(_configDao.getValue(Config.XenServerHotFix.name()));
+    }
+
     @Override
     public Map<? extends ServerResource, Map<String, String>>
         find(long dcId, Long podId, Long clusterId, URI url, String username, String password, List<String> hostTags) throws DiscoveryException {
@@ -274,6 +280,8 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L
                     hostOS = record.softwareVersion.get("platform_name");
                 }
 
+                //Boolean xs620hotfix = record.tags.contains(xs620snapshothotfix);
+                Boolean xs620hotfix = xenserverHotFixEnabled();
                 String hostOSVer = prodVersion;
                 String hostKernelVer = record.softwareVersion.get("linux");
 
@@ -303,6 +311,7 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L
                 details.put(HostInfo.HOST_OS_VERSION, hostOSVer);
                 details.put(HostInfo.HOST_OS_KERNEL_VERSION, hostKernelVer);
                 details.put(HostInfo.HYPERVISOR_VERSION, xenVersion);
+                details.put(HostInfo.XS620_SNAPSHOT_HOTFIX, xs620hotfix.toString());
 
                 String privateNetworkLabel = _networkMgr.getDefaultManagementTrafficLabel(dcId, HypervisorType.XenServer);
                 String storageNetworkLabel = _networkMgr.getDefaultStorageTrafficLabel(dcId, HypervisorType.XenServer);
@@ -452,9 +461,21 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L
             return new XenServer602Resource();
         else if (prodBrand.equals("XenServer") && prodVersion.equals("6.1.0"))
             return new XenServer610Resource();
-        else if (prodBrand.equals("XenServer") && prodVersion.equals("6.2.0"))
-            return new XenServer620Resource();
-        else if (prodBrand.equals("XenServer") && prodVersion.equals("5.6.100")) {
+        else if (prodBrand.equals("XenServer") && prodVersion.equals("6.2.0")) {
+            /*
+            Set<String> tags =record.tags;
+            if (tags.contains(xs620snapshothotfix)) {
+                return new Xenserver625Resource();
+            } else {
+                return new XenServer620Resource();
+            }*/
+            boolean hotfix = xenserverHotFixEnabled();
+            if (hotfix) {
+                return new Xenserver625Resource();
+            } else {
+                return new XenServer620Resource();
+            }
+        } else if (prodBrand.equals("XenServer") && prodVersion.equals("5.6.100")) {
             String prodVersionTextShort = record.softwareVersion.get("product_version_text_short").trim();
             if ("5.6 SP2".equals(prodVersionTextShort)) {
                 return new XenServer56SP2Resource();
@@ -607,7 +628,12 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L
         } else if (prodBrand.equals("XenServer") && prodVersion.equals("6.1.0")) {
             resource = XenServer610Resource.class.getName();
         } else if (prodBrand.equals("XenServer") && prodVersion.equals("6.2.0")) {
-            resource = XenServer620Resource.class.getName();
+            String hotfix = details.get("Xenserer620HotFix");
+            if (hotfix != null && hotfix.equalsIgnoreCase("Xenserver-Vdi-Copy-HotFix")) {
+                resource = Xenserver625Resource.class.getName();
+            } else {
+                resource = XenServer620Resource.class.getName();
+            }
         } else if (prodBrand.equals("XenServer") && prodVersion.equals("5.6.100")) {
             String prodVersionTextShort = details.get("product_version_text_short").trim();
             if ("5.6 SP2".equals(prodVersionTextShort)) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8caf52c6/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
index f38bb3c..fdbeefd 100644
--- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
+++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
@@ -49,6 +49,9 @@ import javax.ejb.Local;
 import javax.naming.ConfigurationException;
 import javax.xml.parsers.DocumentBuilderFactory;
 
+import org.apache.cloudstack.storage.command.StorageSubSystemCommand;
+import org.apache.cloudstack.storage.to.TemplateObjectTO;
+import org.apache.cloudstack.storage.to.VolumeObjectTO;
 import org.apache.commons.codec.binary.Base64;
 import org.apache.log4j.Logger;
 import org.apache.xmlrpc.XmlRpcException;
@@ -102,8 +105,6 @@ import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.AttachIsoCommand;
 import com.cloud.agent.api.AttachVolumeAnswer;
 import com.cloud.agent.api.AttachVolumeCommand;
-import com.cloud.agent.api.BackupSnapshotAnswer;
-import com.cloud.agent.api.BackupSnapshotCommand;
 import com.cloud.agent.api.BumpUpPriorityCommand;
 import com.cloud.agent.api.CheckHealthAnswer;
 import com.cloud.agent.api.CheckHealthCommand;
@@ -121,13 +122,9 @@ import com.cloud.agent.api.CleanupNetworkRulesCmd;
 import com.cloud.agent.api.ClusterSyncAnswer;
 import com.cloud.agent.api.ClusterSyncCommand;
 import com.cloud.agent.api.Command;
-import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand;
-import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand;
 import com.cloud.agent.api.CreateStoragePoolCommand;
 import com.cloud.agent.api.CreateVMSnapshotAnswer;
 import com.cloud.agent.api.CreateVMSnapshotCommand;
-import com.cloud.agent.api.CreateVolumeFromSnapshotAnswer;
-import com.cloud.agent.api.CreateVolumeFromSnapshotCommand;
 import com.cloud.agent.api.DeleteStoragePoolCommand;
 import com.cloud.agent.api.DeleteVMSnapshotAnswer;
 import com.cloud.agent.api.DeleteVMSnapshotCommand;
@@ -147,8 +144,6 @@ import com.cloud.agent.api.HostStatsEntry;
 import com.cloud.agent.api.HostVmStateReportEntry;
 import com.cloud.agent.api.MaintainAnswer;
 import com.cloud.agent.api.MaintainCommand;
-import com.cloud.agent.api.ManageSnapshotAnswer;
-import com.cloud.agent.api.ManageSnapshotCommand;
 import com.cloud.agent.api.MigrateAnswer;
 import com.cloud.agent.api.MigrateCommand;
 import com.cloud.agent.api.ModifySshKeysCommand;
@@ -247,7 +242,6 @@ import com.cloud.agent.api.storage.CopyVolumeAnswer;
 import com.cloud.agent.api.storage.CopyVolumeCommand;
 import com.cloud.agent.api.storage.CreateAnswer;
 import com.cloud.agent.api.storage.CreateCommand;
-import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer;
 import com.cloud.agent.api.storage.DestroyCommand;
 import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer;
 import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
@@ -262,10 +256,8 @@ import com.cloud.agent.api.to.IpAddressTO;
 import com.cloud.agent.api.to.NfsTO;
 import com.cloud.agent.api.to.NicTO;
 import com.cloud.agent.api.to.PortForwardingRuleTO;
-import com.cloud.agent.api.to.S3TO;
 import com.cloud.agent.api.to.StaticNatRuleTO;
 import com.cloud.agent.api.to.StorageFilerTO;
-import com.cloud.agent.api.to.SwiftTO;
 import com.cloud.agent.api.to.VirtualMachineTO;
 import com.cloud.agent.api.to.VolumeTO;
 import com.cloud.exception.InternalErrorException;
@@ -282,7 +274,6 @@ import com.cloud.network.rules.FirewallRule;
 import com.cloud.resource.ServerResource;
 import com.cloud.resource.hypervisor.HypervisorResource;
 import com.cloud.storage.Storage;
-import com.cloud.storage.Storage.ImageFormat;
 import com.cloud.storage.Storage.StoragePoolType;
 import com.cloud.storage.Volume;
 import com.cloud.storage.VolumeVO;
@@ -303,6 +294,41 @@ import com.cloud.vm.VirtualMachine;
 import com.cloud.vm.VirtualMachine.PowerState;
 import com.cloud.vm.VirtualMachine.State;
 import com.cloud.vm.snapshot.VMSnapshot;
+import com.google.gson.Gson;
+import com.trilead.ssh2.SCPClient;
+import com.xensource.xenapi.Bond;
+import com.xensource.xenapi.Connection;
+import com.xensource.xenapi.Console;
+import com.xensource.xenapi.Host;
+import com.xensource.xenapi.HostCpu;
+import com.xensource.xenapi.HostMetrics;
+import com.xensource.xenapi.Network;
+import com.xensource.xenapi.PBD;
+import com.xensource.xenapi.PIF;
+import com.xensource.xenapi.PIF.Record;
+import com.xensource.xenapi.Pool;
+import com.xensource.xenapi.SR;
+import com.xensource.xenapi.Session;
+import com.xensource.xenapi.Task;
+import com.xensource.xenapi.Types;
+import com.xensource.xenapi.Types.BadAsyncResult;
+import com.xensource.xenapi.Types.BadServerResponse;
+import com.xensource.xenapi.Types.ConsoleProtocol;
+import com.xensource.xenapi.Types.IpConfigurationMode;
+import com.xensource.xenapi.Types.OperationNotAllowed;
+import com.xensource.xenapi.Types.SrFull;
+import com.xensource.xenapi.Types.VbdType;
+import com.xensource.xenapi.Types.VmBadPowerState;
+import com.xensource.xenapi.Types.VmPowerState;
+import com.xensource.xenapi.Types.XenAPIException;
+import com.xensource.xenapi.VBD;
+import com.xensource.xenapi.VBDMetrics;
+import com.xensource.xenapi.VDI;
+import com.xensource.xenapi.VIF;
+import com.xensource.xenapi.VLAN;
+import com.xensource.xenapi.VM;
+import com.xensource.xenapi.VMGuestMetrics;
+import com.xensource.xenapi.XenAPIObject;
 
 /**
  * CitrixResourceBase encapsulates the calls to the XenServer Xapi process
@@ -537,25 +563,13 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
         } else if (clazz == ModifyStoragePoolCommand.class) {
             return execute((ModifyStoragePoolCommand)cmd);
         } else if (clazz == DeleteStoragePoolCommand.class) {
-            return execute((DeleteStoragePoolCommand)cmd);
-        } else if (clazz == CopyVolumeCommand.class) {
-            return execute((CopyVolumeCommand)cmd);
-        } else if (clazz == ResizeVolumeCommand.class) {
-            return execute((ResizeVolumeCommand)cmd);
+            return execute((DeleteStoragePoolCommand) cmd);
+        }else if (clazz == ResizeVolumeCommand.class) {
+            return execute((ResizeVolumeCommand) cmd);
         } else if (clazz == AttachVolumeCommand.class) {
             return execute((AttachVolumeCommand)cmd);
         } else if (clazz == AttachIsoCommand.class) {
-            return execute((AttachIsoCommand)cmd);
-        } else if (clazz == ManageSnapshotCommand.class) {
-            return execute((ManageSnapshotCommand)cmd);
-        } else if (clazz == BackupSnapshotCommand.class) {
-            return execute((BackupSnapshotCommand)cmd);
-        } else if (clazz == CreateVolumeFromSnapshotCommand.class) {
-            return execute((CreateVolumeFromSnapshotCommand)cmd);
-        } else if (clazz == CreatePrivateTemplateFromVolumeCommand.class) {
-            return execute((CreatePrivateTemplateFromVolumeCommand)cmd);
-        } else if (clazz == CreatePrivateTemplateFromSnapshotCommand.class) {
-            return execute((CreatePrivateTemplateFromSnapshotCommand)cmd);
+            return execute((AttachIsoCommand) cmd);
         } else if (clazz == UpgradeSnapshotCommand.class) {
             return execute((UpgradeSnapshotCommand)cmd);
         } else if (clazz == GetStorageStatsCommand.class) {
@@ -1482,6 +1496,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
         return vm;
     }
 
+
     protected void finalizeVmMetaData(VM vm, Connection conn, VirtualMachineTO vmSpec) throws Exception {
 
         Map<String, String> details = vmSpec.getDetails();
@@ -3607,13 +3622,21 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
         throw new CloudRuntimeException("Com'on no control domain?  What the crap?!#@!##$@");
     }
 
+    protected void umountSnapshotDir(Connection conn, Long dcId) {
+        try {
+            callHostPlugin(conn, "vmopsSnapshot", "unmountSnapshotsDir", "dcId", dcId.toString());
+        } catch (Exception e) {
+            s_logger.debug("Failed to umount snapshot dir",e);
+        }
+    }
+
     protected ReadyAnswer execute(ReadyCommand cmd) {
         Connection conn = getConnection();
         Long dcId = cmd.getDataCenterId();
         // Ignore the result of the callHostPlugin. Even if unmounting the
         // snapshots dir fails, let Ready command
         // succeed.
-        callHostPlugin(conn, "vmopsSnapshot", "unmountSnapshotsDir", "dcId", dcId.toString());
+        umountSnapshotDir(conn, dcId);
 
         setupLinkLocalNetwork(conn);
         // try to destroy CD-ROM device for all system VMs on this host
@@ -4019,109 +4042,6 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
         }
     }
 
-    boolean swiftDownload(Connection conn, SwiftTO swift, String container, String rfilename, String dir, String lfilename, Boolean remote) {
-        String result = null;
-        try {
-            result =
-                callHostPluginAsync(conn, "swiftxen", "swift", 60 * 60, "op", "download", "url", swift.getUrl(), "account", swift.getAccount(), "username",
-                    swift.getUserName(), "key", swift.getKey(), "rfilename", rfilename, "dir", dir, "lfilename", lfilename, "remote", remote.toString());
-            if (result != null && result.equals("true")) {
-                return true;
-            }
-        } catch (Exception e) {
-            s_logger.warn("swift download failed due to ", e);
-        }
-        return false;
-    }
-
-    boolean swiftUpload(Connection conn, SwiftTO swift, String container, String ldir, String lfilename, Boolean isISCSI, int wait) {
-        String result = null;
-        try {
-            result =
-                callHostPluginAsync(conn, "swiftxen", "swift", wait, "op", "upload", "url", swift.getUrl(), "account", swift.getAccount(), "username",
-                    swift.getUserName(), "key", swift.getKey(), "container", container, "ldir", ldir, "lfilename", lfilename, "isISCSI", isISCSI.toString());
-            if (result != null && result.equals("true")) {
-                return true;
-            }
-        } catch (Exception e) {
-            s_logger.warn("swift upload failed due to " + e.toString(), e);
-        }
-        return false;
-    }
-
-    boolean swiftDelete(Connection conn, SwiftTO swift, String rfilename) {
-        String result = null;
-        try {
-            result =
-                callHostPlugin(conn, "swiftxen", "swift", "op", "delete", "url", swift.getUrl(), "account", swift.getAccount(), "username", swift.getUserName(), "key",
-                    swift.getKey(), "rfilename", rfilename);
-            if (result != null && result.equals("true")) {
-                return true;
-            }
-        } catch (Exception e) {
-            s_logger.warn("swift download failed due to ", e);
-        }
-        return false;
-    }
-
-    public String swiftBackupSnapshot(Connection conn, SwiftTO swift, String srUuid, String snapshotUuid, String container, Boolean isISCSI, int wait) {
-        String lfilename;
-        String ldir;
-        if (isISCSI) {
-            ldir = "/dev/VG_XenStorage-" + srUuid;
-            lfilename = "VHD-" + snapshotUuid;
-        } else {
-            ldir = "/var/run/sr-mount/" + srUuid;
-            lfilename = snapshotUuid + ".vhd";
-        }
-        swiftUpload(conn, swift, container, ldir, lfilename, isISCSI, wait);
-        return lfilename;
-    }
-
-    protected String backupSnapshot(Connection conn, String primaryStorageSRUuid, Long dcId, Long accountId, Long volumeId, String secondaryStorageMountPath,
-        String snapshotUuid, String prevBackupUuid, Boolean isISCSI, int wait, Long secHostId) {
-        String backupSnapshotUuid = null;
-
-        if (prevBackupUuid == null) {
-            prevBackupUuid = "";
-        }
-
-        // Each argument is put in a separate line for readability.
-        // Using more lines does not harm the environment.
-        String backupUuid = UUID.randomUUID().toString();
-        String results =
-            callHostPluginAsync(conn, "vmopsSnapshot", "backupSnapshot", wait, "primaryStorageSRUuid", primaryStorageSRUuid, "dcId", dcId.toString(), "accountId",
-                accountId.toString(), "volumeId", volumeId.toString(), "secondaryStorageMountPath", secondaryStorageMountPath, "snapshotUuid", snapshotUuid,
-                "prevBackupUuid", prevBackupUuid, "backupUuid", backupUuid, "isISCSI", isISCSI.toString(), "secHostId", secHostId.toString());
-        String errMsg = null;
-        if (results == null || results.isEmpty()) {
-            errMsg =
-                "Could not copy backupUuid: " + backupSnapshotUuid + " of volumeId: " + volumeId + " from primary storage " + primaryStorageSRUuid +
-                    " to secondary storage " + secondaryStorageMountPath + " due to null";
-        } else {
-
-            String[] tmp = results.split("#");
-            String status = tmp[0];
-            backupSnapshotUuid = tmp[1];
-            // status == "1" if and only if backupSnapshotUuid != null
-            // So we don't rely on status value but return backupSnapshotUuid as an
-            // indicator of success.
-            if (status != null && status.equalsIgnoreCase("1") && backupSnapshotUuid != null) {
-                s_logger.debug("Successfully copied backupUuid: " + backupSnapshotUuid + " of volumeId: " + volumeId + " to secondary storage");
-                return backupSnapshotUuid;
-            } else {
-                errMsg =
-                    "Could not copy backupUuid: " + backupSnapshotUuid + " of volumeId: " + volumeId + " from primary storage " + primaryStorageSRUuid +
-                        " to secondary storage " + secondaryStorageMountPath + " due to " + tmp[1];
-            }
-        }
-        String source = backupUuid + ".vhd";
-        killCopyProcess(conn, source);
-        s_logger.warn(errMsg);
-        return null;
-
-    }
-
     protected String callHostPluginAsync(Connection conn, String plugin, String cmd, int wait, String... params) {
         int timeout = wait * 1000;
         Map<String, String> args = new HashMap<String, String>();
@@ -6273,14 +6193,6 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
         }
     }
 
-    void destroyVDI(Connection conn, VDI vdi) {
-        try {
-            vdi.destroy(conn);
-        } catch (Exception e) {
-            String msg = "destroy VDI failed due to " + e.toString();
-            s_logger.warn(msg);
-        }
-    }
 
     public CreateAnswer execute(CreateCommand cmd) {
         Connection conn = getConnection();
@@ -6707,54 +6619,6 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
         return new Answer(cmd, true, "Success");
     }
 
-    public CopyVolumeAnswer execute(final CopyVolumeCommand cmd) {
-        Connection conn = getConnection();
-        String volumeUUID = cmd.getVolumePath();
-        StorageFilerTO poolTO = cmd.getPool();
-        String secondaryStorageURL = cmd.getSecondaryStorageURL();
-        boolean toSecondaryStorage = cmd.toSecondaryStorage();
-        int wait = cmd.getWait();
-        try {
-            URI uri = new URI(secondaryStorageURL);
-            String remoteVolumesMountPath = uri.getHost() + ":" + uri.getPath() + "/volumes/";
-            String volumeFolder = String.valueOf(cmd.getVolumeId()) + "/";
-            String mountpoint = remoteVolumesMountPath + volumeFolder;
-            SR primaryStoragePool = getStorageRepository(conn, poolTO.getUuid());
-            String srUuid = primaryStoragePool.getUuid(conn);
-            if (toSecondaryStorage) {
-                // Create the volume folder
-                if (!createSecondaryStorageFolder(conn, remoteVolumesMountPath, volumeFolder)) {
-                    throw new InternalErrorException("Failed to create the volume folder.");
-                }
-                SR secondaryStorage = null;
-                try {
-                    // Create a SR for the volume UUID folder
-                    secondaryStorage = createNfsSRbyURI(conn, new URI(secondaryStorageURL + "/volumes/" + volumeFolder), false);
-                    // Look up the volume on the source primary storage pool
-                    VDI srcVolume = getVDIbyUuid(conn, volumeUUID);
-                    // Copy the volume to secondary storage
-                    VDI destVolume = cloudVDIcopy(conn, srcVolume, secondaryStorage, wait);
-                    String destVolumeUUID = destVolume.getUuid(conn);
-                    return new CopyVolumeAnswer(cmd, true, null, null, destVolumeUUID);
-                } finally {
-                    removeSR(conn, secondaryStorage);
-                }
-            } else {
-                try {
-                    String volumePath = mountpoint + "/" + volumeUUID + ".vhd";
-                    String uuid = copy_vhd_from_secondarystorage(conn, volumePath, srUuid, wait);
-                    return new CopyVolumeAnswer(cmd, true, null, srUuid, uuid);
-                } finally {
-                    deleteSecondaryStorageFolder(conn, remoteVolumesMountPath, volumeFolder);
-                }
-            }
-        } catch (Exception e) {
-            String msg = "Catch Exception " + e.getClass().getName() + " due to " + e.toString();
-            s_logger.warn(msg, e);
-            return new CopyVolumeAnswer(cmd, false, msg, null, null);
-        }
-    }
-
     protected VDI createVdi(SR sr, String vdiNameLabel, Long volumeSize) throws Types.XenAPIException, XmlRpcException {
         VDI vdi = null;
 
@@ -7276,140 +7140,6 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
         return SRType.LVMOHBA.equals(type) || SRType.LVMOISCSI.equals(type) || SRType.LVM.equals(type);
     }
 
-    protected ManageSnapshotAnswer execute(final ManageSnapshotCommand cmd) {
-        Connection conn = getConnection();
-        long snapshotId = cmd.getSnapshotId();
-        String snapshotName = cmd.getSnapshotName();
-
-        // By default assume failure
-        boolean success = false;
-        String cmdSwitch = cmd.getCommandSwitch();
-        String snapshotOp = "Unsupported snapshot command." + cmdSwitch;
-        if (cmdSwitch.equals(ManageSnapshotCommand.CREATE_SNAPSHOT)) {
-            snapshotOp = "create";
-        } else if (cmdSwitch.equals(ManageSnapshotCommand.DESTROY_SNAPSHOT)) {
-            snapshotOp = "destroy";
-        }
-        String details = "ManageSnapshotCommand operation: " + snapshotOp + " Failed for snapshotId: " + snapshotId;
-        String snapshotUUID = null;
-
-        try {
-            if (cmdSwitch.equals(ManageSnapshotCommand.CREATE_SNAPSHOT)) {
-                // Look up the volume
-                String volumeUUID = cmd.getVolumePath();
-                VDI volume = VDI.getByUuid(conn, volumeUUID);
-
-                // Create a snapshot
-                VDI snapshot = volume.snapshot(conn, new HashMap<String, String>());
-
-                if (snapshotName != null) {
-                    snapshot.setNameLabel(conn, snapshotName);
-                }
-                // Determine the UUID of the snapshot
-
-                snapshotUUID = snapshot.getUuid(conn);
-                String preSnapshotUUID = cmd.getSnapshotPath();
-                //check if it is a empty snapshot
-                if (preSnapshotUUID != null) {
-                    SR sr = volume.getSR(conn);
-                    String srUUID = sr.getUuid(conn);
-                    String type = sr.getType(conn);
-                    Boolean isISCSI = IsISCSI(type);
-                    String snapshotParentUUID = getVhdParent(conn, srUUID, snapshotUUID, isISCSI);
-
-                    String preSnapshotParentUUID = getVhdParent(conn, srUUID, preSnapshotUUID, isISCSI);
-                    if (snapshotParentUUID != null && snapshotParentUUID.equals(preSnapshotParentUUID)) {
-                        // this is empty snapshot, remove it
-                        snapshot.destroy(conn);
-                        snapshotUUID = preSnapshotUUID;
-                    }
-
-                }
-                success = true;
-                details = null;
-            } else if (cmd.getCommandSwitch().equals(ManageSnapshotCommand.DESTROY_SNAPSHOT)) {
-                // Look up the snapshot
-                snapshotUUID = cmd.getSnapshotPath();
-                VDI snapshot = getVDIbyUuid(conn, snapshotUUID);
-
-                snapshot.destroy(conn);
-                snapshotUUID = null;
-                success = true;
-                details = null;
-            }
-        } catch (XenAPIException e) {
-            details += ", reason: " + e.toString();
-            s_logger.warn(details, e);
-        } catch (Exception e) {
-            details += ", reason: " + e.toString();
-            s_logger.warn(details, e);
-        }
-        return new ManageSnapshotAnswer(cmd, snapshotId, snapshotUUID, success, details);
-    }
-
-    protected CreatePrivateTemplateAnswer execute(final CreatePrivateTemplateFromVolumeCommand cmd) {
-        Connection conn = getConnection();
-        String secondaryStoragePoolURL = cmd.getSecondaryStorageUrl();
-        String volumeUUID = cmd.getVolumePath();
-        Long accountId = cmd.getAccountId();
-        String userSpecifiedName = cmd.getTemplateName();
-        Long templateId = cmd.getTemplateId();
-        int wait = cmd.getWait();
-        String details = null;
-        SR tmpltSR = null;
-        boolean result = false;
-        String secondaryStorageMountPath = null;
-        String installPath = null;
-        try {
-            URI uri = new URI(secondaryStoragePoolURL);
-            secondaryStorageMountPath = uri.getHost() + ":" + uri.getPath();
-            installPath = "template/tmpl/" + accountId + "/" + templateId;
-            if (!createSecondaryStorageFolder(conn, secondaryStorageMountPath, installPath)) {
-                details = " Filed to create folder " + installPath + " in secondary storage";
-                s_logger.warn(details);
-                return new CreatePrivateTemplateAnswer(cmd, false, details);
-            }
-
-            VDI volume = getVDIbyUuid(conn, volumeUUID);
-            // create template SR
-            URI tmpltURI = new URI(secondaryStoragePoolURL + "/" + installPath);
-            tmpltSR = createNfsSRbyURI(conn, tmpltURI, false);
-
-            // copy volume to template SR
-            VDI tmpltVDI = cloudVDIcopy(conn, volume, tmpltSR, wait);
-            // scan makes XenServer pick up VDI physicalSize
-            tmpltSR.scan(conn);
-            if (userSpecifiedName != null) {
-                tmpltVDI.setNameLabel(conn, userSpecifiedName);
-            }
-
-            String tmpltUUID = tmpltVDI.getUuid(conn);
-            String tmpltFilename = tmpltUUID + ".vhd";
-            long virtualSize = tmpltVDI.getVirtualSize(conn);
-            long physicalSize = tmpltVDI.getPhysicalUtilisation(conn);
-            // create the template.properties file
-            String templatePath = secondaryStorageMountPath + "/" + installPath;
-            result = postCreatePrivateTemplate(conn, templatePath, tmpltFilename, tmpltUUID, userSpecifiedName, null, physicalSize, virtualSize, templateId);
-            if (!result) {
-                throw new CloudRuntimeException("Could not create the template.properties file on secondary storage dir: " + tmpltURI);
-            }
-            installPath = installPath + "/" + tmpltFilename;
-            removeSR(conn, tmpltSR);
-            tmpltSR = null;
-            return new CreatePrivateTemplateAnswer(cmd, true, null, installPath, virtualSize, physicalSize, tmpltUUID, ImageFormat.VHD);
-        } catch (Exception e) {
-            if (tmpltSR != null) {
-                removeSR(conn, tmpltSR);
-            }
-            if (secondaryStorageMountPath != null) {
-                deleteSecondaryStorageFolder(conn, secondaryStorageMountPath, installPath);
-            }
-            details = "Creating template from volume " + volumeUUID + " failed due to " + e.toString();
-            s_logger.error(details, e);
-        }
-        return new CreatePrivateTemplateAnswer(cmd, result, details);
-    }
-
     protected Answer execute(final UpgradeSnapshotCommand cmd) {
 
         String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
@@ -7439,60 +7169,6 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
         return new Answer(cmd, false, "failure");
     }
 
-    protected CreatePrivateTemplateAnswer execute(final CreatePrivateTemplateFromSnapshotCommand cmd) {
-        Connection conn = getConnection();
-        Long accountId = cmd.getAccountId();
-        Long volumeId = cmd.getVolumeId();
-        String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
-        String backedUpSnapshotUuid = cmd.getSnapshotUuid();
-        Long newTemplateId = cmd.getNewTemplateId();
-        String userSpecifiedName = cmd.getTemplateName();
-        int wait = cmd.getWait();
-        // By default, assume failure
-        String details = null;
-        boolean result = false;
-        String secondaryStorageMountPath = null;
-        String installPath = null;
-        try {
-            URI uri = new URI(secondaryStorageUrl);
-            secondaryStorageMountPath = uri.getHost() + ":" + uri.getPath();
-            installPath = "template/tmpl/" + accountId + "/" + newTemplateId;
-            if (!createSecondaryStorageFolder(conn, secondaryStorageMountPath, installPath)) {
-                details = " Filed to create folder " + installPath + " in secondary storage";
-                s_logger.warn(details);
-                return new CreatePrivateTemplateAnswer(cmd, false, details);
-            }
-            String templatePath = secondaryStorageMountPath + "/" + installPath;
-            // create snapshot SR
-            String filename = backedUpSnapshotUuid;
-            if (!filename.startsWith("VHD-") && !filename.endsWith(".vhd")) {
-                filename = backedUpSnapshotUuid + ".vhd";
-            }
-            String snapshotPath = secondaryStorageMountPath + "/snapshots/" + accountId + "/" + volumeId + "/" + filename;
-            String results = createTemplateFromSnapshot(conn, templatePath, snapshotPath, wait);
-            String[] tmp = results.split("#");
-            String tmpltUuid = tmp[1];
-            long physicalSize = Long.parseLong(tmp[2]);
-            long virtualSize = Long.parseLong(tmp[3]) * 1024 * 1024;
-            String tmpltFilename = tmpltUuid + ".vhd";
-
-            // create the template.properties file
-            result = postCreatePrivateTemplate(conn, templatePath, tmpltFilename, tmpltUuid, userSpecifiedName, null, physicalSize, virtualSize, newTemplateId);
-            if (!result) {
-                throw new CloudRuntimeException("Could not create the template.properties file on secondary storage dir: " + templatePath);
-            }
-            installPath = installPath + "/" + tmpltFilename;
-            return new CreatePrivateTemplateAnswer(cmd, true, null, installPath, virtualSize, physicalSize, tmpltUuid, ImageFormat.VHD);
-        } catch (Exception e) {
-            if (secondaryStorageMountPath != null) {
-                deleteSecondaryStorageFolder(conn, secondaryStorageMountPath, installPath);
-            }
-            details = "Creating template from snapshot " + backedUpSnapshotUuid + " failed due to " + e.toString();
-            s_logger.error(details, e);
-        }
-        return new CreatePrivateTemplateAnswer(cmd, result, details);
-    }
-
     private boolean destroySnapshotOnPrimaryStorageExceptThis(Connection conn, String volumeUuid, String avoidSnapshotUuid) {
         try {
             VDI volume = getVDIbyUuid(conn, volumeUuid);
@@ -7523,203 +7199,6 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
         return false;
     }
 
-    protected BackupSnapshotAnswer execute(final BackupSnapshotCommand cmd) {
-        Connection conn = getConnection();
-        String primaryStorageNameLabel = cmd.getPrimaryStoragePoolNameLabel();
-        Long dcId = cmd.getDataCenterId();
-        Long accountId = cmd.getAccountId();
-        Long volumeId = cmd.getVolumeId();
-        String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
-        String snapshotUuid = cmd.getSnapshotUuid(); // not null: Precondition.
-        String prevBackupUuid = cmd.getPrevBackupUuid();
-        String prevSnapshotUuid = cmd.getPrevSnapshotUuid();
-        int wait = cmd.getWait();
-        Long secHostId = cmd.getSecHostId();
-        // By default assume failure
-        String details = null;
-        boolean success = false;
-        String snapshotBackupUuid = null;
-        boolean fullbackup = true;
-        try {
-            SR primaryStorageSR = getSRByNameLabelandHost(conn, primaryStorageNameLabel);
-            if (primaryStorageSR == null) {
-                throw new InternalErrorException("Could not backup snapshot because the primary Storage SR could not be created from the name label: " +
-                    primaryStorageNameLabel);
-            }
-            String psUuid = primaryStorageSR.getUuid(conn);
-            Boolean isISCSI = IsISCSI(primaryStorageSR.getType(conn));
-            URI uri = new URI(secondaryStorageUrl);
-            String secondaryStorageMountPath = uri.getHost() + ":" + uri.getPath();
-            VDI snapshotVdi = getVDIbyUuid(conn, snapshotUuid);
-            String snapshotPaUuid = null;
-            if (prevBackupUuid != null) {
-                try {
-                    snapshotPaUuid = getVhdParent(conn, psUuid, snapshotUuid, isISCSI);
-                    if (snapshotPaUuid != null) {
-                        String snashotPaPaPaUuid = getVhdParent(conn, psUuid, snapshotPaUuid, isISCSI);
-                        String prevSnashotPaUuid = getVhdParent(conn, psUuid, prevSnapshotUuid, isISCSI);
-                        if (snashotPaPaPaUuid != null && prevSnashotPaUuid != null && prevSnashotPaUuid.equals(snashotPaPaPaUuid)) {
-                            fullbackup = false;
-                        }
-                    }
-                } catch (Exception e) {
-                }
-            }
-
-            if (fullbackup) {
-                // the first snapshot is always a full snapshot
-                String folder = "snapshots/" + accountId + "/" + volumeId;
-                if (!createSecondaryStorageFolder(conn, secondaryStorageMountPath, folder)) {
-                    details = " Filed to create folder " + folder + " in secondary storage";
-                    s_logger.warn(details);
-                    return new BackupSnapshotAnswer(cmd, false, details, null, false);
-                }
-                String snapshotMountpoint = secondaryStorageUrl + "/" + folder;
-                SR snapshotSr = null;
-                try {
-                    snapshotSr = createNfsSRbyURI(conn, new URI(snapshotMountpoint), false);
-                    VDI backedVdi = cloudVDIcopy(conn, snapshotVdi, snapshotSr, wait);
-                    snapshotBackupUuid = backedVdi.getUuid(conn);
-                    if (cmd.getSwift() != null) {
-                        try {
-                            swiftBackupSnapshot(conn, cmd.getSwift(), snapshotSr.getUuid(conn), snapshotBackupUuid, "S-" + volumeId.toString(), false, wait);
-                            snapshotBackupUuid = snapshotBackupUuid + ".vhd";
-                        } finally {
-                            deleteSnapshotBackup(conn, dcId, accountId, volumeId, secondaryStorageMountPath, snapshotBackupUuid);
-                        }
-                    } else if (cmd.getS3() != null) {
-                        try {
-                            backupSnapshotToS3(conn, cmd.getS3(), snapshotSr.getUuid(conn), snapshotBackupUuid, isISCSI, wait);
-                            snapshotBackupUuid = snapshotBackupUuid + ".vhd";
-                        } finally {
-                            deleteSnapshotBackup(conn, dcId, accountId, volumeId, secondaryStorageMountPath, snapshotBackupUuid);
-                        }
-                    }
-                    success = true;
-                } finally {
-                    if (snapshotSr != null) {
-                        removeSR(conn, snapshotSr);
-                    }
-                }
-            } else {
-                String primaryStorageSRUuid = primaryStorageSR.getUuid(conn);
-                if (cmd.getSwift() != null) {
-                    swiftBackupSnapshot(conn, cmd.getSwift(), primaryStorageSRUuid, snapshotPaUuid, "S-" + volumeId.toString(), isISCSI, wait);
-                    if (isISCSI) {
-                        snapshotBackupUuid = "VHD-" + snapshotPaUuid;
-                    } else {
-                        snapshotBackupUuid = snapshotPaUuid + ".vhd";
-                    }
-                    success = true;
-                } else if (cmd.getS3() != null) {
-                    backupSnapshotToS3(conn, cmd.getS3(), primaryStorageSRUuid, snapshotPaUuid, isISCSI, wait);
-                } else {
-                    snapshotBackupUuid =
-                        backupSnapshot(conn, primaryStorageSRUuid, dcId, accountId, volumeId, secondaryStorageMountPath, snapshotUuid, prevBackupUuid, isISCSI, wait,
-                            secHostId);
-                    success = (snapshotBackupUuid != null);
-                }
-            }
-            String volumeUuid = cmd.getVolumePath();
-            destroySnapshotOnPrimaryStorageExceptThis(conn, volumeUuid, snapshotUuid);
-            if (success) {
-                details = "Successfully backedUp the snapshotUuid: " + snapshotUuid + " to secondary storage.";
-
-            }
-        } catch (XenAPIException e) {
-            details = "BackupSnapshot Failed due to " + e.toString();
-            s_logger.warn(details, e);
-        } catch (Exception e) {
-            details = "BackupSnapshot Failed due to " + e.getMessage();
-            s_logger.warn(details, e);
-        }
-
-        return new BackupSnapshotAnswer(cmd, success, details, snapshotBackupUuid, fullbackup);
-    }
-
-    private boolean
-        backupSnapshotToS3(final Connection connection, final S3TO s3, final String srUuid, final String snapshotUuid, final Boolean iSCSIFlag, final int wait) {
-
-        final String filename = iSCSIFlag ? "VHD-" + snapshotUuid : snapshotUuid + ".vhd";
-        final String dir = (iSCSIFlag ? "/dev/VG_XenStorage-" : "/var/run/sr-mount/") + srUuid;
-        final String key = String.format("/snapshots/%1$s", snapshotUuid);
-
-        try {
-
-            final List<String> parameters = newArrayList(flattenProperties(s3, S3Utils.ClientOptions.class));
-            // https workaround for Introspector bug that does not
-            // recognize Boolean accessor methods ...
-            parameters.addAll(Arrays.asList("operation", "put", "filename", dir + "/" + filename, "iSCSIFlag", iSCSIFlag.toString(), "bucket", s3.getBucketName(), "key",
-                key, "https", s3.isHttps() != null ? s3.isHttps().toString() : "null"));
-            final String result = callHostPluginAsync(connection, "s3xen", "s3", wait, parameters.toArray(new String[parameters.size()]));
-
-            if (result != null && result.equals("true")) {
-                return true;
-            }
-
-        } catch (Exception e) {
-            s_logger.error(String.format("S3 upload failed of snapshot %1$s due to %2$s.", snapshotUuid, e.toString()), e);
-        }
-
-        return false;
-
-    }
-
-    protected CreateVolumeFromSnapshotAnswer execute(final CreateVolumeFromSnapshotCommand cmd) {
-        Connection conn = getConnection();
-        String primaryStorageNameLabel = cmd.getPrimaryStoragePoolNameLabel();
-        Long accountId = cmd.getAccountId();
-        Long volumeId = cmd.getVolumeId();
-        String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
-        String backedUpSnapshotUuid = cmd.getSnapshotUuid();
-        int wait = cmd.getWait();
-        boolean result = false;
-        // Generic error message.
-        String details = null;
-        String volumeUUID = null;
-        SR snapshotSR = null;
-
-        if (secondaryStorageUrl == null) {
-            details += " because the URL passed: " + secondaryStorageUrl + " is invalid.";
-            return new CreateVolumeFromSnapshotAnswer(cmd, result, details, volumeUUID);
-        }
-        try {
-            SR primaryStorageSR = getSRByNameLabelandHost(conn, primaryStorageNameLabel);
-            if (primaryStorageSR == null) {
-                throw new InternalErrorException("Could not create volume from snapshot because the primary Storage SR could not be created from the name label: " +
-                    primaryStorageNameLabel);
-            }
-            // Get the absolute path of the snapshot on the secondary storage.
-            URI snapshotURI = new URI(secondaryStorageUrl + "/snapshots/" + accountId + "/" + volumeId);
-            String filename = backedUpSnapshotUuid;
-            if (!filename.startsWith("VHD-") && !filename.endsWith(".vhd")) {
-                filename = backedUpSnapshotUuid + ".vhd";
-            }
-            String snapshotPath = snapshotURI.getHost() + ":" + snapshotURI.getPath() + "/" + filename;
-            String srUuid = primaryStorageSR.getUuid(conn);
-            volumeUUID = copy_vhd_from_secondarystorage(conn, snapshotPath, srUuid, wait);
-            result = true;
-        } catch (XenAPIException e) {
-            details += " due to " + e.toString();
-            s_logger.warn(details, e);
-        } catch (Exception e) {
-            details += " due to " + e.getMessage();
-            s_logger.warn(details, e);
-        } finally {
-            // In all cases, if the temporary SR was created, forget it.
-            if (snapshotSR != null) {
-                removeSR(conn, snapshotSR);
-            }
-        }
-        if (!result) {
-            // Is this logged at a higher level?
-            s_logger.error(details);
-        }
-
-        // In all cases return something.
-        return new CreateVolumeFromSnapshotAnswer(cmd, result, details, volumeUUID);
-    }
-
     protected VM getVM(Connection conn, String vmName) {
         // Look up VMs with the specified name
         Set<VM> vms;
@@ -7919,27 +7398,6 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
         return parentUuid;
     }
 
-    protected boolean destroySnapshotOnPrimaryStorage(Connection conn, String snapshotUuid) {
-        // Precondition snapshotUuid != null
-        try {
-            VDI snapshot = getVDIbyUuid(conn, snapshotUuid);
-            if (snapshot == null) {
-                throw new InternalErrorException("Could not destroy snapshot " + snapshotUuid + " because the snapshot VDI was null");
-            }
-            snapshot.destroy(conn);
-            s_logger.debug("Successfully destroyed snapshotUuid: " + snapshotUuid + " on primary storage");
-            return true;
-        } catch (XenAPIException e) {
-            String msg = "Destroy snapshotUuid: " + snapshotUuid + " on primary storage failed due to " + e.toString();
-            s_logger.error(msg, e);
-        } catch (Exception e) {
-            String msg = "Destroy snapshotUuid: " + snapshotUuid + " on primary storage failed due to " + e.getMessage();
-            s_logger.warn(msg, e);
-        }
-
-        return false;
-    }
-
     protected String deleteSnapshotBackup(Connection conn, Long dcId, Long accountId, Long volumeId, String secondaryStorageMountPath, String backupUUID) {
 
         // If anybody modifies the formatting below again, I'll skin them
@@ -7950,10 +7408,6 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
         return result;
     }
 
-    protected boolean deleteSnapshotsDir(Connection conn, Long dcId, Long accountId, Long volumeId, String secondaryStorageMountPath) {
-        return deleteSecondaryStorageFolder(conn, secondaryStorageMountPath, "snapshots" + "/" + accountId.toString() + "/" + volumeId.toString());
-    }
-
     @Override
     public boolean start() {
         return true;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8caf52c6/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerPoolVms.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerPoolVms.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerPoolVms.java
index d685c3f..767d77e 100644
--- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerPoolVms.java
+++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerPoolVms.java
@@ -51,6 +51,11 @@ public class XenServerPoolVms {
         return pv == null ? State.Stopped : pv.second(); // if a VM is absent on the cluster, it is effectively in stopped state.
     }
 
+    public Ternary<String, State, String> get(String clusterId, String name) {
+        HashMap<String, Ternary<String, State, String>> vms = getClusterVmState(clusterId);
+        return vms.get(name);
+    }
+
     public void put(String clusterId, String hostUuid, String name, State state, String platform) {
         HashMap<String, Ternary<String, State, String>> vms = getClusterVmState(clusterId);
         vms.put(name, new Ternary<String, State, String>(hostUuid, state, platform));

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8caf52c6/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java
index 9171152..0d5eec8 100644
--- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java
+++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java
@@ -90,7 +90,7 @@ import com.cloud.utils.storage.encoding.Decoder;
 public class XenServerStorageProcessor implements StorageProcessor {
     private static final Logger s_logger = Logger.getLogger(XenServerStorageProcessor.class);
     protected CitrixResourceBase hypervisorResource;
-    private String BaseMountPointOnHost = "/var/run/cloud_mount";
+    protected String BaseMountPointOnHost = "/var/run/cloud_mount";
 
     public XenServerStorageProcessor(CitrixResourceBase resource) {
         hypervisorResource = resource;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8caf52c6/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/Xenserver625Resource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/Xenserver625Resource.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/Xenserver625Resource.java
new file mode 100644
index 0000000..7d2a2a1
--- /dev/null
+++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/Xenserver625Resource.java
@@ -0,0 +1,112 @@
+/*
+ * 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 com.cloud.hypervisor.xen.resource;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.ejb.Local;
+
+import org.apache.cloudstack.hypervisor.xenserver.XenServerResourceNewBase;
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.StartupRoutingCommand;
+import com.cloud.resource.ServerResource;
+import com.cloud.storage.resource.StorageSubsystemCommandHandler;
+import com.cloud.storage.resource.StorageSubsystemCommandHandlerBase;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.script.Script;
+import com.xensource.xenapi.Connection;
+
+@Local(value=ServerResource.class)
+public class Xenserver625Resource extends XenServerResourceNewBase {
+    private static final Logger s_logger = Logger.getLogger(XenServer620Resource.class);
+
+    public Xenserver625Resource() {
+        super();
+    }
+
+    @Override
+    protected void fillHostInfo(Connection conn, StartupRoutingCommand cmd) {
+        super.fillHostInfo(conn, cmd);
+        Map<String, String> details = cmd.getHostDetails();
+        details.put("Xenserer620HotFix", "Xenserver-Vdi-Copy-HotFix");
+    }
+
+    @Override
+    protected String getGuestOsType(String stdType, boolean bootFromCD) {
+        return CitrixHelper.getXenServer620GuestOsType(stdType, bootFromCD);
+    }
+
+    @Override
+    protected List<File> getPatchFiles() {
+        List<File> files = new ArrayList<File>();
+        String patch = "scripts/vm/hypervisor/xenserver/xenserver62/patch";
+        String patchfilePath = Script.findScript("", patch);
+        if (patchfilePath == null) {
+            throw new CloudRuntimeException("Unable to find patch file " + patch);
+        }
+        File file = new File(patchfilePath);
+        files.add(file);
+        return files;
+    }
+
+    @Override
+    public long getStaticMax(String os, boolean b, long dynamicMinRam, long dynamicMaxRam){
+        long recommendedValue = CitrixHelper.getXenServer620StaticMax(os, b);
+        if(recommendedValue == 0){
+            s_logger.warn("No recommended value found for dynamic max, setting static max and dynamic max equal");
+            return dynamicMaxRam;
+        }
+        long staticMax = Math.min(recommendedValue, 4l * dynamicMinRam);  // XS constraint for stability
+        if (dynamicMaxRam > staticMax){ // XS contraint that dynamic max <= static max
+            s_logger.warn("dynamixMax " + dynamicMaxRam + " cant be greater than static max " + staticMax + ", can lead to stability issues. Setting static max as much as dynamic max ");
+            return dynamicMaxRam;
+        }
+        return staticMax;
+    }
+
+    @Override
+    public long getStaticMin(String os, boolean b, long dynamicMinRam, long dynamicMaxRam){
+        long recommendedValue = CitrixHelper.getXenServer620StaticMin(os, b);
+        if(recommendedValue == 0){
+            s_logger.warn("No recommended value found for dynamic min");
+            return dynamicMinRam;
+        }
+
+        if(dynamicMinRam < recommendedValue){   // XS contraint that dynamic min > static min
+            s_logger.warn("Vm is set to dynamixMin " + dynamicMinRam + " less than the recommended static min " + recommendedValue + ", could lead to stability issues");
+        }
+        return dynamicMinRam;
+    }
+
+    @Override
+    protected StorageSubsystemCommandHandler getStorageHandler() {
+        XenServerStorageProcessor processor = new Xenserver625StorageProcessor(this);
+        return new StorageSubsystemCommandHandlerBase(processor);
+    }
+
+    @Override
+    protected void umountSnapshotDir(Connection conn, Long dcId) {
+
+    }
+
+}
\ No newline at end of file


[10/10] git commit: updated refs/heads/master to 62bb5d8

Posted by ed...@apache.org.
fix checkstyle


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

Branch: refs/heads/master
Commit: 62bb5d88483adddf585eac993e972b8d0c311cb9
Parents: 0824c78
Author: Edison Su <su...@gmail.com>
Authored: Thu Dec 19 15:05:58 2013 -0800
Committer: Edison Su <su...@gmail.com>
Committed: Thu Dec 19 15:05:58 2013 -0800

----------------------------------------------------------------------
 api/src/com/cloud/vm/VirtualMachineName.java    |  2 +-
 .../motion/AncientDataMotionStrategy.java       | 11 ++-
 .../src/com/cloud/hypervisor/XenServerGuru.java | 15 ++--
 .../xen/resource/CitrixResourceBase.java        | 74 +++-----------------
 .../xen/resource/XenServerStorageProcessor.java | 36 +++++-----
 .../xenserver/XenServerResourceNewBase.java     | 20 ------
 6 files changed, 48 insertions(+), 110 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/62bb5d88/api/src/com/cloud/vm/VirtualMachineName.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/vm/VirtualMachineName.java b/api/src/com/cloud/vm/VirtualMachineName.java
index d3b14c7..4bbcb64 100755
--- a/api/src/com/cloud/vm/VirtualMachineName.java
+++ b/api/src/com/cloud/vm/VirtualMachineName.java
@@ -38,7 +38,7 @@ public class VirtualMachineName {
 
         return true;
     }
-    
+
     public static String getVnetName(long vnetId) {
         StringBuilder vnet = new StringBuilder();
         Formatter formatter = new Formatter(vnet);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/62bb5d88/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 47467e5..315f279 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
@@ -23,10 +23,19 @@ import java.util.Map;
 
 import javax.inject.Inject;
 
-import org.apache.cloudstack.engine.subsystem.api.storage.*;
+import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope;
+import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionStrategy;
+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.DataStoreManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
+import org.apache.cloudstack.engine.subsystem.api.storage.HostScope;
 import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event;
 import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
 import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.StorageAction;
 import org.apache.cloudstack.engine.subsystem.api.storage.StorageCacheManager;
 import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority;
 import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/62bb5d88/plugins/hypervisors/xen/src/com/cloud/hypervisor/XenServerGuru.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/XenServerGuru.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/XenServerGuru.java
index 89a727b..fd9bfae 100644
--- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/XenServerGuru.java
+++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/XenServerGuru.java
@@ -19,8 +19,17 @@ package com.cloud.hypervisor;
 import javax.ejb.Local;
 import javax.inject.Inject;
 
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
+import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
+import org.apache.cloudstack.storage.command.CopyCommand;
+
 import com.cloud.agent.api.Command;
-import com.cloud.agent.api.to.*;
+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.NfsTO;
+import com.cloud.agent.api.to.VirtualMachineTO;
 import com.cloud.host.HostInfo;
 import com.cloud.host.HostVO;
 import com.cloud.host.dao.HostDao;
@@ -30,10 +39,6 @@ import com.cloud.storage.dao.GuestOSDao;
 import com.cloud.template.VirtualMachineTemplate.BootloaderType;
 import com.cloud.utils.Pair;
 import com.cloud.vm.VirtualMachineProfile;
-import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
-import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
-import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
-import org.apache.cloudstack.storage.command.CopyCommand;
 
 @Local(value = HypervisorGuru.class)
 public class XenServerGuru extends HypervisorGuruBase implements HypervisorGuru {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/62bb5d88/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
index fdbeefd..4309af3 100644
--- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
+++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
@@ -16,9 +16,6 @@
 // under the License.
 package com.cloud.hypervisor.xen.resource;
 
-import static com.cloud.utils.ReflectUtil.flattenProperties;
-import static com.google.common.collect.Lists.newArrayList;
-
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileInputStream;
@@ -31,7 +28,6 @@ import java.net.URISyntaxException;
 import java.net.URL;
 import java.net.URLConnection;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -60,46 +56,6 @@ import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
 import org.xml.sax.InputSource;
 
-import com.google.gson.Gson;
-import com.trilead.ssh2.SCPClient;
-import com.xensource.xenapi.Bond;
-import com.xensource.xenapi.Connection;
-import com.xensource.xenapi.Console;
-import com.xensource.xenapi.Host;
-import com.xensource.xenapi.HostCpu;
-import com.xensource.xenapi.HostMetrics;
-import com.xensource.xenapi.Network;
-import com.xensource.xenapi.PBD;
-import com.xensource.xenapi.PIF;
-import com.xensource.xenapi.PIF.Record;
-import com.xensource.xenapi.Pool;
-import com.xensource.xenapi.SR;
-import com.xensource.xenapi.Session;
-import com.xensource.xenapi.Task;
-import com.xensource.xenapi.Types;
-import com.xensource.xenapi.Types.BadAsyncResult;
-import com.xensource.xenapi.Types.BadServerResponse;
-import com.xensource.xenapi.Types.ConsoleProtocol;
-import com.xensource.xenapi.Types.IpConfigurationMode;
-import com.xensource.xenapi.Types.OperationNotAllowed;
-import com.xensource.xenapi.Types.SrFull;
-import com.xensource.xenapi.Types.VbdType;
-import com.xensource.xenapi.Types.VmBadPowerState;
-import com.xensource.xenapi.Types.VmPowerState;
-import com.xensource.xenapi.Types.XenAPIException;
-import com.xensource.xenapi.VBD;
-import com.xensource.xenapi.VBDMetrics;
-import com.xensource.xenapi.VDI;
-import com.xensource.xenapi.VIF;
-import com.xensource.xenapi.VLAN;
-import com.xensource.xenapi.VM;
-import com.xensource.xenapi.VMGuestMetrics;
-import com.xensource.xenapi.XenAPIObject;
-
-import org.apache.cloudstack.storage.command.StorageSubSystemCommand;
-import org.apache.cloudstack.storage.to.TemplateObjectTO;
-import org.apache.cloudstack.storage.to.VolumeObjectTO;
-
 import com.cloud.agent.IAgentControl;
 import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.AttachIsoCommand;
@@ -238,8 +194,6 @@ import com.cloud.agent.api.routing.SetStaticRouteCommand;
 import com.cloud.agent.api.routing.Site2SiteVpnCfgCommand;
 import com.cloud.agent.api.routing.VmDataCommand;
 import com.cloud.agent.api.routing.VpnUsersCfgCommand;
-import com.cloud.agent.api.storage.CopyVolumeAnswer;
-import com.cloud.agent.api.storage.CopyVolumeCommand;
 import com.cloud.agent.api.storage.CreateAnswer;
 import com.cloud.agent.api.storage.CreateCommand;
 import com.cloud.agent.api.storage.DestroyCommand;
@@ -283,7 +237,6 @@ import com.cloud.storage.template.TemplateProp;
 import com.cloud.template.VirtualMachineTemplate.BootloaderType;
 import com.cloud.utils.NumbersUtil;
 import com.cloud.utils.Pair;
-import com.cloud.utils.S3Utils;
 import com.cloud.utils.StringUtils;
 import com.cloud.utils.Ternary;
 import com.cloud.utils.exception.CloudRuntimeException;
@@ -305,20 +258,12 @@ import com.xensource.xenapi.HostMetrics;
 import com.xensource.xenapi.Network;
 import com.xensource.xenapi.PBD;
 import com.xensource.xenapi.PIF;
-import com.xensource.xenapi.PIF.Record;
 import com.xensource.xenapi.Pool;
 import com.xensource.xenapi.SR;
 import com.xensource.xenapi.Session;
 import com.xensource.xenapi.Task;
 import com.xensource.xenapi.Types;
-import com.xensource.xenapi.Types.BadAsyncResult;
 import com.xensource.xenapi.Types.BadServerResponse;
-import com.xensource.xenapi.Types.ConsoleProtocol;
-import com.xensource.xenapi.Types.IpConfigurationMode;
-import com.xensource.xenapi.Types.OperationNotAllowed;
-import com.xensource.xenapi.Types.SrFull;
-import com.xensource.xenapi.Types.VbdType;
-import com.xensource.xenapi.Types.VmBadPowerState;
 import com.xensource.xenapi.Types.VmPowerState;
 import com.xensource.xenapi.Types.XenAPIException;
 import com.xensource.xenapi.VBD;
@@ -330,6 +275,7 @@ import com.xensource.xenapi.VM;
 import com.xensource.xenapi.VMGuestMetrics;
 import com.xensource.xenapi.XenAPIObject;
 
+
 /**
  * CitrixResourceBase encapsulates the calls to the XenServer Xapi process
  * to perform the required functionalities for CloudStack.
@@ -3678,7 +3624,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
             Iterator<Console> i = consoles.iterator();
             while (i.hasNext()) {
                 c = i.next();
-                if (c.getProtocol(conn) == ConsoleProtocol.RFB)
+                if (c.getProtocol(conn) == Types.ConsoleProtocol.RFB)
                     return c.getLocation(conn);
             }
         } catch (XenAPIException e) {
@@ -5055,7 +5001,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
             return false;
         }
 
-        src.reconfigureIp(conn, IpConfigurationMode.NONE, null, null, null, null);
+        src.reconfigureIp(conn, Types.IpConfigurationMode.NONE, null, null, null, null);
         return true;
     }
 
@@ -5873,7 +5819,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
             XsLocalNetwork nw = getNetworkByName(conn, label);
             s_logger.debug("Network object:" + nw.getNetwork().getUuid(conn));
             PIF pif = nw.getPif(conn);
-            Record pifRec = pif.getRecord(conn);
+            PIF.Record pifRec = pif.getRecord(conn);
             s_logger.debug("PIF object:" + pifRec.uuid + "(" + pifRec.device + ")");
             return new OvsFetchInterfaceAnswer(cmd, true, "Interface " + pifRec.device + " retrieved successfully", pifRec.IP, pifRec.netmask, pifRec.MAC);
         } catch (BadServerResponse e) {
@@ -6921,9 +6867,9 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
             return new CreateVMSnapshotAnswer(cmd, cmd.getTarget(), cmd.getVolumeTOs());
         } catch (Exception e) {
             String msg = "";
-            if (e instanceof BadAsyncResult) {
+            if (e instanceof Types.BadAsyncResult) {
                 String licenseKeyWord = "LICENCE_RESTRICTION";
-                BadAsyncResult errorResult = (BadAsyncResult)e;
+                Types.BadAsyncResult errorResult = (Types.BadAsyncResult)e;
                 if (errorResult.shortDescription != null && errorResult.shortDescription.contains(licenseKeyWord)) {
                     msg = licenseKeyWord;
                 }
@@ -6940,7 +6886,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
                         Set<VBD> vbds = vmSnapshot.getVBDs(conn);
                         for (VBD vbd : vbds) {
                             VBD.Record vbdr = vbd.getRecord(conn);
-                            if (vbdr.type == VbdType.DISK) {
+                            if (vbdr.type == Types.VbdType.DISK) {
                                 VDI vdi = vbdr.VDI;
                                 vdi.destroy(conn);
                             }
@@ -6959,8 +6905,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
         }
     }
 
-    private VM createWorkingVM(Connection conn, String vmName, String guestOSType, List<VolumeObjectTO> listVolumeTo) throws BadServerResponse, VmBadPowerState, SrFull,
-        OperationNotAllowed, XenAPIException, XmlRpcException {
+    private VM createWorkingVM(Connection conn, String vmName, String guestOSType, List<VolumeObjectTO> listVolumeTo) throws BadServerResponse, Types.VmBadPowerState, Types.SrFull,
+            Types.OperationNotAllowed, XenAPIException, XmlRpcException {
         String guestOsTypeName = getGuestOsType(guestOSType, false);
         if (guestOsTypeName == null) {
             String msg =
@@ -7015,7 +6961,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
             VM snapshot = snapshots.iterator().next();
             Set<VBD> vbds = snapshot.getVBDs(conn);
             for (VBD vbd : vbds) {
-                if (vbd.getType(conn) == VbdType.DISK) {
+                if (vbd.getType(conn) == Types.VbdType.DISK) {
                     VDI vdi = vbd.getVDI(conn);
                     vdiList.add(vdi);
                 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/62bb5d88/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java
index 0d5eec8..d4f0ffd 100644
--- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java
+++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java
@@ -30,22 +30,6 @@ import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
 
-import org.apache.log4j.Logger;
-import org.apache.xmlrpc.XmlRpcException;
-
-import com.xensource.xenapi.Connection;
-import com.xensource.xenapi.Host;
-import com.xensource.xenapi.PBD;
-import com.xensource.xenapi.Pool;
-import com.xensource.xenapi.SR;
-import com.xensource.xenapi.Types;
-import com.xensource.xenapi.Types.BadServerResponse;
-import com.xensource.xenapi.Types.XenAPIException;
-import com.xensource.xenapi.VBD;
-import com.xensource.xenapi.VDI;
-import com.xensource.xenapi.VM;
-import com.xensource.xenapi.VMGuestMetrics;
-
 import org.apache.cloudstack.storage.command.AttachAnswer;
 import org.apache.cloudstack.storage.command.AttachCommand;
 import org.apache.cloudstack.storage.command.AttachPrimaryDataStoreAnswer;
@@ -64,6 +48,8 @@ import org.apache.cloudstack.storage.datastore.protocol.DataStoreProtocol;
 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 org.apache.xmlrpc.XmlRpcException;
 
 import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.CreateStoragePoolCommand;
@@ -86,6 +72,18 @@ import com.cloud.utils.exception.CloudRuntimeException;
 import com.cloud.utils.storage.encoding.DecodedDataObject;
 import com.cloud.utils.storage.encoding.DecodedDataStore;
 import com.cloud.utils.storage.encoding.Decoder;
+import com.xensource.xenapi.Connection;
+import com.xensource.xenapi.Host;
+import com.xensource.xenapi.PBD;
+import com.xensource.xenapi.Pool;
+import com.xensource.xenapi.SR;
+import com.xensource.xenapi.Types;
+import com.xensource.xenapi.Types.BadServerResponse;
+import com.xensource.xenapi.Types.XenAPIException;
+import com.xensource.xenapi.VBD;
+import com.xensource.xenapi.VDI;
+import com.xensource.xenapi.VM;
+import com.xensource.xenapi.VMGuestMetrics;
 
 public class XenServerStorageProcessor implements StorageProcessor {
     private static final Logger s_logger = Logger.getLogger(XenServerStorageProcessor.class);
@@ -777,7 +775,7 @@ public class XenServerStorageProcessor implements StorageProcessor {
         }
     }
 
-    private boolean IsISCSI(String type) {
+    protected boolean IsISCSI(String type) {
         return SRType.LVMOHBA.equals(type) || SRType.LVMOISCSI.equals(type) || SRType.LVM.equals(type);
     }
 
@@ -1076,7 +1074,7 @@ public class XenServerStorageProcessor implements StorageProcessor {
         return lfilename;
     }
 
-    private String backupSnapshotToS3(final Connection connection, final S3TO s3, final String srUuid, final String folder, final String snapshotUuid,
+    protected String backupSnapshotToS3(final Connection connection, final S3TO s3, final String srUuid, final String folder, final String snapshotUuid,
         final Boolean iSCSIFlag, final int wait) {
 
         final String filename = iSCSIFlag ? "VHD-" + snapshotUuid : snapshotUuid + ".vhd";
@@ -1149,7 +1147,7 @@ public class XenServerStorageProcessor implements StorageProcessor {
         throw new CloudRuntimeException(errMsg);
     }
 
-    private boolean destroySnapshotOnPrimaryStorageExceptThis(Connection conn, String volumeUuid, String avoidSnapshotUuid) {
+    protected boolean destroySnapshotOnPrimaryStorageExceptThis(Connection conn, String volumeUuid, String avoidSnapshotUuid) {
         try {
             VDI volume = getVDIbyUuid(conn, volumeUuid);
             if (volume == null) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/62bb5d88/plugins/hypervisors/xen/src/org/apache/cloudstack/hypervisor/xenserver/XenServerResourceNewBase.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xen/src/org/apache/cloudstack/hypervisor/xenserver/XenServerResourceNewBase.java b/plugins/hypervisors/xen/src/org/apache/cloudstack/hypervisor/xenserver/XenServerResourceNewBase.java
index 2ee45a3..1c97486 100644
--- a/plugins/hypervisors/xen/src/org/apache/cloudstack/hypervisor/xenserver/XenServerResourceNewBase.java
+++ b/plugins/hypervisors/xen/src/org/apache/cloudstack/hypervisor/xenserver/XenServerResourceNewBase.java
@@ -45,26 +45,6 @@ import com.cloud.utils.exception.CloudRuntimeException;
 import com.cloud.vm.VirtualMachine;
 import com.cloud.vm.VirtualMachineName;
 
-/**
- * 
- * XenServerResourceNewBase is an abstract base class that encapsulates how
- * CloudStack should interact with XenServer after a special XenServer
- * 6.2 hotfix.  From here on, every Resource for future versions of
- * XenServer should use this as the base class.  This base class lessens
- * the amount of load CloudStack places on Xapi because it doesn't use
- * polling as a means to collect data and figure out task completion.
- * 
- * This base class differs from CitrixResourceBase in the following ways:
- *   - VM states are detected using Event.from instead of polling.  This
- *     increases the number of threads CloudStack uses but the threads
- *     are mostly idle just waiting for events from XenServer.
- *   - stats are collected through the http interface rather than Xapi plugin.
- *     This change may be promoted to CitrixResourceBase as it's also possible
- *     in previous versions of XenServer.
- *   - Asynchronous task completion is done throught Event.from rather than
- *     polling.
- *
- */
 public class XenServerResourceNewBase extends XenServer610Resource {
     private static final Logger s_logger = Logger.getLogger(XenServerResourceNewBase.class);
     protected VmEventListener _listener = null;


[05/10] git commit: updated refs/heads/master to 62bb5d8

Posted by ed...@apache.org.
Revert "Remove uncessary changes."

This reverts commit fcab2b776a252de4e6159de76b89f4fc776d5bca.


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

Branch: refs/heads/master
Commit: 9c77f680959ceae54b44c534e07821afaa5ed0ad
Parents: 336241b
Author: edison su <su...@gmail.com>
Authored: Thu Dec 5 13:14:11 2013 -0800
Committer: Edison Su <su...@gmail.com>
Committed: Thu Dec 19 13:35:52 2013 -0800

----------------------------------------------------------------------
 api/src/org/apache/cloudstack/api/ServerApiException.java | 5 +++++
 1 file changed, 5 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/9c77f680/api/src/org/apache/cloudstack/api/ServerApiException.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/ServerApiException.java b/api/src/org/apache/cloudstack/api/ServerApiException.java
index 825f64a..a8bb2ed 100644
--- a/api/src/org/apache/cloudstack/api/ServerApiException.java
+++ b/api/src/org/apache/cloudstack/api/ServerApiException.java
@@ -81,4 +81,9 @@ public class ServerApiException extends CloudRuntimeException {
     public void setDescription(String description) {
         _description = description;
     }
+
+    @Override
+    public String getMessage() {
+        return _description;
+    }
 }


[02/10] git commit: updated refs/heads/master to 62bb5d8

Posted by ed...@apache.org.
Add AUTO_INCREMENT in details dao


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

Branch: refs/heads/master
Commit: 864c91ba7fd7f2b7a1a25db34b770ff400c7c07b
Parents: a3fade8
Author: edison su <su...@gmail.com>
Authored: Tue Dec 3 13:04:35 2013 -0800
Committer: Edison Su <su...@gmail.com>
Committed: Thu Dec 19 13:35:15 2013 -0800

----------------------------------------------------------------------
 setup/db/db/schema-421to430.sql | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/864c91ba/setup/db/db/schema-421to430.sql
----------------------------------------------------------------------
diff --git a/setup/db/db/schema-421to430.sql b/setup/db/db/schema-421to430.sql
index e3e8f1c..e662429 100644
--- a/setup/db/db/schema-421to430.sql
+++ b/setup/db/db/schema-421to430.sql
@@ -45,7 +45,7 @@ ALTER TABLE `cloud`.`load_balancing_rules` ADD COLUMN `lb_protocol` VARCHAR(40);
 
 DROP TABLE IF EXISTS `cloud`.`vm_snapshot_details`;
 CREATE TABLE `cloud`.`vm_snapshot_details` (
-  `id` bigint unsigned UNIQUE NOT NULL,
+  `id` bigint unsigned UNIQUE NOT NULL AUTO_INCREMENT,
   `vm_snapshot_id` bigint unsigned NOT NULL,
   `name` varchar(255) NOT NULL,
   `value` varchar(255) NOT NULL,
@@ -54,7 +54,7 @@ CREATE TABLE `cloud`.`vm_snapshot_details` (
 
 DROP TABLE IF EXISTS `cloud`.`snapshot_details`;
 CREATE TABLE `cloud`.`snapshot_details` (
-  `id` bigint unsigned UNIQUE NOT NULL,
+  `id` bigint unsigned UNIQUE NOT NULL AUTO_INCREMENT,
   `snapshot_id` bigint unsigned NOT NULL,
   `name` varchar(255) NOT NULL,
   `value` varchar(255) NOT NULL,


[06/10] git commit: updated refs/heads/master to 62bb5d8

Posted by ed...@apache.org.
CS-18582: if EIP is used, extract volume and template returns wrong public ip address. If remote agent is ssvm agent, then looking up public ip address from ssvm table

Conflicts:

	engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java
	engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeServiceTest.java
	engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java
	engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTestVmware.java
	engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java
	engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java


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

Branch: refs/heads/master
Commit: c40d03b41728c012012147a5f159d71aadf8b064
Parents: 9c77f68
Author: Edison Su <su...@gmail.com>
Authored: Thu Dec 19 14:01:20 2013 -0800
Committer: Edison Su <su...@gmail.com>
Committed: Thu Dec 19 14:01:20 2013 -0800

----------------------------------------------------------------------
 .../cloudstack/storage/test/SnapshotTest.java   |  3 +--
 .../storage/test/VolumeServiceTest.java         |  2 +-
 .../cloudstack/storage/test/VolumeTest.java     |  2 +-
 .../storage/test/VolumeTestVmware.java          |  2 +-
 .../cloudstack/storage/RemoteHostEndPoint.java  | 24 ++++++++++++++------
 .../endpoint/DefaultEndPointSelector.java       |  9 ++++----
 6 files changed, 26 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c40d03b4/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java
----------------------------------------------------------------------
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java
index f1f9383..cac6ea2 100644
--- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java
+++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java
@@ -277,8 +277,7 @@ public class SnapshotTest extends CloudStackTestNGBase {
         List<HostVO> hosts = new ArrayList<HostVO>();
         hosts.add(this.host);
         Mockito.when(resourceMgr.listAllUpAndEnabledHosts((Type)Matchers.any(), Matchers.anyLong(), Matchers.anyLong(), Matchers.anyLong())).thenReturn(hosts);
-
-        remoteEp = RemoteHostEndPoint.getHypervisorHostEndPoint(this.host.getId(), this.host.getPrivateIpAddress(), this.host.getPublicIpAddress());
+        remoteEp = RemoteHostEndPoint.getHypervisorHostEndPoint(this.host);
         Mockito.when(epSelector.select(Matchers.any(DataObject.class), Matchers.any(DataObject.class))).thenReturn(remoteEp);
         Mockito.when(epSelector.select(Matchers.any(DataObject.class))).thenReturn(remoteEp);
         Mockito.when(epSelector.select(Matchers.any(DataStore.class))).thenReturn(remoteEp);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c40d03b4/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeServiceTest.java
----------------------------------------------------------------------
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeServiceTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeServiceTest.java
index 2f5b18b..5fe1d39 100644
--- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeServiceTest.java
+++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeServiceTest.java
@@ -195,7 +195,7 @@ public class VolumeServiceTest extends CloudStackTestNGBase {
         Mockito.when(hostDao.findById(Matchers.anyLong())).thenReturn(host);
         Mockito.when(hostDao.findHypervisorHostInCluster(Matchers.anyLong())).thenReturn(results);
         List<EndPoint> eps = new ArrayList<EndPoint>();
-        eps.add(RemoteHostEndPoint.getHypervisorHostEndPoint(host.getId(), host.getPrivateIpAddress(), host.getPublicIpAddress()));
+        eps.add(RemoteHostEndPoint.getHypervisorHostEndPoint(host));
         Mockito.when(selector.selectAll(Matchers.any(DataStore.class))).thenReturn(eps);
         Mockito.when(selector.select(Matchers.any(DataObject.class))).thenReturn(eps.get(0));
         Mockito.when(selector.select(Matchers.any(DataObject.class), Matchers.any(DataObject.class))).thenReturn(eps.get(0));

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c40d03b4/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java
----------------------------------------------------------------------
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java
index c75b2e7..4a6151d 100644
--- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java
+++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java
@@ -254,7 +254,7 @@ public class VolumeTest extends CloudStackTestNGBase {
         hosts.add(this.host);
         Mockito.when(resourceMgr.listAllUpAndEnabledHosts((Type)Matchers.any(), Matchers.anyLong(), Matchers.anyLong(), Matchers.anyLong())).thenReturn(hosts);
 
-        RemoteHostEndPoint ep = RemoteHostEndPoint.getHypervisorHostEndPoint(this.host.getId(), this.host.getPrivateIpAddress(), this.host.getPublicIpAddress());
+        RemoteHostEndPoint ep = RemoteHostEndPoint.getHypervisorHostEndPoint(this.host);
         Mockito.when(epSelector.select(Matchers.any(DataObject.class), Matchers.any(DataObject.class))).thenReturn(ep);
         Mockito.when(epSelector.select(Matchers.any(DataObject.class))).thenReturn(ep);
         Mockito.when(epSelector.select(Matchers.any(DataStore.class))).thenReturn(ep);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c40d03b4/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTestVmware.java
----------------------------------------------------------------------
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTestVmware.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTestVmware.java
index 800bc6b..1f3aff0 100644
--- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTestVmware.java
+++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTestVmware.java
@@ -256,7 +256,7 @@ public class VolumeTestVmware extends CloudStackTestNGBase {
         hosts.add(this.host);
         Mockito.when(resourceMgr.listAllUpAndEnabledHosts((Type)Matchers.any(), Matchers.anyLong(), Matchers.anyLong(), Matchers.anyLong())).thenReturn(hosts);
 
-        RemoteHostEndPoint ep = RemoteHostEndPoint.getHypervisorHostEndPoint(this.host.getId(), this.host.getPrivateIpAddress(), this.host.getPublicIpAddress());
+        RemoteHostEndPoint ep = RemoteHostEndPoint.getHypervisorHostEndPoint(this.host);
         Mockito.when(epSelector.select(Matchers.any(DataObject.class), Matchers.any(DataObject.class))).thenReturn(ep);
         Mockito.when(epSelector.select(Matchers.any(DataObject.class))).thenReturn(ep);
         Mockito.when(epSelector.select(Matchers.any(DataStore.class))).thenReturn(ep);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c40d03b4/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java b/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java
index 98c9db1..34f9c9d 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java
@@ -25,7 +25,8 @@ import java.util.concurrent.TimeUnit;
 import javax.inject.Inject;
 
 import org.apache.log4j.Logger;
-
+import com.cloud.vm.SecondaryStorageVmVO;
+import com.cloud.vm.dao.SecondaryStorageVmDao;
 import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
 import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
 import org.apache.cloudstack.managed.context.ManagedContextRunnable;
@@ -57,21 +58,30 @@ public class RemoteHostEndPoint implements EndPoint {
     AgentManager agentMgr;
     @Inject
     protected HypervisorGuruManager _hvGuruMgr;
+    @Inject
+    protected SecondaryStorageVmDao vmDao;
     private ScheduledExecutorService executor;
 
     public RemoteHostEndPoint() {
         executor = Executors.newScheduledThreadPool(10, new NamedThreadFactory("RemoteHostEndPoint"));
     }
 
-    private void configure(long hostId, String hostAddress, String publicAddress) {
-        this.hostId = hostId;
-        this.hostAddress = hostAddress;
-        this.publicAddress = publicAddress;
+    private void configure(Host host) {
+        this.hostId = host.getId();
+        this.hostAddress = host.getPrivateIpAddress();
+        this.publicAddress = host.getPublicIpAddress();
+        if (Host.Type.SecondaryStorageVM == host.getType()) {
+            String vmName = host.getName();
+            SecondaryStorageVmVO ssvm = vmDao.findByInstanceName(vmName);
+            if (ssvm != null) {
+                this.publicAddress = ssvm.getPublicIpAddress();
+            }
+        }
     }
 
-    public static RemoteHostEndPoint getHypervisorHostEndPoint(long hostId, String hostAddress, String publicAddress) {
+    public static RemoteHostEndPoint getHypervisorHostEndPoint(Host host) {
         RemoteHostEndPoint ep = ComponentContext.inject(RemoteHostEndPoint.class);
-        ep.configure(hostId, hostAddress, publicAddress);
+        ep.configure(host);
         return ep;
     }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c40d03b4/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 df1c9ee..6560d2f 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java
@@ -140,7 +140,7 @@ public class DefaultEndPointSelector implements EndPointSelector {
             return null;
         }
 
-        return RemoteHostEndPoint.getHypervisorHostEndPoint(host.getId(), host.getPrivateIpAddress(), host.getPublicIpAddress());
+        return RemoteHostEndPoint.getHypervisorHostEndPoint(host);
     }
 
     protected EndPoint findEndPointForImageMove(DataStore srcStore, DataStore destStore) {
@@ -223,7 +223,7 @@ public class DefaultEndPointSelector implements EndPointSelector {
         }
         Collections.shuffle(ssAHosts);
         HostVO host = ssAHosts.get(0);
-        return RemoteHostEndPoint.getHypervisorHostEndPoint(host.getId(), host.getPrivateIpAddress(), host.getPublicIpAddress());
+        return RemoteHostEndPoint.getHypervisorHostEndPoint(host);
     }
 
     private List<HostVO> listUpAndConnectingSecondaryStorageVmHost(Long dcId) {
@@ -276,14 +276,15 @@ public class DefaultEndPointSelector implements EndPointSelector {
         List<EndPoint> endPoints = new ArrayList<EndPoint>();
         if (store.getScope().getScopeType() == ScopeType.HOST) {
             HostVO host = hostDao.findById(store.getScope().getScopeId());
-            endPoints.add(RemoteHostEndPoint.getHypervisorHostEndPoint(host.getId(), host.getPrivateIpAddress(), host.getPublicIpAddress()));
+
+            endPoints.add(RemoteHostEndPoint.getHypervisorHostEndPoint(host));
         } else if (store.getScope().getScopeType() == ScopeType.CLUSTER) {
             QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
             sc.and(sc.entity().getClusterId(), Op.EQ, store.getScope().getScopeId());
             sc.and(sc.entity().getStatus(), Op.EQ, Status.Up);
             List<HostVO> hosts = sc.list();
             for (HostVO host : hosts) {
-                endPoints.add(RemoteHostEndPoint.getHypervisorHostEndPoint(host.getId(), host.getPrivateIpAddress(), host.getPublicIpAddress()));
+                endPoints.add(RemoteHostEndPoint.getHypervisorHostEndPoint(host));
             }
 
         } else {


[09/10] git commit: updated refs/heads/master to 62bb5d8

Posted by ed...@apache.org.
CLOUDSTACK-4939 - Failed to create snapshot (KVM, Multiple hosts, Sharedstorage)

Conflicts:

	engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java
	engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java
	plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java

Conflicts:

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


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

Branch: refs/heads/master
Commit: 0824c78761911ef56825010d3f710562e2eedd65
Parents: 8caf52c
Author: Edison Su <su...@gmail.com>
Authored: Thu Dec 19 14:17:30 2013 -0800
Committer: Edison Su <su...@gmail.com>
Committed: Thu Dec 19 14:17:30 2013 -0800

----------------------------------------------------------------------
 .../subsystem/api/storage/EndPointSelector.java |  4 ++
 .../subsystem/api/storage/StorageAction.java    | 25 +++++++++++
 .../subsystem/api/storage/VolumeInfo.java       |  2 +
 .../motion/AncientDataMotionStrategy.java       | 13 ++----
 .../endpoint/DefaultEndPointSelector.java       | 47 ++++++++++++++++++--
 .../cloudstack/storage/volume/VolumeObject.java | 14 +++++-
 .../CloudStackPrimaryDataStoreDriverImpl.java   | 11 ++---
 7 files changed, 95 insertions(+), 21 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0824c787/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 8f5921d..4657316 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
@@ -23,10 +23,14 @@ import java.util.List;
 public interface EndPointSelector {
     EndPoint select(DataObject srcData, DataObject destData);
 
+    EndPoint select(DataObject srcData, DataObject destData, StorageAction action);
+
     EndPoint select(DataObject object);
 
     EndPoint select(DataStore store);
 
+    EndPoint select(DataObject object, StorageAction action);
+
     List<EndPoint> selectAll(DataStore store);
 
     EndPoint select(Scope scope, Long storeId);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0824c787/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageAction.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageAction.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageAction.java
new file mode 100644
index 0000000..4fbb20e
--- /dev/null
+++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageAction.java
@@ -0,0 +1,25 @@
+/*
+ * 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.engine.subsystem.api.storage;
+
+public enum StorageAction {
+    TAKESNAPSHOT,
+    BACKUPSNAPSHOT,
+    DELETESNAPSHOT
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0824c787/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java
index 5cba79a..f93f4ef 100644
--- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java
+++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java
@@ -22,6 +22,7 @@ import com.cloud.agent.api.Answer;
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
 import com.cloud.offering.DiskOffering.DiskCacheMode;
 import com.cloud.storage.Volume;
+import com.cloud.vm.VirtualMachine;
 
 public interface VolumeInfo extends DataObject, Volume {
     boolean isAttachedVM();
@@ -35,6 +36,7 @@ public interface VolumeInfo extends DataObject, Volume {
     Long getLastPoolId();
 
     String getAttachedVmName();
+    VirtualMachine getAttachedVM();
 
     void processEventOnly(ObjectInDataStoreStateMachine.Event event);
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0824c787/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 3809722..47467e5 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
@@ -23,15 +23,7 @@ import java.util.Map;
 
 import javax.inject.Inject;
 
-import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope;
-import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionStrategy;
-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.DataStoreManager;
-import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
-import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
-import org.apache.cloudstack.engine.subsystem.api.storage.HostScope;
+import org.apache.cloudstack.engine.subsystem.api.storage.*;
 import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event;
 import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
 import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
@@ -498,7 +490,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy {
             } else {
                 CopyCommand cmd = new CopyCommand(srcData.getTO(), destData.getTO(), _backupsnapshotwait, VirtualMachineManager.ExecuteInSequence.value());
                 cmd.setOptions(options);
-                EndPoint ep = selector.select(srcData, destData);
+                EndPoint ep = selector.select(srcData, destData, StorageAction.BACKUPSNAPSHOT);
                 if (ep == null) {
                     String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
                     s_logger.error(errMsg);
@@ -506,6 +498,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy {
                 } else {
                     answer = ep.sendMessage(cmd);
                 }
+
             }
             // clean up cache entry
             if (cacheData != null) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0824c787/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 9f23940..b83fb4e 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java
@@ -27,23 +27,25 @@ import java.util.List;
 
 import javax.inject.Inject;
 
-import com.cloud.utils.db.Transaction;
-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;
 import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
 import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
+import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.StorageAction;
 import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
 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;
 import com.cloud.host.Status;
 import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor;
 import com.cloud.storage.DataStoreRole;
 import com.cloud.storage.ScopeType;
 import com.cloud.storage.Storage.TemplateType;
@@ -52,6 +54,7 @@ import com.cloud.utils.db.QueryBuilder;
 import com.cloud.utils.db.SearchCriteria.Op;
 import com.cloud.utils.db.TransactionLegacy;
 import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.VirtualMachine;
 
 @Component
 public class DefaultEndPointSelector implements EndPointSelector {
@@ -206,6 +209,21 @@ public class DefaultEndPointSelector implements EndPointSelector {
         return null;
     }
 
+    @Override
+    public EndPoint select(DataObject srcData, DataObject destData, StorageAction action) {
+        if (action == StorageAction.BACKUPSNAPSHOT) {
+            SnapshotInfo srcSnapshot = (SnapshotInfo)srcData;
+            if (srcSnapshot.getHypervisorType() == Hypervisor.HypervisorType.KVM) {
+                VolumeInfo volumeInfo = srcSnapshot.getBaseVolume();
+                VirtualMachine vm = volumeInfo.getAttachedVM();
+                if (vm != null && vm.getState() == VirtualMachine.State.Running) {
+                    return getEndPointFromHostId(vm.getHostId());
+                }
+            }
+        }
+        return select(srcData, destData);
+    }
+
     protected EndPoint findEndpointForPrimaryStorage(DataStore store) {
         return findEndPointInScope(store.getScope(), findOneHostOnPrimaryStorage, store.getId());
     }
@@ -268,6 +286,27 @@ public class DefaultEndPointSelector implements EndPointSelector {
         }
     }
 
+    private EndPoint getEndPointFromHostId(Long hostId) {
+        HostVO host = hostDao.findById(hostId);
+        return RemoteHostEndPoint.getHypervisorHostEndPoint(host);
+    }
+
+    @Override
+    public EndPoint select(DataObject object, StorageAction action) {
+        if (action == StorageAction.TAKESNAPSHOT) {
+            SnapshotInfo snapshotInfo = (SnapshotInfo)object;
+            if (snapshotInfo.getHypervisorType() == Hypervisor.HypervisorType.KVM) {
+                VolumeInfo volumeInfo = snapshotInfo.getBaseVolume();
+                VirtualMachine vm = volumeInfo.getAttachedVM();
+                if ((vm != null) && (vm.getState() == VirtualMachine.State.Running)) {
+                    Long hostId = vm.getHostId();
+                    return getEndPointFromHostId(hostId);
+                }
+            }
+        }
+        return select(object);
+    }
+
     @Override
     public EndPoint select(Scope scope, Long storeId) {
         return findEndPointInScope(scope, findOneHostOnPrimaryStorage, storeId);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0824c787/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java
----------------------------------------------------------------------
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java
index 3b5d938..76a94cd 100644
--- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java
+++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java
@@ -22,6 +22,9 @@ import javax.inject.Inject;
 
 import org.apache.log4j.Logger;
 
+import com.cloud.storage.DiskOfferingVO;
+import com.cloud.storage.dao.DiskOfferingDao;
+import com.cloud.vm.VirtualMachine;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
 import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
@@ -40,11 +43,9 @@ import com.cloud.agent.api.to.DataTO;
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
 import com.cloud.offering.DiskOffering.DiskCacheMode;
 import com.cloud.storage.DataStoreRole;
-import com.cloud.storage.DiskOfferingVO;
 import com.cloud.storage.Storage.ImageFormat;
 import com.cloud.storage.Volume;
 import com.cloud.storage.VolumeVO;
-import com.cloud.storage.dao.DiskOfferingDao;
 import com.cloud.storage.dao.VolumeDao;
 import com.cloud.utils.component.ComponentContext;
 import com.cloud.utils.exception.CloudRuntimeException;
@@ -101,6 +102,15 @@ public class VolumeObject implements VolumeInfo {
     }
 
     @Override
+    public VirtualMachine getAttachedVM() {
+        Long vmId = this.volumeVO.getInstanceId();
+        if (vmId != null) {
+            VMInstanceVO vm = vmInstanceDao.findById(vmId);
+            return vm;
+        }
+        return null;
+    }
+    @Override
     public String getUuid() {
         return volumeVO.getUuid();
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0824c787/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java
----------------------------------------------------------------------
diff --git a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java
index e41b437..bab960e 100644
--- a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java
+++ b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java
@@ -24,8 +24,6 @@ import java.util.UUID;
 
 import javax.inject.Inject;
 
-import org.apache.log4j.Logger;
-
 import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
 import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo;
 import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
@@ -37,6 +35,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
 import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
 import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver;
 import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.StorageAction;
 import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
 import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
@@ -51,6 +50,7 @@ import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
 import org.apache.cloudstack.storage.to.SnapshotObjectTO;
 import org.apache.cloudstack.storage.to.TemplateObjectTO;
 import org.apache.cloudstack.storage.volume.VolumeObject;
+import org.apache.log4j.Logger;
 
 import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.storage.ResizeVolumeAnswer;
@@ -269,10 +269,11 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri
             }
 
             CreateObjectCommand cmd = new CreateObjectCommand(snapshotTO);
-            EndPoint ep = epSelector.select(snapshot);
+            EndPoint ep = this.epSelector.select(snapshot, StorageAction.TAKESNAPSHOT);
             Answer answer = null;
-            if (ep == null) {
-                String errMsg = "No remote endpoint to send DeleteCommand, check if host or ssvm is down?";
+
+            if ( ep == null ){
+                String errMsg = "No remote endpoint to send createObjectCommand, check if host or ssvm is down?";
                 s_logger.error(errMsg);
                 answer = new Answer(cmd, false, errMsg);
             } else {


[07/10] add xenserver 6.2.0 hotfix support, to optimize vdi copy

Posted by ed...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8caf52c6/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/Xenserver625StorageProcessor.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/Xenserver625StorageProcessor.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/Xenserver625StorageProcessor.java
new file mode 100644
index 0000000..dad3d14
--- /dev/null
+++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/Xenserver625StorageProcessor.java
@@ -0,0 +1,822 @@
+/*
+ * 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 com.cloud.hypervisor.xen.resource;
+
+import java.io.File;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
+import org.apache.cloudstack.storage.command.CopyCmdAnswer;
+import org.apache.cloudstack.storage.command.CopyCommand;
+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.to.DataObjectType;
+import com.cloud.agent.api.to.DataStoreTO;
+import com.cloud.agent.api.to.DataTO;
+import com.cloud.agent.api.to.NfsTO;
+import com.cloud.agent.api.to.S3TO;
+import com.cloud.agent.api.to.SwiftTO;
+import com.cloud.exception.InternalErrorException;
+import com.cloud.storage.Storage;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.xensource.xenapi.Connection;
+import com.xensource.xenapi.Host;
+import com.xensource.xenapi.PBD;
+import com.xensource.xenapi.SR;
+import com.xensource.xenapi.Task;
+import com.xensource.xenapi.Types;
+import com.xensource.xenapi.VDI;
+
+public class Xenserver625StorageProcessor extends XenServerStorageProcessor {
+    private static final Logger s_logger = Logger.getLogger(XenServerStorageProcessor.class);
+
+    public Xenserver625StorageProcessor(CitrixResourceBase resource) {
+        super(resource);
+    }
+    protected boolean mountNfs(Connection conn, String remoteDir, String localDir) {
+        if (localDir == null) {
+            localDir = "/var/cloud_mount/" + UUID.nameUUIDFromBytes(remoteDir.getBytes());
+        }
+        String results = hypervisorResource.callHostPluginAsync(conn, "cloud-plugin-storage", "mountNfsSecondaryStorage", 100 * 1000,
+                "localDir", localDir, "remoteDir", remoteDir);
+        if (results == null || results.isEmpty()) {
+            String errMsg = "Could not mount secondary storage " + remoteDir + " on host ";
+            s_logger.warn(errMsg);
+            throw new CloudRuntimeException(errMsg);
+        }
+        return true;
+    }
+
+    protected boolean makeDirectory(Connection conn, String path) {
+        String result = hypervisorResource.callHostPlugin(conn, "cloud-plugin-storage", "makeDirectory", "path", path);
+        if (result == null || result.isEmpty()) {
+            return false;
+        }
+        return true;
+    }
+
+    protected SR createFileSR(Connection conn, String path) {
+        SR sr = null;
+        PBD pbd = null;
+        try {
+            Map<String, String> smConfig = new HashMap<String, String>();
+            Host host = Host.getByUuid(conn, hypervisorResource.getHost().uuid);
+            String uuid = UUID.randomUUID().toString();
+
+            sr = SR.introduce(conn,uuid, uuid, uuid, "file", "file", false, smConfig);
+            PBD.Record record = new PBD.Record();
+            record.host = host;
+            record.SR = sr;
+            smConfig.put("location", path);
+            record.deviceConfig = smConfig;
+            pbd = PBD.create(conn, record);
+            pbd.plug(conn);
+            sr.scan(conn);
+            return sr;
+        } catch (Exception e) {
+            try {
+                if (pbd != null) {
+                    pbd.destroy(conn);
+                }
+            } catch (Exception e1) {
+                s_logger.debug("Failed to destroy pbd", e);
+            }
+            try {
+                if (sr != null) {
+                    sr.forget(conn);
+                }
+            } catch (Exception e2) {
+                s_logger.error("Failed to forget sr", e);
+            }
+            String msg = "createFileSR failed! due to " + e.toString();
+            s_logger.warn(msg, e);
+            throw new CloudRuntimeException(msg, e);
+        }
+    }
+
+    protected SR createFileSr(Connection conn, String remotePath, String dir) {
+        String localDir = "/var/cloud_mount/" + UUID.nameUUIDFromBytes(remotePath.getBytes());
+        mountNfs(conn, remotePath, localDir);
+        SR sr = createFileSR(conn, localDir + "/" + dir);
+        return sr;
+    }
+
+    @Override
+    public Answer copyTemplateToPrimaryStorage(CopyCommand cmd) {
+        DataTO srcData = cmd.getSrcTO();
+        DataTO destData = cmd.getDestTO();
+        int wait = cmd.getWait();
+        DataStoreTO srcStore = srcData.getDataStore();
+        Connection conn = hypervisorResource.getConnection();
+        SR srcSr = null;
+        try {
+            if ((srcStore instanceof NfsTO) && (srcData.getObjectType() == DataObjectType.TEMPLATE)) {
+                NfsTO srcImageStore = (NfsTO)srcStore;
+                TemplateObjectTO srcTemplate = (TemplateObjectTO)srcData;
+                String storeUrl = srcImageStore.getUrl();
+                URI uri = new URI(storeUrl);
+                String volumePath = srcData.getPath();
+                volumePath = StringUtils.stripEnd(volumePath, "/");
+                String[] splits = volumePath.split("/");
+                String volumeDirectory = volumePath;
+                if (splits.length > 4) {
+                    //"template/tmpl/dcid/templateId/templatename"
+                    int index = volumePath.lastIndexOf("/");
+                    volumeDirectory = volumePath.substring(0, index);
+                }
+                srcSr = createFileSr(conn, uri.getHost() + ":" + uri.getPath(), volumeDirectory);
+                Set<VDI> vdis = srcSr.getVDIs(conn);
+                if (vdis.size() != 1) {
+                    return new CopyCmdAnswer("Can't find template VDI under: " + uri.getHost() + ":" + uri.getPath() + "/" + volumeDirectory);
+                }
+
+                VDI srcVdi = vdis.iterator().next();
+
+                PrimaryDataStoreTO destStore = (PrimaryDataStoreTO)destData.getDataStore();
+                String poolName = destStore.getUuid();
+
+
+                SR poolsr = null;
+                Set<SR> srs = SR.getByNameLabel(conn, poolName);
+                if (srs.size() != 1) {
+                    String msg = "There are " + srs.size() + " SRs with same name: " + poolName;
+                    s_logger.warn(msg);
+                    return new CopyCmdAnswer(msg);
+                } else {
+                    poolsr = srs.iterator().next();
+                }
+                String pUuid = poolsr.getUuid(conn);
+                boolean isISCSI = IsISCSI(poolsr.getType(conn));
+                Task task = srcVdi.copyAsync2(conn, poolsr, null, null);
+                // poll every 1 seconds ,
+                hypervisorResource.waitForTask(conn, task, 1000, wait * 1000);
+                hypervisorResource.checkForSuccess(conn, task);
+                VDI tmpl = Types.toVDI(task, conn);
+                VDI snapshotvdi = tmpl.snapshot(conn, new HashMap<String, String>());
+                snapshotvdi.setNameLabel(conn, "Template " + srcTemplate.getName());
+                tmpl.destroy(conn);
+                poolsr.scan(conn);
+                try{
+                    Thread.sleep(5000);
+                } catch (Exception e) {
+                }
+
+                TemplateObjectTO newVol = new TemplateObjectTO();
+                newVol.setUuid(snapshotvdi.getUuid(conn));
+                newVol.setPath(newVol.getUuid());
+                newVol.setFormat(Storage.ImageFormat.VHD);
+                return new CopyCmdAnswer(newVol);
+            }
+        }catch (Exception e) {
+            String msg = "Catch Exception " + e.getClass().getName() + " for template + " + " due to " + e.toString();
+            s_logger.warn(msg, e);
+            return new CopyCmdAnswer(msg);
+        } finally {
+            if (srcSr != null) {
+                hypervisorResource.removeSR(conn, srcSr);
+            }
+        }
+        return new CopyCmdAnswer("not implemented yet");
+    }
+
+    protected String backupSnapshot(Connection conn, String primaryStorageSRUuid, String localMountPoint, String path, String secondaryStorageMountPath, String snapshotUuid, String prevBackupUuid, String prevSnapshotUuid, Boolean isISCSI, int wait) {
+        String errMsg = null;
+        boolean mounted = false;
+        boolean filesrcreated = false;
+        boolean copied = false;
+        if (prevBackupUuid == null) {
+            prevBackupUuid = "";
+        }
+        SR ssSR = null;
+
+        String remoteDir = secondaryStorageMountPath;
+
+        try {
+            ssSR = createFileSr(conn, remoteDir, path);
+            filesrcreated = true;
+
+            VDI snapshotvdi = VDI.getByUuid(conn, snapshotUuid);
+            Task task = null;
+            if (wait == 0) {
+                wait = 2 * 60 * 60;
+            }
+            VDI dvdi = null;
+            try {
+                VDI previousSnapshotVdi = null;
+                if (prevSnapshotUuid != null) {
+                    previousSnapshotVdi = VDI.getByUuid(conn,prevSnapshotUuid);
+                }
+                task = snapshotvdi.copyAsync2(conn, ssSR, previousSnapshotVdi, null);
+                // poll every 1 seconds ,
+                hypervisorResource.waitForTask(conn, task, 1000, wait * 1000);
+                hypervisorResource.checkForSuccess(conn, task);
+                dvdi = Types.toVDI(task, conn);
+                copied = true;
+            } finally {
+                if (task != null) {
+                    try {
+                        task.destroy(conn);
+                    } catch (Exception e1) {
+                        s_logger.warn("unable to destroy task(" + task.toString() + ") on host("
+                                + ") due to ", e1);
+                    }
+                }
+            }
+            String backupUuid = dvdi.getUuid(conn);
+            return backupUuid;
+        } catch (Exception e) {
+            String msg = "Exception in backupsnapshot stage due to " + e.toString();
+            s_logger.debug(msg);
+            throw new CloudRuntimeException(msg, e);
+        } finally {
+            try {
+                if (filesrcreated && ssSR != null) {
+                    hypervisorResource.removeSR(conn, ssSR);
+                }
+            } catch (Exception e) {
+                s_logger.debug("Exception in backupsnapshot cleanup stage due to " + e.toString());
+            }
+        }
+    }
+
+    @Override
+    protected String getVhdParent(Connection conn, String primaryStorageSRUuid, String snapshotUuid, Boolean isISCSI) {
+        String parentUuid = hypervisorResource.callHostPlugin(conn, "cloud-plugin-storage", "getVhdParent", "primaryStorageSRUuid", primaryStorageSRUuid,
+                "snapshotUuid", snapshotUuid, "isISCSI", isISCSI.toString());
+
+        if (parentUuid == null || parentUuid.isEmpty() || parentUuid.equalsIgnoreCase("None")) {
+            s_logger.debug("Unable to get parent of VHD " + snapshotUuid + " in SR " + primaryStorageSRUuid);
+            // errString is already logged.
+            return null;
+        }
+        return parentUuid;
+    }
+
+    @Override
+    public Answer backupSnapshot(CopyCommand cmd) {
+        Connection conn = hypervisorResource.getConnection();
+        DataTO srcData = cmd.getSrcTO();
+        DataTO cacheData = cmd.getCacheTO();
+        DataTO destData = cmd.getDestTO();
+        int wait = cmd.getWait();
+        PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)srcData.getDataStore();
+        String primaryStorageNameLabel = primaryStore.getUuid();
+        String secondaryStorageUrl = null;
+        NfsTO cacheStore = null;
+        String destPath = null;
+        if (cacheData != null) {
+            cacheStore = (NfsTO)cacheData.getDataStore();
+            secondaryStorageUrl = cacheStore.getUrl();
+            destPath = cacheData.getPath();
+        } else {
+            cacheStore = (NfsTO)destData.getDataStore();
+            secondaryStorageUrl = cacheStore.getUrl();
+            destPath = destData.getPath();
+        }
+
+        SnapshotObjectTO snapshotTO = (SnapshotObjectTO)srcData;
+        SnapshotObjectTO snapshotOnImage = (SnapshotObjectTO)destData;
+        String snapshotUuid = snapshotTO.getPath();
+
+        String prevBackupUuid = snapshotOnImage.getParentSnapshotPath();
+        String prevSnapshotUuid = snapshotTO.getParentSnapshotPath();
+        Map<String, String> options = cmd.getOptions();
+        // By default assume failure
+        String details = null;
+        String snapshotBackupUuid = null;
+        boolean fullbackup = Boolean.parseBoolean(options.get("fullSnapshot"));
+        try {
+            SR primaryStorageSR = hypervisorResource.getSRByNameLabelandHost(conn, primaryStorageNameLabel);
+            if (primaryStorageSR == null) {
+                throw new InternalErrorException("Could not backup snapshot because the primary Storage SR could not be created from the name label: " + primaryStorageNameLabel);
+            }
+            String psUuid = primaryStorageSR.getUuid(conn);
+            Boolean isISCSI = IsISCSI(primaryStorageSR.getType(conn));
+
+            VDI snapshotVdi = getVDIbyUuid(conn, snapshotUuid);
+            String snapshotPaUuid = null;
+
+            URI uri = new URI(secondaryStorageUrl);
+            String secondaryStorageMountPath = uri.getHost() + ":" + uri.getPath();
+            DataStoreTO destStore = destData.getDataStore();
+            String folder = destPath;
+            String finalPath = null;
+
+            String localMountPoint =  BaseMountPointOnHost + File.separator + UUID.nameUUIDFromBytes(secondaryStorageUrl.getBytes()).toString();
+            if (fullbackup) {
+                SR snapshotSr = null;
+                try {
+                    String localDir = "/var/cloud_mount/" + UUID.nameUUIDFromBytes(secondaryStorageMountPath.getBytes());
+                    mountNfs(conn, secondaryStorageMountPath, localDir);
+                    boolean result = makeDirectory(conn, localDir + "/" + folder);
+                    if (!result) {
+                        details = " Filed to create folder " + folder + " in secondary storage";
+                        s_logger.warn(details);
+                        return new CopyCmdAnswer(details);
+                    }
+
+                    snapshotSr = createFileSr(conn, secondaryStorageMountPath, folder);
+
+                    Task task = snapshotVdi.copyAsync2(conn, snapshotSr, null, null);
+                    // poll every 1 seconds ,
+                    hypervisorResource.waitForTask(conn, task, 1000, wait * 1000);
+                    hypervisorResource.checkForSuccess(conn, task);
+                    VDI backedVdi = Types.toVDI(task, conn);
+                    snapshotBackupUuid = backedVdi.getUuid(conn);
+
+                    if( destStore instanceof SwiftTO) {
+                        try {
+                            String container = "S-" + snapshotTO.getVolume().getVolumeId().toString();
+                            String destSnapshotName = swiftBackupSnapshot(conn, (SwiftTO)destStore, snapshotSr.getUuid(conn), snapshotBackupUuid, container, false, wait);
+                            String swiftPath = container + File.separator + destSnapshotName;
+                            finalPath = swiftPath;
+                        } finally {
+                            try {
+                                deleteSnapshotBackup(conn, localMountPoint, folder, secondaryStorageMountPath, snapshotBackupUuid);
+                            } catch (Exception e) {
+                                s_logger.debug("Failed to delete snapshot on cache storages" ,e);
+                            }
+                        }
+
+                    } else if (destStore instanceof S3TO) {
+                        try {
+                            finalPath = backupSnapshotToS3(conn, (S3TO) destStore, snapshotSr.getUuid(conn), folder, snapshotBackupUuid, isISCSI, wait);
+                            if (finalPath == null) {
+                                throw new CloudRuntimeException("S3 upload of snapshots " + snapshotBackupUuid + " failed");
+                            }
+                        } finally {
+                            try {
+                                deleteSnapshotBackup(conn, localMountPoint, folder, secondaryStorageMountPath, snapshotBackupUuid);
+                            } catch (Exception e) {
+                                s_logger.debug("Failed to delete snapshot on cache storages" ,e);
+                            }
+                        }
+                        // finalPath = folder + File.separator + snapshotBackupUuid;
+                    } else {
+                        finalPath = folder + File.separator + snapshotBackupUuid;
+                    }
+
+                } finally {
+                    if( snapshotSr != null) {
+                        hypervisorResource.removeSR(conn, snapshotSr);
+                    }
+                }
+            } else {
+                String primaryStorageSRUuid = primaryStorageSR.getUuid(conn);
+                if( destStore instanceof SwiftTO ) {
+                    String container = "S-" + snapshotTO.getVolume().getVolumeId().toString();
+                    snapshotBackupUuid = swiftBackupSnapshot(conn, (SwiftTO)destStore, primaryStorageSRUuid, snapshotPaUuid, "S-" + snapshotTO.getVolume().getVolumeId().toString(), isISCSI, wait);
+                    finalPath = container + File.separator + snapshotBackupUuid;
+                } else if (destStore instanceof S3TO ) {
+                    finalPath = backupSnapshotToS3(conn, (S3TO) destStore, primaryStorageSRUuid, folder, snapshotPaUuid, isISCSI, wait);
+                    if (finalPath == null) {
+                        throw new CloudRuntimeException("S3 upload of snapshots " + snapshotPaUuid + " failed");
+                    }
+                } else {
+                    snapshotBackupUuid = backupSnapshot(conn, primaryStorageSRUuid, localMountPoint, folder,
+                            secondaryStorageMountPath, snapshotUuid, prevBackupUuid, prevSnapshotUuid, isISCSI, wait);
+
+                    finalPath = folder + File.separator + snapshotBackupUuid;
+                }
+            }
+            String volumeUuid = snapshotTO.getVolume().getPath();
+            destroySnapshotOnPrimaryStorageExceptThis(conn, volumeUuid, snapshotUuid);
+
+            SnapshotObjectTO newSnapshot = new SnapshotObjectTO();
+            newSnapshot.setPath(finalPath);
+            if (fullbackup) {
+                newSnapshot.setParentSnapshotPath(null);
+            } else {
+                newSnapshot.setParentSnapshotPath(prevBackupUuid);
+            }
+            return new CopyCmdAnswer(newSnapshot);
+        } catch (Types.XenAPIException e) {
+            details = "BackupSnapshot Failed due to " + e.toString();
+            s_logger.warn(details, e);
+        } catch (Exception e) {
+            details = "BackupSnapshot Failed due to " + e.getMessage();
+            s_logger.warn(details, e);
+        }
+
+        return new CopyCmdAnswer(details);
+    }
+
+    @Override
+    public Answer createTemplateFromVolume(CopyCommand cmd) {
+        Connection conn = hypervisorResource.getConnection();
+        VolumeObjectTO volume = (VolumeObjectTO)cmd.getSrcTO();
+        TemplateObjectTO template = (TemplateObjectTO)cmd.getDestTO();
+        NfsTO destStore = (NfsTO)cmd.getDestTO().getDataStore();
+        int wait = cmd.getWait();
+
+        String secondaryStoragePoolURL = destStore.getUrl();
+        String volumeUUID = volume.getPath();
+
+        String userSpecifiedName = template.getName();
+
+
+        String details = null;
+        SR tmpltSR = null;
+        boolean result = false;
+        String secondaryStorageMountPath = null;
+        String installPath = null;
+        try {
+            URI uri = new URI(secondaryStoragePoolURL);
+            secondaryStorageMountPath = uri.getHost() + ":" + uri.getPath();
+            installPath = template.getPath();
+            if( !hypervisorResource.createSecondaryStorageFolder(conn, secondaryStorageMountPath, installPath)) {
+                details = " Filed to create folder " + installPath + " in secondary storage";
+                s_logger.warn(details);
+                return new CopyCmdAnswer(details);
+            }
+
+            VDI vol = getVDIbyUuid(conn, volumeUUID);
+            // create template SR
+            tmpltSR = createFileSr(conn, uri.getHost() + ":" + uri.getPath(), installPath);
+
+            // copy volume to template SR
+            Task task = vol.copyAsync2(conn, tmpltSR, null, null);
+            // poll every 1 seconds ,
+            hypervisorResource.waitForTask(conn, task, 1000, wait * 1000);
+            hypervisorResource.checkForSuccess(conn, task);
+            VDI tmpltVDI = Types.toVDI(task, conn);
+            // scan makes XenServer pick up VDI physicalSize
+            tmpltSR.scan(conn);
+            if (userSpecifiedName != null) {
+                tmpltVDI.setNameLabel(conn, userSpecifiedName);
+            }
+
+            String tmpltUUID = tmpltVDI.getUuid(conn);
+            String tmpltFilename = tmpltUUID + ".vhd";
+            long virtualSize = tmpltVDI.getVirtualSize(conn);
+            long physicalSize = tmpltVDI.getPhysicalUtilisation(conn);
+            // create the template.properties file
+            String templatePath = secondaryStorageMountPath + "/" + installPath;
+            result = hypervisorResource.postCreatePrivateTemplate(conn, templatePath, tmpltFilename, tmpltUUID, userSpecifiedName, null, physicalSize, virtualSize, template.getId());
+            if (!result) {
+                throw new CloudRuntimeException("Could not create the template.properties file on secondary storage dir");
+            }
+            installPath = installPath + "/" + tmpltFilename;
+            hypervisorResource.removeSR(conn, tmpltSR);
+            tmpltSR = null;
+            TemplateObjectTO newTemplate = new TemplateObjectTO();
+            newTemplate.setPath(installPath);
+            newTemplate.setFormat(Storage.ImageFormat.VHD);
+            newTemplate.setSize(virtualSize);
+            newTemplate.setPhysicalSize(physicalSize);
+            newTemplate.setName(tmpltUUID);
+            CopyCmdAnswer answer = new CopyCmdAnswer(newTemplate);
+            return answer;
+        } catch (Exception e) {
+            if (tmpltSR != null) {
+                hypervisorResource.removeSR(conn, tmpltSR);
+            }
+            if ( secondaryStorageMountPath != null) {
+                hypervisorResource.deleteSecondaryStorageFolder(conn, secondaryStorageMountPath, installPath);
+            }
+            details = "Creating template from volume " + volumeUUID + " failed due to " + e.toString();
+            s_logger.error(details, e);
+        }
+        return new CopyCmdAnswer(details);
+    }
+
+    protected String getSnapshotUuid(String snapshotPath) {
+        int index = snapshotPath.lastIndexOf(File.separator);
+        String snapshotUuid = snapshotPath.substring(index + 1);
+        index = snapshotUuid.lastIndexOf(".");
+        if (index != -1) {
+            snapshotUuid = snapshotUuid.substring(0, index);
+        }
+        return snapshotUuid;
+    }
+
+    @Override
+    public Answer createVolumeFromSnapshot(CopyCommand cmd) {
+        Connection conn = hypervisorResource.getConnection();
+        DataTO srcData = cmd.getSrcTO();
+        SnapshotObjectTO snapshot = (SnapshotObjectTO)srcData;
+        DataTO destData = cmd.getDestTO();
+        PrimaryDataStoreTO pool = (PrimaryDataStoreTO)destData.getDataStore();
+        VolumeObjectTO volume = (VolumeObjectTO)destData;
+                DataStoreTO imageStore = srcData.getDataStore();
+
+        if (!(imageStore instanceof NfsTO)) {
+            return new CopyCmdAnswer("unsupported protocol");
+        }
+
+        NfsTO nfsImageStore = (NfsTO)imageStore;
+        String primaryStorageNameLabel = pool.getUuid();
+        String secondaryStorageUrl = nfsImageStore.getUrl();
+        int wait = cmd.getWait();
+        boolean result = false;
+        // Generic error message.
+        String details = null;
+        String volumeUUID = null;
+
+        if (secondaryStorageUrl == null) {
+            details += " because the URL passed: " + secondaryStorageUrl + " is invalid.";
+            return new CopyCmdAnswer(details);
+        }
+        SR srcSr = null;
+        VDI destVdi = null;
+        try {
+            SR primaryStorageSR = hypervisorResource.getSRByNameLabelandHost(conn, primaryStorageNameLabel);
+            if (primaryStorageSR == null) {
+                throw new InternalErrorException("Could not create volume from snapshot because the primary Storage SR could not be created from the name label: "
+                        + primaryStorageNameLabel);
+            }
+            String nameLabel = "cloud-" + UUID.randomUUID().toString();
+            destVdi = createVdi(conn, nameLabel, primaryStorageSR, volume.getSize());
+            volumeUUID = destVdi.getUuid(conn);
+            String snapshotInstallPath = snapshot.getPath();
+            int index = snapshotInstallPath.lastIndexOf(File.separator);
+            String snapshotDirectory = snapshotInstallPath.substring(0, index);
+            String snapshotUuid = getSnapshotUuid(snapshotInstallPath);
+
+            URI uri = new URI(secondaryStorageUrl);
+            srcSr = createFileSr(conn, uri.getHost() + ":" + uri.getPath(), snapshotDirectory);
+
+            String[] parents = snapshot.getParents();
+            List<VDI> snapshotChains = new ArrayList<VDI>();
+            if (parents != null) {
+                for(int i = 0; i < parents.length; i++) {
+                    String snChainPath = parents[i];
+                    String uuid = getSnapshotUuid(snChainPath);
+                    VDI chain = VDI.getByUuid(conn, uuid);
+                    snapshotChains.add(chain);
+                }
+            }
+
+            VDI snapshotVdi = VDI.getByUuid(conn, snapshotUuid);
+            snapshotChains.add(snapshotVdi);
+
+            for(VDI snapChain : snapshotChains) {
+                Task task = snapChain.copyAsync2(conn, null, null, destVdi);
+                // poll every 1 seconds ,
+                hypervisorResource.waitForTask(conn, task, 1000, wait * 1000);
+                hypervisorResource.checkForSuccess(conn, task);
+            }
+
+            result = true;
+            destVdi = VDI.getByUuid(conn, volumeUUID);
+            VDI.Record vdir = destVdi.getRecord(conn);
+            VolumeObjectTO newVol = new VolumeObjectTO();
+            newVol.setPath(volumeUUID);
+            newVol.setSize(vdir.virtualSize);
+            return new CopyCmdAnswer(newVol);
+        } catch (Types.XenAPIException e) {
+            details += " due to " + e.toString();
+            s_logger.warn(details, e);
+        } catch (Exception e) {
+            details += " due to " + e.getMessage();
+            s_logger.warn(details, e);
+        } finally {
+            if (srcSr != null) {
+                hypervisorResource.removeSR(conn, srcSr);
+            }
+            if (!result && destVdi != null) {
+                try {
+                    destVdi.destroy(conn);
+                } catch (Exception e) {
+                    s_logger.debug("destroy dest vdi failed", e);
+                }
+            }
+        }
+        if (!result) {
+            // Is this logged at a higher level?
+            s_logger.error(details);
+        }
+
+        // In all cases return something.
+        return new CopyCmdAnswer(details);
+    }
+
+    @Override
+    public Answer copyVolumeFromPrimaryToSecondary(CopyCommand cmd) {
+        Connection conn = hypervisorResource.getConnection();
+        VolumeObjectTO srcVolume = (VolumeObjectTO)cmd.getSrcTO();
+        VolumeObjectTO destVolume = (VolumeObjectTO)cmd.getDestTO();
+        int wait = cmd.getWait();
+        DataStoreTO destStore = destVolume.getDataStore();
+
+        if (destStore instanceof NfsTO) {
+            SR secondaryStorage = null;
+            try {
+                NfsTO nfsStore = (NfsTO)destStore;
+                URI uri = new URI(nfsStore.getUrl());
+                // Create the volume folder
+                if (!hypervisorResource.createSecondaryStorageFolder(conn, uri.getHost() + ":" + uri.getPath(), destVolume.getPath())) {
+                    throw new InternalErrorException("Failed to create the volume folder.");
+                }
+
+                // Create a SR for the volume UUID folder
+                secondaryStorage = createFileSr(conn, uri.getHost() + ":" + uri.getPath(), destVolume.getPath());
+                // Look up the volume on the source primary storage pool
+                VDI srcVdi = getVDIbyUuid(conn, srcVolume.getPath());
+                // Copy the volume to secondary storage
+                Task task = srcVdi.copyAsync2(conn, secondaryStorage, null, null);
+                // poll every 1 seconds ,
+                hypervisorResource.waitForTask(conn, task, 1000, wait * 1000);
+                hypervisorResource.checkForSuccess(conn, task);
+                VDI destVdi = Types.toVDI(task, conn);
+                String destVolumeUUID = destVdi.getUuid(conn);
+
+                VolumeObjectTO newVol = new VolumeObjectTO();
+                newVol.setPath(destVolume.getPath() + File.separator + destVolumeUUID + ".vhd");
+                newVol.setSize(srcVolume.getSize());
+                return new CopyCmdAnswer(newVol);
+            } catch (Exception e) {
+                s_logger.debug("Failed to copy volume to secondary: " + e.toString());
+                return new CopyCmdAnswer("Failed to copy volume to secondary: " + e.toString());
+            } finally {
+                hypervisorResource.removeSR(conn, secondaryStorage);
+            }
+        }
+        return new CopyCmdAnswer("unsupported protocol");
+    }
+
+    @Override
+    public Answer copyVolumeFromImageCacheToPrimary(CopyCommand cmd) {
+        Connection conn = hypervisorResource.getConnection();
+        DataTO srcData = cmd.getSrcTO();
+        DataTO destData = cmd.getDestTO();
+        int wait = cmd.getWait();
+        VolumeObjectTO srcVolume = (VolumeObjectTO)srcData;
+        VolumeObjectTO destVolume = (VolumeObjectTO)destData;
+        PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)destVolume.getDataStore();
+        DataStoreTO srcStore = srcVolume.getDataStore();
+
+        if (srcStore instanceof NfsTO) {
+            NfsTO nfsStore = (NfsTO)srcStore;
+            String volumePath = srcVolume.getPath();
+            int index = volumePath.lastIndexOf("/");
+            String volumeDirectory = volumePath.substring(0, index);
+            String volumeUuid = volumePath.substring(index + 1);
+            index = volumeUuid.indexOf(".");
+            if (index != -1) {
+                volumeUuid = volumeUuid.substring(0, index);
+            }
+            URI uri = null;
+            try {
+                uri = new URI(nfsStore.getUrl());
+            } catch (Exception e) {
+                return new CopyCmdAnswer(e.toString());
+            }
+            SR srcSr = createFileSr(conn, uri.getHost() + ":" + uri.getPath(), volumeDirectory);
+            try {
+                SR primaryStoragePool = hypervisorResource.getStorageRepository(conn, primaryStore.getUuid());
+                VDI srcVdi = VDI.getByUuid(conn, volumeUuid);
+                Task task = srcVdi.copyAsync2(conn, primaryStoragePool, null, null);
+                // poll every 1 seconds ,
+                hypervisorResource.waitForTask(conn, task, 1000, wait * 1000);
+                hypervisorResource.checkForSuccess(conn, task);
+                VDI destVdi = Types.toVDI(task, conn);
+                VolumeObjectTO newVol = new VolumeObjectTO();
+                newVol.setPath(destVdi.getUuid(conn));
+                newVol.setSize(srcVolume.getSize());
+
+                return new CopyCmdAnswer(newVol);
+            } catch (Exception e) {
+                String msg = "Catch Exception " + e.getClass().getName() + " due to " + e.toString();
+                s_logger.warn(msg, e);
+                return new CopyCmdAnswer(e.toString());
+            } finally {
+                if (srcSr != null) {
+                    hypervisorResource.removeSR(conn, srcSr);
+                }
+            }
+        }
+
+        s_logger.debug("unsupported protocol");
+        return new CopyCmdAnswer("unsupported protocol");
+    }
+
+    @Override
+    public Answer createTemplateFromSnapshot(CopyCommand cmd) {
+        Connection conn = hypervisorResource.getConnection();
+        DataTO srcData = cmd.getSrcTO();
+        DataTO destData = cmd.getDestTO();
+        int wait = cmd.getWait();
+        SnapshotObjectTO srcObj = (SnapshotObjectTO)srcData;
+        TemplateObjectTO destObj = (TemplateObjectTO)destData;
+        NfsTO srcStore = (NfsTO)srcObj.getDataStore();
+        NfsTO destStore = (NfsTO)destObj.getDataStore();
+
+        URI srcUri = null;
+        URI destUri = null;
+        try {
+            srcUri = new URI(srcStore.getUrl());
+            destUri = new URI(destStore.getUrl());
+        } catch (Exception e) {
+            s_logger.debug("incorrect url", e);
+            return new CopyCmdAnswer("incorrect url" + e.toString());
+        }
+
+        String srcPath = srcObj.getPath();
+        int index = srcPath.lastIndexOf("/");
+        String srcDir = srcPath.substring(0, index);
+        String destDir = destObj.getPath();
+        SR srcSr = null;
+        SR destSr = null;
+        VDI destVdi = null;
+        boolean result = false;
+        try {
+            srcSr = createFileSr(conn, srcUri.getHost() + ":" + srcUri.getPath(), srcDir);
+
+            String destNfsPath = destUri.getHost() + ":" + destUri.getPath();
+            String localDir = "/var/cloud_mount/" + UUID.nameUUIDFromBytes(destNfsPath.getBytes());
+            mountNfs(conn, destUri.getHost() + ":" + destUri.getPath(), localDir);
+            makeDirectory(conn, localDir + "/" + destDir);
+            destSr = createFileSR(conn, localDir + "/" + destDir);
+
+            String nameLabel = "cloud-" + UUID.randomUUID().toString();
+
+            String[] parents = srcObj.getParents();
+            List<VDI> snapshotChains = new ArrayList<VDI>();
+            if (parents != null) {
+                for(int i = 0; i < parents.length; i++) {
+                    String snChainPath = parents[i];
+                    String uuid = getSnapshotUuid(snChainPath);
+                    VDI chain = VDI.getByUuid(conn, uuid);
+                    snapshotChains.add(chain);
+                }
+            }
+            String snapshotUuid = getSnapshotUuid(srcPath);
+            VDI snapshotVdi = VDI.getByUuid(conn, snapshotUuid);
+            snapshotChains.add(snapshotVdi);
+
+            long templateVirtualSize = snapshotChains.get(0).getVirtualSize(conn);
+            destVdi = createVdi(conn, nameLabel, destSr, templateVirtualSize);
+            String destVdiUuid = destVdi.getUuid(conn);
+
+            for(VDI snapChain : snapshotChains) {
+                Task task = snapChain.copyAsync2(conn, null, null, destVdi);
+                // poll every 1 seconds ,
+                hypervisorResource.waitForTask(conn, task, 1000, wait * 1000);
+                hypervisorResource.checkForSuccess(conn, task);
+            }
+
+            destVdi = VDI.getByUuid(conn, destVdiUuid);
+            String templatePath = destDir + "/" + destVdiUuid + ".vhd";
+            templatePath = templatePath.replaceAll("//","/");
+            TemplateObjectTO newTemplate = new TemplateObjectTO();
+            newTemplate.setPath(templatePath);
+            newTemplate.setFormat(Storage.ImageFormat.VHD);
+            newTemplate.setSize(destVdi.getVirtualSize(conn));
+            newTemplate.setPhysicalSize(destVdi.getPhysicalUtilisation(conn));
+            newTemplate.setName(destVdiUuid);
+
+            result = true;
+            return new CopyCmdAnswer(newTemplate);
+        } catch (Exception e) {
+            s_logger.error("Failed create template from snapshot", e);
+            return new CopyCmdAnswer("Failed create template from snapshot " + e.toString());
+        } finally {
+            if (!result) {
+                if (destVdi != null) {
+                    try {
+                        destVdi.destroy(conn);
+                    } catch (Exception e) {
+                        s_logger.debug("Clean up left over on dest storage failed: ", e);
+                    }
+                }
+            }
+
+            if (destSr != null) {
+                hypervisorResource.removeSR(conn, destSr);
+            }
+
+            if (srcSr != null) {
+                hypervisorResource.removeSR(conn, srcSr);
+            }
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8caf52c6/plugins/hypervisors/xen/src/org/apache/cloudstack/hypervisor/xenserver/XenServerResourceNewBase.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xen/src/org/apache/cloudstack/hypervisor/xenserver/XenServerResourceNewBase.java b/plugins/hypervisors/xen/src/org/apache/cloudstack/hypervisor/xenserver/XenServerResourceNewBase.java
new file mode 100644
index 0000000..2ee45a3
--- /dev/null
+++ b/plugins/hypervisors/xen/src/org/apache/cloudstack/hypervisor/xenserver/XenServerResourceNewBase.java
@@ -0,0 +1,340 @@
+// 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.hypervisor.xenserver;
+
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeoutException;
+
+import org.apache.log4j.Logger;
+import org.apache.xmlrpc.XmlRpcException;
+
+import com.xensource.xenapi.Connection;
+import com.xensource.xenapi.Event;
+import com.xensource.xenapi.Host;
+import com.xensource.xenapi.Pool;
+import com.xensource.xenapi.Task;
+import com.xensource.xenapi.Types;
+import com.xensource.xenapi.Types.XenAPIException;
+import com.xensource.xenapi.VM;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.ClusterSyncAnswer;
+import com.cloud.agent.api.ClusterSyncCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.hypervisor.xen.resource.XenServer610Resource;
+import com.cloud.utils.Ternary;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachineName;
+
+/**
+ * 
+ * XenServerResourceNewBase is an abstract base class that encapsulates how
+ * CloudStack should interact with XenServer after a special XenServer
+ * 6.2 hotfix.  From here on, every Resource for future versions of
+ * XenServer should use this as the base class.  This base class lessens
+ * the amount of load CloudStack places on Xapi because it doesn't use
+ * polling as a means to collect data and figure out task completion.
+ * 
+ * This base class differs from CitrixResourceBase in the following ways:
+ *   - VM states are detected using Event.from instead of polling.  This
+ *     increases the number of threads CloudStack uses but the threads
+ *     are mostly idle just waiting for events from XenServer.
+ *   - stats are collected through the http interface rather than Xapi plugin.
+ *     This change may be promoted to CitrixResourceBase as it's also possible
+ *     in previous versions of XenServer.
+ *   - Asynchronous task completion is done throught Event.from rather than
+ *     polling.
+ *
+ */
+public class XenServerResourceNewBase extends XenServer610Resource {
+    private static final Logger s_logger = Logger.getLogger(XenServerResourceNewBase.class);
+    protected VmEventListener _listener = null;
+
+    @Override
+    public StartupCommand[] initialize() throws IllegalArgumentException {
+        StartupCommand[] cmds = super.initialize();
+
+        Connection conn = getConnection();
+        Pool pool;
+        try {
+            pool = Pool.getByUuid(conn, _host.pool);
+            Pool.Record poolr = pool.getRecord(conn);
+
+            Host.Record masterRecord = poolr.master.getRecord(conn);
+            if (_host.uuid.equals(masterRecord.uuid)) {
+                _listener = new VmEventListener(true);
+                _listener.start();
+            } else {
+                _listener = new VmEventListener(false);
+            }
+        } catch (XenAPIException e) {
+            throw new CloudRuntimeException("Unable to determine who is the master", e);
+        } catch (XmlRpcException e) {
+            throw new CloudRuntimeException("Unable to determine who is the master", e);
+        }
+        return cmds;
+    }
+
+    protected void waitForTask2(Connection c, Task task, long pollInterval, long timeout) throws XenAPIException, XmlRpcException, TimeoutException {
+        long beginTime = System.currentTimeMillis();
+        if (s_logger.isTraceEnabled()) {
+            s_logger.trace("Task " + task.getNameLabel(c) + " (" + task.getType(c) + ") sent to " + c.getSessionReference() + " is pending completion with a " + timeout +
+                           "ms timeout");
+        }
+        Set<String> classes = new HashSet<String>();
+        classes.add("Task/" + task.toString());
+        String token = "";
+        Double t = new Double(timeout / 1000);
+        while (true) {
+            Map<?, ?> map = Event.properFrom(c, classes, token, t);
+            token = (String)map.get("token");
+            @SuppressWarnings("unchecked")
+            Set<Event.Record> events = (Set<Event.Record>)map.get("events");
+            if (events.size() == 0) {
+                String msg = "Async " + timeout / 1000 + " seconds timeout for task " + task.toString();
+                s_logger.warn(msg);
+                task.cancel(c);
+                throw new TimeoutException(msg);
+            }
+            for (Event.Record rec : events) {
+                if (!(rec.snapshot instanceof Task.Record)) {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Skipping over " + rec);
+                    }
+                    continue;
+                }
+
+                Task.Record taskRecord = (Task.Record)rec.snapshot;
+
+                if (taskRecord.status != Types.TaskStatusType.PENDING) {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Task is done " + taskRecord.status);
+                    }
+                    return;
+                } else {
+                    s_logger.debug("Task is not done " + taskRecord);
+                }
+            }
+        }
+    }
+
+    @Override
+    protected Answer execute(final ClusterSyncCommand cmd) {
+        if (!_listener.isListening()) {
+            return new Answer(cmd);
+        }
+
+        HashMap<String, Ternary<String, VirtualMachine.State, String>> newStates = _listener.getChanges();
+        return new ClusterSyncAnswer(cmd.getClusterId(), newStates);
+    }
+
+    protected class VmEventListener extends Thread {
+        boolean _stop = false;
+        HashMap<String, Ternary<String, VirtualMachine.State, String>> _changes = new HashMap<String, Ternary<String, VirtualMachine.State, String>>();
+        boolean _isMaster;
+        Set<String> _classes;
+        String _token = "";
+
+        public VmEventListener(boolean isMaster) {
+            _isMaster = isMaster;
+            _classes = new HashSet<String>();
+            _classes.add("VM");
+        }
+
+        @Override
+        public void run() {
+            setName("XS-Listener-" + _host.ip);
+            while (!_stop) {
+                try {
+                    Connection conn = getConnection();
+                    Map<?, ?> results;
+                    try {
+                        results = Event.properFrom(conn, _classes, _token, new Double(30));
+                    } catch (Exception e) {
+                        s_logger.error("Retrying the waiting on VM events due to: ", e);
+                        continue;
+                    }
+
+                    _token = (String)results.get("token");
+                    @SuppressWarnings("unchecked")
+                    Set<Event.Record> events = (Set<Event.Record>)results.get("events");
+                    for (Event.Record event : events) {
+                        try {
+                            if (!(event.snapshot instanceof VM.Record)) {
+                                if (s_logger.isDebugEnabled()) {
+                                    s_logger.debug("The snapshot is not a VM: " + event);
+                                }
+                                continue;
+                            }
+                            VM.Record vm = (VM.Record)event.snapshot;
+
+                            String hostUuid = null;
+                            if (vm.residentOn != null && !vm.residentOn.toWireString().contains("OpaqueRef:NULL")) {
+                                hostUuid = vm.residentOn.getUuid(conn);
+                            }
+                            recordChanges(conn, vm, hostUuid);
+                        } catch (Exception e) {
+                            s_logger.error("Skipping over " + event, e);
+                        }
+                    }
+                } catch (Throwable th) {
+                    s_logger.error("Exception caught in eventlistener thread: ", th);
+                }
+            }
+        }
+
+        protected void recordChanges(Connection conn, VM.Record rec, String hostUuid) {
+            String vm = rec.nameLabel;
+            if (!VirtualMachineName.isValidCloudStackVmName(vm, _instance)) {
+                s_logger.debug("Skipping over VMs that does not conform to CloudStack naming convention: " + vm);
+                return;
+            }
+
+            VirtualMachine.State currentState = convertToState(rec.powerState);
+            if (vm.startsWith("migrating")) {
+                s_logger.warn("Skipping " + vm + " because it is migrating.");
+                return;
+            }
+
+            if (currentState == VirtualMachine.State.Stopped) {
+                if (s_logger.isTraceEnabled()) {
+                    s_logger.trace("Double check the power state to make sure we got the correct state for " + vm);
+                }
+                currentState = getRealPowerState(conn, vm);
+            }
+
+            boolean updateMap = false;
+            boolean reportChange = false;
+
+            // NOTE: For now we only record change when the VM is stopped.  We don't find out any VMs starting for now.
+            synchronized (_cluster.intern()) {
+                Ternary<String, VirtualMachine.State, String> oldState = s_vms.get(_cluster, vm);
+                if (oldState == null) {
+                    if (s_logger.isTraceEnabled()) {
+                        s_logger.trace("Unable to find " + vm + " from previous map.  Assuming it was in Stopped state.");
+                    }
+                    oldState = new Ternary<String, VirtualMachine.State, String>(null, VirtualMachine.State.Stopped, null);
+                }
+
+                if (s_logger.isTraceEnabled()) {
+                    s_logger.trace(vm + ": current state=" + currentState + ", previous state=" + oldState);
+                }
+
+                if (oldState.second() == VirtualMachine.State.Starting) {
+                    if (currentState == VirtualMachine.State.Running) {
+                        updateMap = true;
+                        reportChange = false;
+                    } else if (currentState == VirtualMachine.State.Stopped) {
+                        updateMap = false;
+                        reportChange = false;
+                    }
+                } else if (oldState.second() == VirtualMachine.State.Migrating) {
+                    updateMap = true;
+                    reportChange = false;
+                } else if (oldState.second() == VirtualMachine.State.Stopping) {
+                    if (currentState == VirtualMachine.State.Stopped) {
+                        updateMap = true;
+                        reportChange = false;
+                    } else if (currentState == VirtualMachine.State.Running) {
+                        updateMap = false;
+                        reportChange = false;
+                    }
+                } else if (oldState.second() != currentState) {
+                    updateMap = true;
+                    reportChange = true;
+                } else if (hostUuid != null && !hostUuid.equals(oldState.first())) {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Detecting " + vm + " moved from " + oldState.first() + " to " + hostUuid);
+                    }
+                    reportChange = true;
+                    updateMap = true;
+                }
+
+                if (updateMap) {
+                    s_vms.put(_cluster, hostUuid, vm, currentState);
+                    if (s_logger.isTraceEnabled()) {
+                        s_logger.trace("Updated " + vm + " to [" + hostUuid + ", " + currentState);
+                    }
+                }
+                if (reportChange) {
+                    Ternary<String, VirtualMachine.State, String> change = _changes.get(vm);
+                    if (hostUuid == null) {
+                        // This is really strange code.  It looks like the sync
+                        // code wants this to be set, which is extremely weird
+                        // for VMs that are dead.  Why would I want to set the
+                        // hostUuid if the VM is stopped.
+                        hostUuid = oldState.first();
+                        if (hostUuid == null) {
+                            hostUuid = _host.uuid;
+                        }
+                    }
+                    if (change == null) {
+                        change = new Ternary<String, VirtualMachine.State, String>(hostUuid, currentState, null);
+                    } else {
+                        change.first(hostUuid);
+                        change.second(currentState);
+                    }
+                    _changes.put(vm, change);
+                }
+            }
+        }
+
+        @Override
+        public void start() {
+            if (_isMaster) {
+                // Throw away the initial set of events because they're history
+                Connection conn = getConnection();
+                Map<?, ?> results;
+                try {
+                    results = Event.properFrom(conn, _classes, _token, new Double(30));
+                } catch (Exception e) {
+                    s_logger.error("Retrying the waiting on VM events due to: ", e);
+                    throw new CloudRuntimeException("Unable to start a listener thread to listen to VM events", e);
+                }
+                _token = (String)results.get("token");
+                s_logger.debug("Starting the event listener thread for " + _host.uuid);
+                super.start();
+            }
+        }
+
+        public boolean isListening() {
+            return _isMaster;
+        }
+
+        public HashMap<String, Ternary<String, VirtualMachine.State, String>> getChanges() {
+            synchronized (_cluster.intern()) {
+                if (_changes.size() == 0) {
+                    return null;
+                }
+                HashMap<String, Ternary<String, VirtualMachine.State, String>> diff = _changes;
+                _changes = new HashMap<String, Ternary<String, VirtualMachine.State, String>>();
+                return diff;
+            }
+        }
+
+        public void signalStop() {
+            _stop = true;
+            interrupt();
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8caf52c6/scripts/vm/hypervisor/xenserver/xenserver62/cloud-plugin-storage
----------------------------------------------------------------------
diff --git a/scripts/vm/hypervisor/xenserver/xenserver62/cloud-plugin-storage b/scripts/vm/hypervisor/xenserver/xenserver62/cloud-plugin-storage
new file mode 100644
index 0000000..03a05b7
--- /dev/null
+++ b/scripts/vm/hypervisor/xenserver/xenserver62/cloud-plugin-storage
@@ -0,0 +1,301 @@
+#!/usr/bin/python
+# 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.
+
+# Version @VERSION@
+#
+# A plugin for executing script needed by vmops cloud 
+
+import os, sys, time
+import XenAPIPlugin
+if os.path.exists("/opt/xensource/sm"):
+    sys.path.extend(["/opt/xensource/sm/", "/usr/local/sbin/", "/sbin/"])
+if os.path.exists("/usr/lib/xcp/sm"):
+    sys.path.extend(["/usr/lib/xcp/sm/", "/usr/local/sbin/", "/sbin/"])
+
+import SR, VDI, SRCommand, util, lvutil
+from util import CommandException
+import vhdutil
+import shutil
+import lvhdutil
+import errno
+import subprocess
+import xs_errors
+import cleanup
+import stat
+import random
+import cloudstack_pluginlib as lib
+import logging
+
+lib.setup_logging("/var/log/cloud/vmops.log")
+
+VHDUTIL = "vhd-util"
+VHD_PREFIX = 'VHD-'
+CLOUD_DIR = '/var/run/cloud_mount'
+
+def echo(fn):
+    def wrapped(*v, **k):
+        name = fn.__name__
+        logging.debug("#### VMOPS enter  %s ####" % name )
+        res = fn(*v, **k)
+        logging.debug("#### VMOPS exit  %s ####" % name )
+        return res
+    return wrapped
+
+def getPrimarySRPath(primaryStorageSRUuid, isISCSI):
+    if isISCSI:
+        primarySRDir = lvhdutil.VG_PREFIX + primaryStorageSRUuid
+        return os.path.join(lvhdutil.VG_LOCATION, primarySRDir)
+    else:
+        return os.path.join(SR.MOUNT_BASE, primaryStorageSRUuid)
+
+def getBackupVHD(UUID):
+    return UUID + '.' + SR.DEFAULT_TAP
+
+def getVHD(UUID, isISCSI):
+    if isISCSI:
+        return VHD_PREFIX + UUID
+    else:
+        return UUID + '.' + SR.DEFAULT_TAP
+
+def getIsTrueString(stringValue):
+    booleanValue = False
+    if (stringValue and stringValue == 'true'):
+        booleanValue = True
+    return booleanValue
+
+def makeUnavailable(uuid, primarySRPath, isISCSI):
+    if not isISCSI:
+        return
+    VHD = getVHD(uuid, isISCSI)
+    path = os.path.join(primarySRPath, VHD)
+    manageAvailability(path, '-an')
+    return
+
+def manageAvailability(path, value):
+    if path.__contains__("/var/run/sr-mount"):
+        return
+    logging.debug("Setting availability of " + path + " to " + value)
+    try:
+        cmd = ['/usr/sbin/lvchange', value, path]
+        util.pread2(cmd)
+    except: #CommandException, (rc, cmdListStr, stderr):
+        #errMsg = "CommandException thrown while executing: " + cmdListStr + " with return code: " + str(rc) + " and stderr: " + stderr
+        errMsg = "Unexpected exception thrown by lvchange"
+        logging.debug(errMsg)
+        if value == "-ay":
+            # Raise an error only if we are trying to make it available.
+            # Just warn if we are trying to make it unavailable after the
+            # snapshot operation is done.
+            raise xs_errors.XenError(errMsg)
+    return
+
+
+def checkVolumeAvailablility(path):
+    try:
+        if not isVolumeAvailable(path):
+            # The VHD file is not available on XenSever. The volume is probably
+            # inactive or detached.
+            # Do lvchange -ay to make it available on XenServer
+            manageAvailability(path, '-ay')
+    except:
+        errMsg = "Could not determine status of ISCSI path: " + path
+        logging.debug(errMsg)
+        raise xs_errors.XenError(errMsg)
+
+    success = False
+    i = 0
+    while i < 6:
+        i = i + 1
+        # Check if the vhd is actually visible by checking for the link
+        # set isISCSI to true
+        success = isVolumeAvailable(path)
+        if success:
+            logging.debug("Made vhd: " + path + " available and confirmed that it is visible")
+            break
+
+        # Sleep for 10 seconds before checking again.
+        time.sleep(10)
+
+    # If not visible within 1 min fail
+    if not success:
+        logging.debug("Could not make vhd: " +  path + " available despite waiting for 1 minute. Does it exist?")
+
+    return success
+
+def isVolumeAvailable(path):
+    # Check if iscsi volume is available on this XenServer.
+    status = "0"
+    try:
+        p = subprocess.Popen(["/bin/bash", "-c", "if [ -L " + path + " ]; then echo 1; else echo 0;fi"], stdout=subprocess.PIPE)
+        status = p.communicate()[0].strip("\n")
+    except:
+        errMsg = "Could not determine status of ISCSI path: " + path
+        logging.debug(errMsg)
+        raise xs_errors.XenError(errMsg)
+
+    return (status == "1")
+
+def scanParent(path):
+    # Do a scan for the parent for ISCSI volumes
+    # Note that the parent need not be visible on the XenServer
+    parentUUID = ''
+    try:
+        lvName = os.path.basename(path)
+        dirname = os.path.dirname(path)
+        vgName = os.path.basename(dirname)
+        vhdInfo = vhdutil.getVHDInfoLVM(lvName, lvhdutil.extractUuid, vgName)
+        parentUUID = vhdInfo.parentUuid
+    except:
+        errMsg = "Could not get vhd parent of " + path
+        logging.debug(errMsg)
+        raise xs_errors.XenError(errMsg)
+    return parentUUID
+
+def getParentOfSnapshot(snapshotUuid, primarySRPath, isISCSI):
+    snapshotVHD    = getVHD(snapshotUuid, isISCSI)
+    snapshotPath   = os.path.join(primarySRPath, snapshotVHD)
+
+    baseCopyUuid = ''
+    if isISCSI:
+        checkVolumeAvailablility(snapshotPath)
+        baseCopyUuid = scanParent(snapshotPath)
+    else:
+        baseCopyUuid = getParent(snapshotPath, isISCSI)
+
+    logging.debug("Base copy of snapshotUuid: " + snapshotUuid + " is " + baseCopyUuid)
+    return baseCopyUuid
+
+def getParent(path, isISCSI):
+    parentUUID = ''
+    try :
+        if isISCSI:
+            parentUUID = vhdutil.getParent(path, lvhdutil.extractUuid)
+        else:
+            parentUUID = vhdutil.getParent(path, cleanup.FileVDI.extractUuid)
+    except:
+        errMsg = "Could not get vhd parent of " + path
+        logging.debug(errMsg)
+        raise xs_errors.XenError(errMsg)
+    return parentUUID
+
+def getVhdParent(session, args):
+    logging.debug("getParent with " + str(args))
+    try:
+        primaryStorageSRUuid      = args['primaryStorageSRUuid']
+        snapshotUuid              = args['snapshotUuid']
+        isISCSI                   = getIsTrueString(args['isISCSI'])
+
+        primarySRPath = getPrimarySRPath(primaryStorageSRUuid, isISCSI)
+        logging.debug("primarySRPath: " + primarySRPath)
+
+        baseCopyUuid = getParentOfSnapshot(snapshotUuid, primarySRPath, isISCSI)
+
+        return  baseCopyUuid
+    except:
+        logging.debug('getVhdParent', exc_info=True)
+        raise xs_errors.XenError("Failed to getVhdParent")
+def makedirs(path):
+    if not os.path.isdir(path):
+        try:
+            os.makedirs(path)
+        except OSError, (errno, strerror):
+            umount(path)
+            if os.path.isdir(path):
+                return
+            errMsg = "OSError while creating " + path + " with errno: " + str(errno) + " and strerr: " + strerror
+            logging.debug(errMsg)
+            raise xs_errors.XenError(errMsg)
+    return
+
+def umount(localDir):
+    try:
+        cmd = ['umount', localDir]
+        util.pread2(cmd)
+    except CommandException:
+        errMsg = "CommandException raised while trying to umount " + localDir
+        logging.debug(errMsg)
+        raise xs_errors.XenError(errMsg)
+
+    logging.debug("Successfully unmounted " + localDir)
+    return
+
+@echo
+def mountNfsSecondaryStorage(session, args):
+    remoteDir = args['remoteDir']
+    localDir  = args['localDir']
+    mounted = False
+    f = open("/proc/mounts", 'r')
+    for line in f:
+        tokens = line.split(" ")
+        if len(tokens) > 2 and tokens[0] == remoteDir and tokens[1] == localDir:
+            mounted = True
+
+    if mounted:
+        return "true"
+
+    makedirs(localDir)
+    options = "soft,tcp,timeo=133,retrans=1"
+    try:
+        cmd = ['mount', '-o', options, remoteDir, localDir]
+        txt = util.pread2(cmd)
+    except:
+        txt = ''
+        errMsg = "Unexpected error while trying to mount " + remoteDir + " to " + localDir
+        logging.debug(errMsg)
+        raise xs_errors.XenError(errMsg)
+    logging.debug("Successfully mounted " + remoteDir + " to " + localDir)
+
+    return "true"
+
+@echo
+def umountNfsSecondaryStorage(session, args):
+    localDir = args['localDir']
+    try:
+        cmd = ['umount', localDir]
+        util.pread2(cmd)
+    except CommandException:
+        errMsg = "CommandException raised while trying to umount " + localDir
+        logging.debug(errMsg)
+        raise xs_errors.XenError(errMsg)
+    try:
+        os.system("rmdir " + localDir)
+    except:
+        pass
+    logging.debug("Successfully unmounted " + localDir)
+    return "true"
+
+@echo
+def makeDirectory(session, args):
+    path = args['path']
+    if not os.path.isdir(path):
+        try:
+            os.makedirs(path)
+        except OSError, (errno, strerror):
+            if os.path.isdir(path):
+                return "true"
+            errMsg = "OSError while creating " + path + " with errno: " + str(errno) + " and strerr: " + strerror
+            logging.debug(errMsg)
+            raise xs_errors.XenError(errMsg)
+    return "true"
+
+if __name__ == "__main__":
+    XenAPIPlugin.dispatch({"getVhdParent":getVhdParent, "mountNfsSecondaryStorage":mountNfsSecondaryStorage,
+        "umountNfsSecondaryStorage":umountNfsSecondaryStorage,
+        "makeDirectory":makeDirectory})
+    
+

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8caf52c6/scripts/vm/hypervisor/xenserver/xenserver62/patch
----------------------------------------------------------------------
diff --git a/scripts/vm/hypervisor/xenserver/xenserver62/patch b/scripts/vm/hypervisor/xenserver/xenserver62/patch
new file mode 100644
index 0000000..70b86b4
--- /dev/null
+++ b/scripts/vm/hypervisor/xenserver/xenserver62/patch
@@ -0,0 +1,74 @@
+# 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.
+
+# This file specifies the files that need
+# to be transferred over to the XenServer.
+# The format of this file is as follows:
+# [Name of file]=[source path],[file permission],[destination path]
+# [destination path] is required.
+# If [file permission] is missing, 755 is assumed.
+# If [source path] is missing, it looks in the same
+# directory as the patch file.
+# If [source path] starts with '/', then it is absolute path.
+# If [source path] starts with '~', then it is path relative to management server home directory.
+# If [source path] does not start with '/' or '~', then it is relative path to the location of the patch file. 
+vmops=..,0755,/etc/xapi.d/plugins
+vmopspremium=..,0755,/etc/xapi.d/plugins
+xen-ovs-vif-flows.rules=..,0644,/etc/udev/rules.d
+ovs-vif-flows.py=..,0755,/etc/xapi.d/plugins
+cloudstack_plugins.conf=..,0644,/etc/xensource
+cloudstack_pluginlib.py=..,0755,/etc/xapi.d/plugins
+ovstunnel=..,0755,/etc/xapi.d/plugins
+cloud-plugin-storage=,0755,/etc/xapi.d/plugins
+hostvmstats.py=..,0755,/opt/xensource/sm
+systemvm.iso=../../../../../vms,0644,/opt/xensource/packages/iso
+id_rsa.cloud=../../../systemvm,0600,/root/.ssh
+network_info.sh=..,0755,/opt/cloud/bin
+setupxenserver.sh=..,0755,/opt/cloud/bin
+make_migratable.sh=..,0755,/opt/cloud/bin
+createipAlias.sh=..,0755,/opt/cloud/bin
+deleteipAlias.sh=..,0755,/opt/cloud/bin
+setup_iscsi.sh=..,0755,/opt/cloud/bin
+pingtest.sh=../../..,0755,/opt/cloud/bin
+dhcp_entry.sh=../../../../network/domr/,0755,/opt/cloud/bin
+save_password_to_domr.sh=../../../../network/domr/,0755,/opt/cloud/bin
+call_firewall.sh=../../../../network/domr/,0755,/opt/cloud/bin
+call_loadbalancer.sh=../../../../network/domr/,0755,/opt/cloud/bin
+router_proxy.sh=../../../../network/domr/,0755,/opt/cloud/bin
+cloud-setup-bonding.sh=..,0755,/opt/cloud/bin
+kill_copy_process.sh=..,0755,/opt/cloud/bin
+setup_heartbeat_sr.sh=..,0755,/opt/cloud/bin
+setup_heartbeat_file.sh=..,0755,/opt/cloud/bin
+check_heartbeat.sh=..,0755,/opt/cloud/bin
+xenheartbeat.sh=..,0755,/opt/cloud/bin
+launch_hb.sh=..,0755,/opt/cloud/bin
+vhd-util=..,0755,/opt/cloud/bin
+upgrade_snapshot.sh=..,0755,/opt/cloud/bin
+cloud-clean-vlan.sh=..,0755,/opt/cloud/bin
+cloud-prepare-upgrade.sh=..,0755,/opt/cloud/bin
+bumpUpPriority.sh=../../../../network/domr/,0755,/opt/cloud/bin
+swift=..,0755,/opt/cloud/bin
+swiftxen=..,0755,/etc/xapi.d/plugins
+s3xen=..,0755,/etc/xapi.d/plugins
+add_to_vcpus_params_live.sh=..,0755,/opt/cloud/bin
+ovs-pvlan=..,0755,/etc/xapi.d/plugins
+ovs-pvlan-dhcp-host.sh=../../../network,0755,/opt/cloud/bin
+ovs-pvlan-vm.sh=../../../network,0755,/opt/cloud/bin
+ovs-pvlan-cleanup.sh=../../../network,0755,/opt/cloud/bin
+ovs-get-dhcp-iface.sh=..,0755,/opt/cloud/bin
+ovs-get-bridge.sh=..,0755,/opt/cloud/bin
+cloudlog=..,0644,/etc/logrotate.d

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8caf52c6/server/src/com/cloud/configuration/Config.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java
index 73f6897..0c58141 100755
--- a/server/src/com/cloud/configuration/Config.java
+++ b/server/src/com/cloud/configuration/Config.java
@@ -1109,6 +1109,13 @@ public enum Config {
             "xenserver61",
             "default Xen PV driver version for registered template, valid value:xenserver56,xenserver61 ",
             "xenserver56,xenserver61"),
+    XenServerHotFix("Advanced",
+            ManagementServer.class,
+            Boolean.class,
+            "xen.hotfix.enabled",
+            "false",
+            "Enable/Disable xenserver hot fix",
+            null),
 
     // VMware
     VmwareUseNexusVSwitch(


[04/10] git commit: updated refs/heads/master to 62bb5d8

Posted by ed...@apache.org.
Remove uncessary changes.


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

Branch: refs/heads/master
Commit: 336241be76cb22fddfc0d92fc59d99dab4facba3
Parents: 02ace34
Author: edison su <su...@gmail.com>
Authored: Tue Dec 3 13:16:10 2013 -0800
Committer: Edison Su <su...@gmail.com>
Committed: Thu Dec 19 13:35:37 2013 -0800

----------------------------------------------------------------------
 api/src/org/apache/cloudstack/api/ServerApiException.java | 5 -----
 1 file changed, 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/336241be/api/src/org/apache/cloudstack/api/ServerApiException.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/ServerApiException.java b/api/src/org/apache/cloudstack/api/ServerApiException.java
index a8bb2ed..825f64a 100644
--- a/api/src/org/apache/cloudstack/api/ServerApiException.java
+++ b/api/src/org/apache/cloudstack/api/ServerApiException.java
@@ -81,9 +81,4 @@ public class ServerApiException extends CloudRuntimeException {
     public void setDescription(String description) {
         _description = description;
     }
-
-    @Override
-    public String getMessage() {
-        return _description;
-    }
 }


[03/10] git commit: updated refs/heads/master to 62bb5d8

Posted by ed...@apache.org.
0001-Fixed-issue-with-DataStoreDrivers-not-being-able-to-


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

Branch: refs/heads/master
Commit: 02ace3442db96c78da53bd79d544b1ab511f2a29
Parents: 864c91b
Author: edison su <su...@gmail.com>
Authored: Tue Dec 3 13:12:36 2013 -0800
Committer: Edison Su <su...@gmail.com>
Committed: Thu Dec 19 13:35:21 2013 -0800

----------------------------------------------------------------------
 .../apache/cloudstack/api/ServerApiException.java  |  4 ++++
 .../src/com/cloud/storage/StorageManagerImpl.java  | 17 ++++++++---------
 2 files changed, 12 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/02ace344/api/src/org/apache/cloudstack/api/ServerApiException.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/ServerApiException.java b/api/src/org/apache/cloudstack/api/ServerApiException.java
index 81184e3..a8bb2ed 100644
--- a/api/src/org/apache/cloudstack/api/ServerApiException.java
+++ b/api/src/org/apache/cloudstack/api/ServerApiException.java
@@ -82,4 +82,8 @@ public class ServerApiException extends CloudRuntimeException {
         _description = description;
     }
 
+    @Override
+    public String getMessage() {
+        return _description;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/02ace344/server/src/com/cloud/storage/StorageManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java
index 831fac8..c7503b9 100755
--- a/server/src/com/cloud/storage/StorageManagerImpl.java
+++ b/server/src/com/cloud/storage/StorageManagerImpl.java
@@ -41,9 +41,6 @@ import javax.ejb.Local;
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
 import org.apache.cloudstack.api.command.admin.storage.AddImageStoreCmd;
 import org.apache.cloudstack.api.command.admin.storage.CancelPrimaryStorageMaintenanceCmd;
 import org.apache.cloudstack.api.command.admin.storage.CreateSecondaryStagingStoreCmd;
@@ -87,6 +84,8 @@ import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
 import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
 
 import com.cloud.agent.AgentManager;
 import com.cloud.agent.api.Answer;
@@ -658,12 +657,12 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
                 lifeCycle.attachZone(store, zoneScope, hypervisorType);
             }
         } catch (Exception e) {
-            s_logger.debug("Failed to add data store", e);
+            s_logger.debug("Failed to add data store: "+e.getMessage(), e);
             // clean up the db
             if (store != null) {
                 lifeCycle.deleteDataStore(store);
             }
-            throw new CloudRuntimeException("Failed to add data store", e);
+            throw new CloudRuntimeException("Failed to add data store: "+e.getMessage(), e);
         }
 
         return (PrimaryDataStoreInfo)dataStoreMgr.getDataStore(store.getId(), DataStoreRole.Primary);
@@ -1698,8 +1697,8 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
         try {
             store = lifeCycle.initialize(params);
         } catch (Exception e) {
-            s_logger.debug("Failed to add data store", e);
-            throw new CloudRuntimeException("Failed to add data store", e);
+            s_logger.debug("Failed to add data store: "+e.getMessage(), e);
+            throw new CloudRuntimeException("Failed to add data store: "+e.getMessage(), e);
         }
 
         if (((ImageStoreProvider)storeProvider).needDownloadSysTemplate()) {
@@ -1862,8 +1861,8 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
         try {
             store = lifeCycle.initialize(params);
         } catch (Exception e) {
-            s_logger.debug("Failed to add data store", e);
-            throw new CloudRuntimeException("Failed to add data store", e);
+            s_logger.debug("Failed to add data store: "+e.getMessage(), e);
+            throw new CloudRuntimeException("Failed to add data store: "+e.getMessage(), e);
         }
 
         return (ImageStore)_dataStoreMgr.getDataStore(store.getId(), DataStoreRole.ImageCache);