You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by mt...@apache.org on 2013/10/31 15:32:51 UTC
git commit: updated refs/heads/master to 449b5da
Updated Branches:
refs/heads/master a3cec3802 -> 449b5daa7
VMware changes related to managed storage
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/449b5daa
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/449b5daa
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/449b5daa
Branch: refs/heads/master
Commit: 449b5daa70f033128f014942e9dcbacd15b09181
Parents: a3cec38
Author: Mike Tutkowski <mi...@solidfire.com>
Authored: Thu Oct 31 08:27:30 2013 -0600
Committer: Mike Tutkowski <mi...@solidfire.com>
Committed: Thu Oct 31 08:30:50 2013 -0600
----------------------------------------------------------------------
.../vmware/manager/VmwareHostService.java | 3 +
.../vmware/resource/VmwareResource.java | 69 +++++++++++++++++---
.../VmwareSecondaryStorageResourceHandler.java | 4 ++
.../resource/VmwareStorageProcessor.java | 51 ++++++++++++++-
.../SolidFirePrimaryDataStoreLifeCycle.java | 2 +
.../com/cloud/storage/VolumeApiServiceImpl.java | 15 ++++-
.../hypervisor/vmware/mo/VirtualMachineMO.java | 16 ++++-
7 files changed, 147 insertions(+), 13 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/449b5daa/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareHostService.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareHostService.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareHostService.java
index d0147d1..d5a2284 100644
--- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareHostService.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareHostService.java
@@ -16,6 +16,8 @@
// under the License.
package com.cloud.hypervisor.vmware.manager;
+import java.util.List;
+
import com.cloud.agent.api.Command;
import com.cloud.hypervisor.vmware.mo.DatastoreMO;
import com.cloud.hypervisor.vmware.mo.VmwareHypervisorHost;
@@ -33,4 +35,5 @@ public interface VmwareHostService {
String iqn, String initiatorChapName, String initiatorChapSecret, String mutualChapName, String mutualChapSecret) throws Exception;
void createVmdk(Command cmd, DatastoreMO dsMo, String volumeDatastorePath, Long volumeSize) throws Exception;
void handleDatastoreAndVmdkDetach(String iqn, String storageHost, int storagePort) throws Exception;
+ void removeManagedTargetsFromCluster(List<String> managedIqns) throws Exception;
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/449b5daa/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
index 6d3d34a..a205fb6 100755
--- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
@@ -2985,7 +2985,9 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
VolumeObjectTO volumeTO = (VolumeObjectTO)vol.getData();
PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)volumeTO.getDataStore();
-
+ Map<String, String> details = vol.getDetails();
+ boolean isManaged = details != null && Boolean.parseBoolean(details.get(DiskTO.MANAGED));
+
Pair<ManagedObjectReference, DatastoreMO> volumeDsDetails = dataStoresDetails.get(primaryStore.getUuid());
if(volumeDsDetails == null)
throw new Exception("Primary datastore " + primaryStore.getUuid() + " is not mounted on host.");
@@ -2997,17 +2999,25 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
String disks[] = diskInfo.getDiskChain();
for(int i = 0; i < disks.length; i++) {
DatastoreFile file = new DatastoreFile(disks[i]);
- if(file.getDir() != null && file.getDir().isEmpty()) {
+ if (!isManaged && file.getDir() != null && file.getDir().isEmpty()) {
s_logger.info("Perform run-time datastore folder upgrade. sync " + disks[i] + " to VM folder");
disks[i] = VmwareStorageLayoutHelper.syncVolumeToVmDefaultFolder(
dcMo, vmMo.getName(), dsMo, file.getFileBaseName());
}
}
return disks;
- }
-
- String datastoreDiskPath = VmwareStorageLayoutHelper.syncVolumeToVmDefaultFolder(
- dcMo, vmMo.getName(), dsMo, volumeTO.getPath());
+ }
+
+ final String datastoreDiskPath;
+
+ if (isManaged) {
+ datastoreDiskPath = dsMo.getDatastorePath(dsMo.getName() + ".vmdk");
+ }
+ else {
+ datastoreDiskPath = VmwareStorageLayoutHelper.syncVolumeToVmDefaultFolder(
+ dcMo, vmMo.getName(), dsMo, volumeTO.getPath());
+ }
+
if(!dsMo.fileExists(datastoreDiskPath)) {
s_logger.warn("Volume " + volumeTO.getId() + " does not seem to exist on datastore, out of sync? path: " + datastoreDiskPath);
}
@@ -3223,7 +3233,10 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
if(diskInfoBuilder != null) {
VolumeObjectTO volume = (VolumeObjectTO)vol.getData();
- VirtualMachineDiskInfo diskInfo = diskInfoBuilder.getDiskInfoByBackingFileBaseName(volume.getPath());
+ Map<String, String> details = vol.getDetails();
+ boolean isManaged = details != null && Boolean.parseBoolean(details.get(DiskTO.MANAGED));
+
+ VirtualMachineDiskInfo diskInfo = diskInfoBuilder.getDiskInfoByBackingFileBaseName(isManaged ? new DatastoreFile(volume.getPath()).getFileBaseName() : volume.getPath());
if(diskInfo != null) {
s_logger.info("Found existing disk info from volume path: " + volume.getPath());
return diskInfo;
@@ -3421,7 +3434,16 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)volumeTO.getDataStore();
String poolUuid = primaryStore.getUuid();
if(poolMors.get(poolUuid) == null) {
- ManagedObjectReference morDataStore = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, poolUuid);
+ boolean isManaged = false;
+ String iScsiName = null;
+ Map<String, String> details = vol.getDetails();
+
+ if (details != null) {
+ isManaged = Boolean.parseBoolean(details.get(DiskTO.MANAGED));
+ iScsiName = details.get(DiskTO.IQN);
+ }
+
+ ManagedObjectReference morDataStore = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, isManaged ? VmwareResource.getDatastoreName(iScsiName) : poolUuid);
if (morDataStore == null) {
String msg = "Failed to get the mounted datastore for the volume's pool " + poolUuid;
s_logger.error(msg);
@@ -4534,7 +4556,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
String volumeDatastorePath = String.format("[%s] %s.vmdk", dsMo.getName(), dsMo.getName());
if (!dsMo.fileExists(volumeDatastorePath)) {
- createVmdk(cmd, dsMo, VmwareResource.getDatastoreName(cmd.get_iScsiName()), cmd.getVolumeSize());
+ createVmdk(cmd, dsMo, volumeDatastorePath, cmd.getVolumeSize());
}
}
else {
@@ -4592,6 +4614,35 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
}
}
+ @Override
+ public void removeManagedTargetsFromCluster(List<String> iqns) throws Exception {
+ List<HostInternetScsiHbaStaticTarget> lstManagedTargets = new ArrayList<HostInternetScsiHbaStaticTarget>();
+
+ VmwareContext context = getServiceContext();
+ VmwareHypervisorHost hyperHost = getHyperHost(context);
+ ManagedObjectReference morCluster = hyperHost.getHyperHostCluster();
+ ClusterMO cluster = new ClusterMO(context, morCluster);
+ List<Pair<ManagedObjectReference, String>> lstHosts = cluster.getClusterHosts();
+ HostMO host = new HostMO(context, lstHosts.get(0).first());
+ HostStorageSystemMO hostStorageSystem = host.getHostStorageSystemMO();
+
+ for (HostHostBusAdapter hba : hostStorageSystem.getStorageDeviceInfo().getHostBusAdapter()) {
+ if (hba instanceof HostInternetScsiHba) {
+ List<HostInternetScsiHbaStaticTarget> lstTargets = ((HostInternetScsiHba)hba).getConfiguredStaticTarget();
+
+ if (lstTargets != null) {
+ for (HostInternetScsiHbaStaticTarget target : lstTargets) {
+ if (iqns.contains(target.getIScsiName())) {
+ lstManagedTargets.add(target);
+ }
+ }
+ }
+ }
+ }
+
+ addRemoveInternetScsiTargetsToAllHosts(false, lstManagedTargets, lstHosts);
+ }
+
private void addRemoveInternetScsiTargetsToAllHosts(final boolean add, final List<HostInternetScsiHbaStaticTarget> lstTargets,
final List<Pair<ManagedObjectReference, String>> lstHosts) throws Exception {
VmwareContext context = getServiceContext();
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/449b5daa/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java
index c84813f..81f7bd9 100644
--- a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java
@@ -360,4 +360,8 @@ public class VmwareSecondaryStorageResourceHandler implements SecondaryStorageRe
public void handleDatastoreAndVmdkDetach(String iqn, String storageHost, int storagePort) throws Exception {
throw new OperationNotSupportedException();
}
+
+ public void removeManagedTargetsFromCluster(List<String> managedIqns) throws Exception {
+ throw new OperationNotSupportedException();
+ }
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/449b5daa/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java
index 71ba4e9..70a8769 100644
--- a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java
@@ -23,6 +23,7 @@ import java.io.OutputStreamWriter;
import java.net.URI;
import java.rmi.RemoteException;
import java.util.HashMap;
+import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@@ -79,6 +80,7 @@ import com.cloud.vm.VirtualMachine.State;
import com.google.gson.Gson;
import com.vmware.vim25.ManagedObjectReference;
import com.vmware.vim25.VirtualDisk;
+import com.vmware.vim25.VirtualDiskFlatVer2BackingInfo;
public class VmwareStorageProcessor implements StorageProcessor {
private static final Logger s_logger = Logger.getLogger(VmwareStorageProcessor.class);
@@ -1194,7 +1196,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
Map<String, String> details = disk.getDetails();
morDs = hostService.getVmfsDatastore(hyperHost, VmwareResource.getDatastoreName(iScsiName), storageHost, storagePort,
- VmwareResource.trimIqn(iScsiName), details.get(DiskTO.CHAP_INITIATOR_USERNAME), details.get(DiskTO.CHAP_INITIATOR_SECRET),
+ VmwareResource.trimIqn(iScsiName), details.get(DiskTO.CHAP_INITIATOR_USERNAME), details.get(DiskTO.CHAP_INITIATOR_SECRET),
details.get(DiskTO.CHAP_TARGET_USERNAME), details.get(DiskTO.CHAP_TARGET_SECRET));
DatastoreMO dsMo = new DatastoreMO(hostService.getServiceContext(null), morDs);
@@ -1202,7 +1204,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
String volumeDatastorePath = String.format("[%s] %s.vmdk", dsMo.getName(), dsMo.getName());
if (!dsMo.fileExists(volumeDatastorePath)) {
- hostService.createVmdk(cmd, dsMo, VmwareResource.getDatastoreName(iScsiName), volumeTO.getSize());
+ hostService.createVmdk(cmd, dsMo, volumeDatastorePath, volumeTO.getSize());
}
}
else {
@@ -1498,6 +1500,14 @@ public class VmwareStorageProcessor implements StorageProcessor {
vmMo.safePowerOff(_shutdown_waitMs);
}
+ // call this before calling detachAllDisksExcept
+ // when expunging a VM, we need to see if any of its disks are serviced by managed storage
+ // if there is one or more disk serviced by managed storage, remove the iSCSI connection(s)
+ // don't remove the iSCSI connection(s) until the supported disk(s) is/are removed from the VM
+ // (removeManagedTargetsFromCluster should be called after detachAllDisksExcept and vm.destroy)
+ List<VirtualDisk> virtualDisks = vmMo.getVirtualDisks();
+ List<String> managedIqns = getManagedIqnsFromVirtualDisks(virtualDisks);
+
List<String> detachedDisks = vmMo.detachAllDisksExcept(vol.getPath(), diskInfo != null ? diskInfo.getDiskDeviceBusName() : null);
VmwareStorageLayoutHelper.moveVolumeToRootFolder(new DatacenterMO(context, morDc), detachedDisks);
@@ -1505,6 +1515,9 @@ public class VmwareStorageProcessor implements StorageProcessor {
// vmMo.tearDownDevices(new Class<?>[] { VirtualDisk.class, VirtualEthernetCard.class });
vmMo.destroy();
+ // this.hostService.handleDatastoreAndVmdkDetach(iScsiName, storageHost, storagePort);
+ this.hostService.removeManagedTargetsFromCluster(managedIqns);
+
for (NetworkDetails netDetails : networks) {
if (netDetails.getGCTag() != null && netDetails.getGCTag().equalsIgnoreCase("true")) {
if (netDetails.getVMMorsOnNetwork() == null || netDetails.getVMMorsOnNetwork().length == 1) {
@@ -1555,6 +1568,40 @@ public class VmwareStorageProcessor implements StorageProcessor {
}
}
+ private List<String> getManagedIqnsFromVirtualDisks(List<VirtualDisk> virtualDisks) {
+ List<String> managedIqns = new ArrayList<String>();
+
+ if (virtualDisks != null) {
+ for (VirtualDisk virtualDisk : virtualDisks) {
+ if (virtualDisk.getBacking() instanceof VirtualDiskFlatVer2BackingInfo) {
+ VirtualDiskFlatVer2BackingInfo backingInfo = (VirtualDiskFlatVer2BackingInfo)virtualDisk.getBacking();
+ String path = backingInfo.getFileName();
+
+ path = new DatastoreFile(path).getFileBaseName();
+
+ String search = "-";
+ int index = path.indexOf(search);
+
+ if (index > -1) {
+ path = path.substring(index + search.length());
+
+ index = path.lastIndexOf(search);
+
+ if (index > -1) {
+ path = path.substring(0, index);
+
+ if (path.startsWith("iqn.")) {
+ managedIqns.add(path);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return managedIqns;
+ }
+
private Long restoreVolumeFromSecStorage(VmwareHypervisorHost hyperHost, DatastoreMO primaryDsMo, String newVolumeName,
String secStorageUrl, String secStorageDir, String backupName) throws Exception {
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/449b5daa/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/lifecycle/SolidFirePrimaryDataStoreLifeCycle.java
----------------------------------------------------------------------
diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/lifecycle/SolidFirePrimaryDataStoreLifeCycle.java b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/lifecycle/SolidFirePrimaryDataStoreLifeCycle.java
index 120a357..be43e1c 100644
--- a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/lifecycle/SolidFirePrimaryDataStoreLifeCycle.java
+++ b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/lifecycle/SolidFirePrimaryDataStoreLifeCycle.java
@@ -317,10 +317,12 @@ public class SolidFirePrimaryDataStoreLifeCycle implements PrimaryDataStoreLifeC
dataStoreHelper.attachZone(dataStore);
List<HostVO> xenServerHosts = _resourceMgr.listAllUpAndEnabledHostsInOneZoneByHypervisor(HypervisorType.XenServer, scope.getScopeId());
+ List<HostVO> vmWareServerHosts = _resourceMgr.listAllUpAndEnabledHostsInOneZoneByHypervisor(HypervisorType.VMware, scope.getScopeId());
List<HostVO> kvmHosts = _resourceMgr.listAllUpAndEnabledHostsInOneZoneByHypervisor(HypervisorType.KVM, scope.getScopeId());
List<HostVO> hosts = new ArrayList<HostVO>();
hosts.addAll(xenServerHosts);
+ hosts.addAll(vmWareServerHosts);
hosts.addAll(kvmHosts);
for (HostVO host : hosts) {
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/449b5daa/server/src/com/cloud/storage/VolumeApiServiceImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
index d445381..28df219 100644
--- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java
+++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
@@ -1233,6 +1233,19 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
String errorMsg = "Failed to detach volume: " + volume.getName() + " from VM: " + vm.getHostName();
boolean sendCommand = (vm.getState() == State.Running);
+
+ Long hostId = vm.getHostId();
+
+ if (hostId == null) {
+ hostId = vm.getLastHostId();
+
+ HostVO host = _hostDao.findById(hostId);
+
+ if (host != null && host.getHypervisorType() == HypervisorType.VMware) {
+ sendCommand = true;
+ }
+ }
+
Answer answer = null;
if (sendCommand) {
@@ -1251,7 +1264,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
cmd.set_iScsiName(volume.get_iScsiName());
try {
- answer = _agentMgr.send(vm.getHostId(), cmd);
+ answer = _agentMgr.send(hostId, cmd);
} catch (Exception e) {
throw new CloudRuntimeException(errorMsg + " due to: " + e.getMessage());
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/449b5daa/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java
----------------------------------------------------------------------
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java
index a9536cf..784c031 100644
--- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java
+++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java
@@ -1985,7 +1985,21 @@ public class VirtualMachineMO extends BaseMO {
}
throw new Exception("Unable to find device controller");
}
-
+
+ public List<VirtualDisk> getVirtualDisks() throws Exception {
+ List<VirtualDisk> virtualDisks = new ArrayList<VirtualDisk>();
+
+ List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
+
+ for (VirtualDevice device : devices) {
+ if (device instanceof VirtualDisk) {
+ virtualDisks.add((VirtualDisk)device);
+ }
+ }
+
+ return virtualDisks;
+ }
+
public List<String> detachAllDisksExcept(String vmdkBaseName, String deviceBusName) throws Exception {
List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");