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/19 03:23:17 UTC
[3/3] git commit: updated refs/heads/4.3 to 15403a1
add xenserver 6.2.0 hotfix support, to optimize vdi copy
add xenserver hot fix
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/15403a1f
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/15403a1f
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/15403a1f
Branch: refs/heads/4.3
Commit: 15403a1f294bec2f47bd44549594215074fb6c86
Parents: 3ce63be
Author: edison <su...@gmail.com>
Authored: Tue Dec 17 16:11:51 2013 -0800
Committer: Edison Su <su...@gmail.com>
Committed: Wed Dec 18 18:22:52 2013 -0800
----------------------------------------------------------------------
api/src/com/cloud/vm/VirtualMachineName.java | 13 +
core/src/com/cloud/host/HostInfo.java | 1 +
.../cloudstack/storage/command/CopyCommand.java | 12 +
.../cloudstack/storage/to/SnapshotObjectTO.java | 19 +-
.../src/com/xensource/xenapi/Event.java | 15 +
.../src/com/xensource/xenapi/Types.java | 50 ++
.../src/com/xensource/xenapi/VDI.java | 29 +-
.../subsystem/api/storage/EndPointSelector.java | 2 +
.../orchestration/VolumeOrchestrator.java | 8 +-
.../datastore/db/SnapshotDataStoreDao.java | 2 +
.../motion/AncientDataMotionStrategy.java | 16 +-
.../snapshot/XenserverSnapshotStrategy.java | 30 +-
.../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 | 810 +++---------------
.../xen/resource/XenServerPoolVms.java | 6 +-
.../xen/resource/XenServerStorageProcessor.java | 8 +-
.../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 | 1 +
25 files changed, 2105 insertions(+), 735 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/15403a1f/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 1279fd6..49cb40b 100755
--- a/api/src/com/cloud/vm/VirtualMachineName.java
+++ b/api/src/com/cloud/vm/VirtualMachineName.java
@@ -25,6 +25,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();
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/15403a1f/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 af929e3..3364e8f 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/15403a1f/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 e9ec0b3..a4ab070 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) {
@@ -67,4 +71,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/15403a1f/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 34e977c..55e34e4 100644
--- a/core/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java
+++ b/core/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java
@@ -16,13 +16,16 @@
// 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;
import com.cloud.agent.api.to.DataTO;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
public class SnapshotObjectTO implements DataTO {
private String path;
@@ -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")
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/15403a1f/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 3574cd1..e1273a5 100644
--- a/deps/XenServerJava/src/com/xensource/xenapi/Event.java
+++ b/deps/XenServerJava/src/com/xensource/xenapi/Event.java
@@ -301,4 +301,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/15403a1f/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 bde887a..36e38c1 100644
--- a/deps/XenServerJava/src/com/xensource/xenapi/Types.java
+++ b/deps/XenServerJava/src/com/xensource/xenapi/Types.java
@@ -1278,6 +1278,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();
@@ -7574,6 +7585,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/15403a1f/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 4ea9daf..167c5a0 100644
--- a/deps/XenServerJava/src/com/xensource/xenapi/VDI.java
+++ b/deps/XenServerJava/src/com/xensource/xenapi/VDI.java
@@ -1594,15 +1594,38 @@ 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
* @return Task
*/
public Task copyAsync(Connection c, SR sr) throws
- BadServerResponse,
- XenAPIException,
- XmlRpcException {
+ BadServerResponse,
+ XenAPIException,
+ XmlRpcException {
String method_call = "Async.VDI.copy";
String session = c.getSessionReference();
Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref), Marshalling.toXMLRPC(sr)};
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/15403a1f/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/15403a1f/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 41a3f29..ebd8709 100644
--- a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java
+++ b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java
@@ -424,10 +424,6 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
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);
@@ -435,6 +431,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/15403a1f/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 dfa03ad..666d2ce 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
@@ -50,4 +50,6 @@ StateDao<ObjectInDataStoreStateMachine.State, ObjectInDataStoreStateMachine.Even
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/15403a1f/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 8e65e80..1cd94ef 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;
@@ -481,6 +481,14 @@ AncientDataMotionStrategy implements DataMotionStrategy {
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)) {
@@ -489,6 +497,7 @@ 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?";
@@ -499,6 +508,7 @@ 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/15403a1f/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 b5a11d8..ae48fe4 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
@@ -21,10 +21,6 @@ import java.util.List;
import javax.inject.Inject;
-import com.cloud.storage.*;
-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;
@@ -40,8 +36,15 @@ import org.apache.cloudstack.storage.command.CreateObjectAnswer;
import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
import org.apache.cloudstack.storage.to.SnapshotObjectTO;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.storage.CreateSnapshotPayload;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.Snapshot;
+import com.cloud.storage.SnapshotVO;
+import com.cloud.storage.Volume;
import com.cloud.storage.dao.SnapshotDao;
import com.cloud.storage.snapshot.SnapshotManager;
import com.cloud.utils.NumbersUtil;
@@ -103,21 +106,16 @@ public class XenserverSnapshotStrategy extends SnapshotStrategyBase {
// determine full snapshot backup or not
- boolean fullBackup = false;
-
- if (parentSnapshot != null) {
+ 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) {
@@ -125,9 +123,15 @@ public class XenserverSnapshotStrategy extends SnapshotStrategyBase {
}
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/15403a1f/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 6155ae9..dd3bee1 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;
@@ -59,6 +60,7 @@ public class DefaultEndPointSelector implements EndPointSelector {
HostDao hostDao;
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/15403a1f/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 7b9cf95..dc85fd8 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
@@ -58,7 +58,10 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase<SnapshotDataStoreVO
" 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
@@ -190,6 +193,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/15403a1f/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 6dd6f3f..5ddde14 100644
--- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/XenServerGuru.java
+++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/XenServerGuru.java
@@ -19,16 +19,29 @@ 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();
@@ -59,4 +72,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/15403a1f/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 7174942..de4646f 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;
@Inject protected AgentManager _agentMgr;
@@ -143,6 +144,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 {
Map<CitrixResourceBase, Map<String, String>> resources = new HashMap<CitrixResourceBase, Map<String, String>>();
@@ -268,6 +274,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");
@@ -297,6 +305,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);
@@ -451,9 +460,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();
@@ -604,7 +625,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)) {