Updated Branches:
  refs/heads/4.2 cd797d55b -> 2976d9c79

CLOUDSTACK-4802: Change VM start flow to better support VM snapshot on certian 
version of vSphere, (vSphere 5.0 Update 2). If we detect that VM has pending VM 
snapshot, we will fully honor VM disk info from vCenter, since in some version 
of vSphere (vSphere 5.0 U2) does not allow disk-editting when VM has pending 
snapshot.


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

Branch: refs/heads/4.2
Commit: 2976d9c7932ed160cf3205c06f4d82efdfa0f10a
Parents: cd797d5
Author: Kelven Yang <kelv...@gmail.com>
Authored: Fri Oct 4 15:59:08 2013 -0700
Committer: Kelven Yang <kelv...@gmail.com>
Committed: Fri Oct 4 16:03:01 2013 -0700

----------------------------------------------------------------------
 .../vmware/resource/VmwareResource.java         | 78 ++++++++++++--------
 .../hypervisor/vmware/mo/VirtualMachineMO.java  | 28 ++++++-
 2 files changed, 75 insertions(+), 31 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2976d9c7/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 de2eb9b..464fd20 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
@@ -2661,6 +2661,7 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
             DatacenterMO dcMo = new DatacenterMO(hyperHost.getContext(), 
hyperHost.getHyperHostDatacenter());
             VirtualMachineDiskInfoBuilder diskInfoBuilder = null;
             VirtualMachineMO vmMo = 
hyperHost.findVmOnHyperHost(vmInternalCSName);
+            boolean hasSnapshot = false;
             if (vmMo != null) {
                 s_logger.info("VM " + vmInternalCSName + " already exists, 
tear down devices for reconfiguration");
                 if (getVmState(vmMo) != State.Stopped)
@@ -2668,7 +2669,11 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
              
                 // retrieve disk information before we tear down
                 diskInfoBuilder = vmMo.getDiskInfoBuilder();
-                vmMo.tearDownDevices(new Class<?>[] { VirtualDisk.class, 
VirtualEthernetCard.class });
+                hasSnapshot = vmMo.hasSnapshot();
+                if(!hasSnapshot)
+                       vmMo.tearDownDevices(new Class<?>[] { 
VirtualDisk.class, VirtualEthernetCard.class });
+                else
+                       vmMo.tearDownDevices(new Class<?>[] { 
VirtualEthernetCard.class });
                 vmMo.ensureScsiDeviceController();
             } else {
                 ManagedObjectReference morDc = 
hyperHost.getHyperHostDatacenter();
@@ -2686,7 +2691,11 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
                         vmMo.safePowerOff(_shutdown_waitMs);
                     
                     diskInfoBuilder = vmMo.getDiskInfoBuilder();
-                    vmMo.tearDownDevices(new Class<?>[] { VirtualDisk.class, 
VirtualEthernetCard.class });
+                    hasSnapshot = vmMo.hasSnapshot();
+                    if(!hasSnapshot)
+                       vmMo.tearDownDevices(new Class<?>[] { 
VirtualDisk.class, VirtualEthernetCard.class });
+                    else
+                       vmMo.tearDownDevices(new Class<?>[] { 
VirtualEthernetCard.class });
                     vmMo.ensureScsiDeviceController();
                 } else {
                     Pair<ManagedObjectReference, DatastoreMO> 
rootDiskDataStoreDetails = null;
@@ -2840,37 +2849,45 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
             //
             DiskTO[] sortedDisks = sortVolumesByDeviceId(disks);
             for (DiskTO vol : sortedDisks) {
-                deviceConfigSpecArray[i] = new VirtualDeviceConfigSpec();
-
                 if (vol.getType() == Volume.Type.ISO)
                        continue;
-                
+            
                 VirtualMachineDiskInfo matchingExistingDisk = 
getMatchingExistingDisk(diskInfoBuilder, vol);
                 controllerKey = getDiskController(matchingExistingDisk, vol, 
vmSpec, ideControllerKey, scsiControllerKey);
 
-                VolumeObjectTO volumeTO = (VolumeObjectTO)vol.getData();
-                PrimaryDataStoreTO primaryStore = 
(PrimaryDataStoreTO)volumeTO.getDataStore();
-                Pair<ManagedObjectReference, DatastoreMO> volumeDsDetails = 
dataStoresDetails.get(primaryStore.getUuid());
-                assert (volumeDsDetails != null);
-                VirtualDevice device;
-                
-                String[] diskChain = syncDiskChain(dcMo, vmMo, vmSpec, 
-                       vol, matchingExistingDisk,
-                       dataStoresDetails);
-                if(controllerKey == scsiControllerKey && 
VmwareHelper.isReservedScsiDeviceNumber(scsiUnitNumber))
-                       scsiUnitNumber++;
-                device = VmwareHelper.prepareDiskDevice(vmMo, null, 
controllerKey, 
-                       diskChain, 
-                       volumeDsDetails.first(),
-                    (controllerKey == ideControllerKey) ? ideUnitNumber++ : 
scsiUnitNumber++, i + 1);
-                
-                deviceConfigSpecArray[i].setDevice(device);
-               
deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.ADD);
-
-                if(s_logger.isDebugEnabled())
-                    s_logger.debug("Prepare volume at new device " + 
_gson.toJson(device));
-
-                i++;
+                if(!hasSnapshot) {
+                    deviceConfigSpecArray[i] = new VirtualDeviceConfigSpec();
+                    
+                       VolumeObjectTO volumeTO = (VolumeObjectTO)vol.getData();
+                       PrimaryDataStoreTO primaryStore = 
(PrimaryDataStoreTO)volumeTO.getDataStore();
+                       Pair<ManagedObjectReference, DatastoreMO> 
volumeDsDetails = dataStoresDetails.get(primaryStore.getUuid());
+                       assert (volumeDsDetails != null);
+                       
+                       String[] diskChain = syncDiskChain(dcMo, vmMo, vmSpec, 
+                               vol, matchingExistingDisk,
+                               dataStoresDetails);
+                       if(controllerKey == scsiControllerKey && 
VmwareHelper.isReservedScsiDeviceNumber(scsiUnitNumber))
+                               scsiUnitNumber++;
+                       VirtualDevice device = 
VmwareHelper.prepareDiskDevice(vmMo, null, controllerKey, 
+                               diskChain, 
+                               volumeDsDetails.first(),
+                           (controllerKey == ideControllerKey) ? 
ideUnitNumber++ : scsiUnitNumber++, i + 1);
+                       
+                       deviceConfigSpecArray[i].setDevice(device);
+                       
deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.ADD);
+       
+                       if(s_logger.isDebugEnabled())
+                           s_logger.debug("Prepare volume at new device " + 
_gson.toJson(device));
+       
+                       i++;
+                } else {
+                       if(controllerKey == scsiControllerKey && 
VmwareHelper.isReservedScsiDeviceNumber(scsiUnitNumber))
+                               scsiUnitNumber++;
+                       if(controllerKey == ideControllerKey) 
+                               ideUnitNumber++;
+                       else
+                               scsiUnitNumber++;
+                }
             }
 
             //
