From c850f0a0e3749090fe5ed7d5c410bf10d06b2281 Mon Sep 17 00:00:00 2001 From: Vijayendra Bhamidipati Date: Tue, 13 Aug 2013 12:44:44 -0700 Subject: [PATCH] CLOUDSTACK-4139: [VMWARE][ZWPS] Failed to resize the volumes which are created from snapshot Description: Support offline volume resize on ESX by creating a worker VM to attach the unattached volume to and then resize it. --- .../vmware/resource/VmwareResource.java | 41 +++++++++++++++++-- .../com/cloud/storage/VolumeManagerImpl.java | 4 +- 2 files changed, 40 insertions(+), 5 deletions(-) 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 c6320f91362..2906c5aba96 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 @@ -610,11 +610,39 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa String path = cmd.getPath(); String vmName = cmd.getInstanceName(); long newSize = cmd.getNewSize()/1024; + boolean useWorkerVm = false; + + VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext()); + String poolId = cmd.getPoolUuid(); + VirtualMachineMO vmMo = null; + DatastoreMO dsMo = null; + ManagedObjectReference morDS = null; + String vmdkDataStorePath = null; + try { - VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext()); + if (vmName.equalsIgnoreCase("none")) { + // we need to spawn a worker VM to attach the volume to and + // resize the volume. + useWorkerVm = true; + vmName = this.getWorkerName(getServiceContext(), cmd, 0); + + morDS = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, poolId); + dsMo = new DatastoreMO(hyperHost.getContext(), morDS); + s_logger.info("Create worker VM " + vmName); + vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, vmName); + if (vmMo == null) { + throw new Exception("Unable to create a worker VM for volume resize"); + } + + synchronized (this) { + vmdkDataStorePath = VmwareStorageLayoutHelper.getLegacyDatastorePathFromVmdkFileName(dsMo, path + ".vmdk"); + vmMo.attachDisk(new String[] { vmdkDataStorePath }, morDS); + } + } + // find VM through datacenter (VM is not at the target host yet) - VirtualMachineMO vmMo = hyperHost.findVmOnPeerHyperHost(vmName); + vmMo = hyperHost.findVmOnPeerHyperHost(vmName); if (vmMo == null) { String msg = "VM " + vmName + " does not exist in VMware datacenter"; s_logger.error(msg); @@ -642,9 +670,16 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.EDIT); vmConfigSpec.getDeviceChange().add(deviceConfigSpec); if (!vmMo.configureVm(vmConfigSpec)) { + if (useWorkerVm == true) { + vmMo.detachDisk(vmdkDataStorePath, false); + vmMo.destroy(); + } throw new Exception("Failed to configure VM to resize disk. vmName: " + vmName); } - + if (useWorkerVm == true) { + vmMo.detachDisk(vmdkDataStorePath, false); + vmMo.destroy(); + } return new ResizeVolumeAnswer(cmd, true, "success", newSize*1024); } catch (Exception e) { s_logger.error("Unable to resize volume",e); diff --git a/server/src/com/cloud/storage/VolumeManagerImpl.java b/server/src/com/cloud/storage/VolumeManagerImpl.java index 8d2eb565355..f7c0f86e847 100644 --- a/server/src/com/cloud/storage/VolumeManagerImpl.java +++ b/server/src/com/cloud/storage/VolumeManagerImpl.java @@ -1096,12 +1096,12 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { "Can't resize a volume that has never been attached, not sure which hypervisor type. Recreate volume to resize."); } - /* Only works for KVM/Xen for now */ + /* Only works for KVM/Xen/VMware for now */ if (_volsDao.getHypervisorType(volume.getId()) != HypervisorType.KVM && _volsDao.getHypervisorType(volume.getId()) != HypervisorType.XenServer && _volsDao.getHypervisorType(volume.getId()) != HypervisorType.VMware) { throw new InvalidParameterValueException( - "Cloudstack currently only supports volumes marked as KVM or XenServer hypervisor for resize"); + "Cloudstack currently only supports volumes marked as KVM or XenServer or ESX hypervisor for resize"); }