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"); }