@@ -2917,7 +2934,8 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
                 nicCount++;
             }
 
-            
vmConfigSpec.getDeviceChange().addAll(Arrays.asList(deviceConfigSpecArray));
+            for(int j = 0; j < i; j++)
+               vmConfigSpec.getDeviceChange().add(deviceConfigSpecArray[j]);
 
             //
             // Setup VM options
@@ -5479,7 +5497,7 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
                         // tear down all devices first before we destroy the 
VM to avoid accidently delete disk backing files
                         if (getVmState(vmMo) != State.Stopped)
                             vmMo.safePowerOff(_shutdown_waitMs);
-                        vmMo.tearDownDevices(new Class<?>[] { 
VirtualDisk.class, VirtualEthernetCard.class });
+                        vmMo.tearDownDevices(new Class<?>[] { /* 
VirtualDisk.class, */ VirtualEthernetCard.class });
                         vmMo.destroy();
 
                         for (NetworkDetails netDetails : networks) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2976d9c7/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 abc5bf8..55cc8de 100644
--- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java
+++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java
@@ -577,6 +577,14 @@ public class VirtualMachineMO extends BaseMO {
                }
                return null;
        }
+       
+       public boolean hasSnapshot() throws Exception {
+               VirtualMachineSnapshotInfo info = getSnapshotInfo();
+               if(info != null) {
+                       return info.getCurrentSnapshot() != null;
+               }
+               return false;
+       }
 
        public boolean createFullClone(String cloneName, ManagedObjectReference 
morFolder, ManagedObjectReference morResourcePool,
                ManagedObjectReference morDs) throws Exception {
@@ -1629,6 +1637,7 @@ public class VirtualMachineMO extends BaseMO {
 
        public void tearDownDevices(Class<?>[] deviceClasses) throws Exception {
                VirtualDevice[] devices = getMatchedDevices(deviceClasses);
+
                if(devices.length > 0) {
                VirtualMachineConfigSpec vmConfigSpec = new 
VirtualMachineConfigSpec();
            VirtualDeviceConfigSpec[] deviceConfigSpecArray = new 
VirtualDeviceConfigSpec[devices.length];
@@ -1637,9 +1646,9 @@ public class VirtualMachineMO extends BaseMO {
                deviceConfigSpecArray[i] = new VirtualDeviceConfigSpec();
                deviceConfigSpecArray[i].setDevice(devices[i]);
                
deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.REMOVE);
+               vmConfigSpec.getDeviceChange().add(deviceConfigSpecArray[i]);
            }
 
-           
vmConfigSpec.getDeviceChange().addAll(Arrays.asList(deviceConfigSpecArray));
                if(!configureVm(vmConfigSpec)) {
                 throw new Exception("Failed to detach devices");
             }
@@ -2021,6 +2030,10 @@ public class VirtualMachineMO extends BaseMO {
            return detachedDiskFiles; 
        }
        
+       public List<VirtualDevice> getAllDeviceList() throws Exception {
+               return 
(List<VirtualDevice>)_context.getVimClient().getDynamicProperty(_mor, 
"config.hardware.device");
+       }
+       
        public VirtualDisk[] getAllDiskDevice() throws Exception {
                List<VirtualDisk> deviceList = new ArrayList<VirtualDisk>();
                List<VirtualDevice> devices = 
(List<VirtualDevice>)_context.getVimClient().getDynamicProperty(_mor, 
"config.hardware.device");
@@ -2034,6 +2047,19 @@ public class VirtualMachineMO extends BaseMO {
 
                return deviceList.toArray(new VirtualDisk[0]);
        }
+       
+       public VirtualDisk getDiskDeviceByBusName(List<VirtualDevice> 
allDevices, String busName) throws Exception {
+               for(VirtualDevice device : allDevices ) {
+                       if(device instanceof VirtualDisk) {
+                               VirtualDisk disk = (VirtualDisk)device;
+                               String diskBusName = 
getDeviceBusName(allDevices, (VirtualDevice)disk);
+                               if(busName.equalsIgnoreCase(diskBusName))
+                                       return disk;
+                       }
+               }
+               
+               return null;
+       }
 
        public VirtualDisk[] getAllIndependentDiskDevice() throws Exception {
                List<VirtualDisk> independentDisks = new 
ArrayList<VirtualDisk>();

Reply via email to