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:51 UTC
[08/10] git commit: updated refs/heads/master to 62bb5d8
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