From aa07959f2adc77a471582a995af2aeb242d10dc0 Mon Sep 17 00:00:00 2001 From: Harikrishna Patnala Date: Fri, 26 Jun 2020 12:02:58 +0530 Subject: [PATCH] Use VStorageObjectManager for disk operations. Created disks using VStorageObjectManager Removed redundant code around attach volume and create volumes --- .../resource/VmwareStorageLayoutHelper.java | 9 +- .../resource/VmwareStorageProcessor.java | 69 +++++--- .../vmware/mo/HypervisorHostHelper.java | 1 + .../cloud/hypervisor/vmware/mo/TaskMO.java | 4 + .../vmware/mo/VirtualMachineMO.java | 105 ++++-------- .../mo/VirtualStorageObjectManager.java | 58 ------- .../mo/VirtualStorageObjectManagerMO.java | 94 +++++++++++ .../hypervisor/vmware/util/VmwareHelper.java | 150 +++++------------- 8 files changed, 214 insertions(+), 276 deletions(-) delete mode 100644 vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualStorageObjectManager.java create mode 100644 vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualStorageObjectManagerMO.java diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageLayoutHelper.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageLayoutHelper.java index a422fedb25f..91970e9073b 100644 --- a/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageLayoutHelper.java +++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageLayoutHelper.java @@ -311,7 +311,14 @@ public class VmwareStorageLayoutHelper { } public static String getLegacyDatastorePathFromVmdkFileName(DatastoreMO dsMo, String vmdkFileName) throws Exception { - return String.format("[%s] %s/%s", dsMo.getName(), HypervisorHostHelper.VSPHERE_DATASTORE_BASE_FOLDER, vmdkFileName); + String vmdkDatastorePath = String.format("[%s] %s/%s", dsMo.getName(), HypervisorHostHelper.VSPHERE_DATASTORE_BASE_FOLDER, vmdkFileName); + if (!dsMo.fileExists(vmdkDatastorePath)) { + vmdkDatastorePath = String.format("[%s] %s/%s", dsMo.getName(), HypervisorHostHelper.VSPHERE_FCD_DEFAULT_FOLDER, vmdkFileName); + } + if (!dsMo.fileExists(vmdkDatastorePath)) { + vmdkDatastorePath = getDeprecatedLegacyDatastorePathFromVmdkFileName(dsMo, vmdkFileName); + } + return vmdkDatastorePath; } public static String getDeprecatedLegacyDatastorePathFromVmdkFileName(DatastoreMO dsMo, String vmdkFileName) throws Exception { diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageProcessor.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageProcessor.java index 1e30101933d..0e12d6e1d75 100644 --- a/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageProcessor.java +++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageProcessor.java @@ -34,6 +34,10 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; +import com.cloud.hypervisor.vmware.mo.VirtualStorageObjectManagerMO; +import com.vmware.vim25.BaseConfigInfoDiskFileBackingInfo; +import com.vmware.vim25.VStorageObject; +import com.vmware.vim25.VirtualDiskType; import org.apache.cloudstack.agent.directdownload.DirectDownloadCommand; import org.apache.cloudstack.storage.command.AttachAnswer; import org.apache.cloudstack.storage.command.AttachCommand; @@ -2253,37 +2257,50 @@ public class VmwareStorageProcessor implements StorageProcessor { String volumeUuid = UUID.randomUUID().toString().replace("-", ""); String volumeDatastorePath = dsMo.getDatastorePath(volumeUuid + ".vmdk"); - String dummyVmName = hostService.getWorkerName(context, cmd, 0); - try { - s_logger.info("Create worker VM " + dummyVmName); - vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, dummyVmName, null); - if (vmMo == null) { - throw new Exception("Unable to create a dummy VM for volume creation"); - } - synchronized (this) { - try { - vmMo.createDisk(volumeDatastorePath, (int)(volume.getSize() / (1024L * 1024L)), morDatastore, vmMo.getScsiDeviceControllerKey()); - vmMo.detachDisk(volumeDatastorePath, false); + VirtualStorageObjectManagerMO vStorageObjectManagerMO = new VirtualStorageObjectManagerMO(context); + VStorageObject virtualDisk = vStorageObjectManagerMO.createDisk(morDatastore, VirtualDiskType.THIN, volume.getSize(), volumeDatastorePath, volumeUuid); + VolumeObjectTO newVol = new VolumeObjectTO(); + DatastoreFile file = new DatastoreFile(((BaseConfigInfoDiskFileBackingInfo)virtualDisk.getConfig().getBacking()).getFilePath()); + newVol.setPath(file.getFileBaseName()); + newVol.setSize(volume.getSize()); + return new CreateObjectAnswer(newVol); + + /* + * // This is old code which uses workervm to create disks + * String dummyVmName = hostService.getWorkerName(context, cmd, 0); + try { + s_logger.info("Create worker VM " + dummyVmName); + vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, dummyVmName, null); + if (vmMo == null) { + throw new Exception("Unable to create a dummy VM for volume creation"); } - catch (Exception e) { - s_logger.error("Deleting file " + volumeDatastorePath + " due to error: " + e.getMessage()); - VmwareStorageLayoutHelper.deleteVolumeVmdkFiles(dsMo, volumeUuid, dcMo, VmwareManager.s_vmwareSearchExcludeFolder.value()); - throw new CloudRuntimeException("Unable to create volume due to: " + e.getMessage()); + + synchronized (this) { + try { + vmMo.createDisk(volumeDatastorePath, (int)(volume.getSize() / (1024L * 1024L)), morDatastore, vmMo.getScsiDeviceControllerKey()); + vmMo.detachDisk(volumeDatastorePath, false); + } + catch (Exception e) { + s_logger.error("Deleting file " + volumeDatastorePath + " due to error: " + e.getMessage()); + VmwareStorageLayoutHelper.deleteVolumeVmdkFiles(dsMo, volumeUuid, dcMo, VmwareManager.s_vmwareSearchExcludeFolder.value()); + throw new CloudRuntimeException("Unable to create volume due to: " + e.getMessage()); + } + } + + VolumeObjectTO newVol = new VolumeObjectTO(); + newVol.setPath(volumeUuid); + newVol.setSize(volume.getSize()); + return new CreateObjectAnswer(newVol); + } finally { + s_logger.info("Destroy dummy VM after volume creation"); + if (vmMo != null) { + vmMo.detachAllDisks(); + vmMo.destroy(); } } - VolumeObjectTO newVol = new VolumeObjectTO(); - newVol.setPath(volumeUuid); - newVol.setSize(volume.getSize()); - return new CreateObjectAnswer(newVol); - } finally { - s_logger.info("Destroy dummy VM after volume creation"); - if (vmMo != null) { - vmMo.detachAllDisks(); - vmMo.destroy(); - } - } + * */ } catch (Throwable e) { if (e instanceof RemoteException) { s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context"); diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java index 21e4f4c9e7c..6fd1a31c865 100644 --- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java +++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java @@ -139,6 +139,7 @@ public class HypervisorHostHelper { private static final String VMDK_PACK_DIR = "ova"; private static final String OVA_OPTION_KEY_BOOTDISK = "cloud.ova.bootdisk"; public static final String VSPHERE_DATASTORE_BASE_FOLDER = ".cloudstack.base.folder"; + public static final String VSPHERE_FCD_DEFAULT_FOLDER = "fcd"; public static VirtualMachineMO findVmFromObjectContent(VmwareContext context, ObjectContent[] ocs, String name, String instanceNameCustomField) { diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/TaskMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/TaskMO.java index 65c6a6bd362..9cf9d9554c4 100644 --- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/TaskMO.java +++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/TaskMO.java @@ -77,4 +77,8 @@ public class TaskMO extends BaseMO { return sb.toString(); } + + public static TaskInfo getTaskInfo(VmwareContext context, ManagedObjectReference morTask) throws Exception { + return (TaskInfo)context.getVimClient().getDynamicProperty(morTask, "info"); + } } diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java index e9c8aafcbd1..3100b7f26ff 100644 --- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java +++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java @@ -38,6 +38,7 @@ import com.vmware.vim25.VStorageObject; import com.vmware.vim25.VStorageObjectConfigInfo; import org.apache.commons.collections.CollectionUtils; import org.apache.log4j.Logger; +import org.apache.commons.lang.StringUtils; import com.google.gson.Gson; import com.vmware.vim25.ArrayOfManagedObjectReference; @@ -1195,7 +1196,18 @@ public class VirtualMachineMO extends BaseMO { s_logger.trace("vCenter API trace - createDisk() done(successfully)"); } - public void updateVmdkAdapter(String vmdkFileName, String newAdapterType) throws Exception { + public void updateVmdkAdapter(String vmdkFileName, String diskController) throws Exception { + + DiskControllerType diskControllerType = DiskControllerType.getType(diskController); + VmdkAdapterType vmdkAdapterType = VmdkAdapterType.getAdapterType(diskControllerType); + if (vmdkAdapterType == VmdkAdapterType.none) { + String message = "Failed to attach disk due to invalid vmdk adapter type for vmdk file [" + + vmdkFileName + "] with controller : " + diskControllerType; + s_logger.debug(message); + throw new Exception(message); + } + + String newAdapterType = vmdkAdapterType.toString(); Pair vmdkInfo = getVmdkFileInfo(vmdkFileName); VmdkFileDescriptor vmdkFileDescriptor = vmdkInfo.first(); boolean isVmfsSparseFile = vmdkFileDescriptor.isVmfsSparseFile(); @@ -1240,6 +1252,10 @@ public class VirtualMachineMO extends BaseMO { } } + public void attachDisk(String[] vmdkDatastorePathChain, ManagedObjectReference morDs) throws Exception { + attachDisk(vmdkDatastorePathChain, morDs, null); + } + public void attachDisk(String[] vmdkDatastorePathChain, ManagedObjectReference morDs, String diskController) throws Exception { if(s_logger.isTraceEnabled()) @@ -1262,24 +1278,20 @@ public class VirtualMachineMO extends BaseMO { controllerKey = getIDEControllerKey(ideDeviceCount); unitNumber = getFreeUnitNumberOnIDEController(controllerKey); } else { - controllerKey = getScsiDiskControllerKey(diskController); + if (StringUtils.isNotBlank(diskController)) { + controllerKey = getScsiDiskControllerKey(diskController); + } else { + controllerKey = getScsiDeviceControllerKey(); + } unitNumber = -1; } + synchronized (_mor.getValue().intern()) { VirtualDevice newDisk = VmwareHelper.prepareDiskDevice(this, null, controllerKey, vmdkDatastorePathChain, morDs, unitNumber, 1); - controllerKey = newDisk.getControllerKey(); - unitNumber = newDisk.getUnitNumber(); - VirtualDiskFlatVer2BackingInfo backingInfo = (VirtualDiskFlatVer2BackingInfo)newDisk.getBacking(); - String vmdkFileName = backingInfo.getFileName(); - DiskControllerType diskControllerType = DiskControllerType.getType(diskController); - VmdkAdapterType vmdkAdapterType = VmdkAdapterType.getAdapterType(diskControllerType); - if (vmdkAdapterType == VmdkAdapterType.none) { - String message = "Failed to attach disk due to invalid vmdk adapter type for vmdk file [" + - vmdkFileName + "] with controller : " + diskControllerType; - s_logger.debug(message); - throw new Exception(message); + if (StringUtils.isNotBlank(diskController)) { + String vmdkFileName = vmdkDatastorePathChain[0]; + updateVmdkAdapter(vmdkFileName, diskController); } - updateVmdkAdapter(vmdkFileName, vmdkAdapterType.toString()); VirtualMachineConfigSpec reConfigSpec = new VirtualMachineConfigSpec(); VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec(); @@ -1319,69 +1331,6 @@ public class VirtualMachineMO extends BaseMO { } - public void attachDisk(String[] vmdkDatastorePathChain, ManagedObjectReference morDs) throws Exception { - - if (s_logger.isTraceEnabled()) - s_logger.trace("vCenter API trace - attachDisk(). target MOR: " + _mor.getValue() + ", vmdkDatastorePath: " + new Gson().toJson(vmdkDatastorePathChain) + - ", datastore: " + morDs.getValue()); - - synchronized (_mor.getValue().intern()) { - VirtualDevice newDisk = VmwareHelper.prepareDiskDevice(this, null, getScsiDeviceControllerKey(), vmdkDatastorePathChain, morDs, -1, 1); - VirtualMachineConfigSpec reConfigSpec = new VirtualMachineConfigSpec(); - VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec(); - - deviceConfigSpec.setDevice(newDisk); - deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD); - - reConfigSpec.getDeviceChange().add(deviceConfigSpec); - - ManagedObjectReference morTask = _context.getService().reconfigVMTask(_mor, reConfigSpec); - boolean result = _context.getVimClient().waitForTask(morTask); - - if (!result) { - if (s_logger.isTraceEnabled()) - s_logger.trace("vCenter API trace - attachDisk() done(failed)"); - throw new Exception("Failed to attach disk due to " + TaskMO.getTaskFailureInfo(_context, morTask)); - } - - _context.waitForTaskProgressDone(morTask); - } - - if (s_logger.isTraceEnabled()) - s_logger.trace("vCenter API trace - attachDisk() done(successfully)"); - } - - public void attachDisk(Pair[] vmdkDatastorePathChain, int controllerKey) throws Exception { - - if (s_logger.isTraceEnabled()) - s_logger.trace("vCenter API trace - attachDisk(). target MOR: " + _mor.getValue() + ", vmdkDatastorePath: " + new Gson().toJson(vmdkDatastorePathChain)); - - synchronized (_mor.getValue().intern()) { - VirtualDevice newDisk = VmwareHelper.prepareDiskDevice(this, controllerKey, vmdkDatastorePathChain, -1, 1); - VirtualMachineConfigSpec reConfigSpec = new VirtualMachineConfigSpec(); - VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec(); - - deviceConfigSpec.setDevice(newDisk); - deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD); - - reConfigSpec.getDeviceChange().add(deviceConfigSpec); - - ManagedObjectReference morTask = _context.getService().reconfigVMTask(_mor, reConfigSpec); - boolean result = _context.getVimClient().waitForTask(morTask); - - if (!result) { - if (s_logger.isTraceEnabled()) - s_logger.trace("vCenter API trace - attachDisk() done(failed)"); - throw new Exception("Failed to attach disk due to " + TaskMO.getTaskFailureInfo(_context, morTask)); - } - - _context.waitForTaskProgressDone(morTask); - } - - if (s_logger.isTraceEnabled()) - s_logger.trace("vCenter API trace - attachDisk() done(successfully)"); - } - // vmdkDatastorePath: [datastore name] vmdkFilePath public List> detachDisk(String vmdkDatastorePath, boolean deleteBackingFile) throws Exception { @@ -2489,7 +2438,7 @@ public class VirtualMachineMO extends BaseMO { s_logger.info("Disk backing : " + diskBackingInfo.getFileName() + " matches ==> " + deviceNumbering); if (((VirtualDisk) device).getVDiskId() == null) { s_logger.debug("vDiskid does not exist for volume " + vmdkDatastorePath + " registering the disk now"); - VirtualStorageObjectManager vStorageObjectManagerMO = new VirtualStorageObjectManager(getOwnerDatacenter().first().getContext()); + VirtualStorageObjectManagerMO vStorageObjectManagerMO = new VirtualStorageObjectManagerMO(getOwnerDatacenter().first().getContext()); VStorageObject vStorageObject = vStorageObjectManagerMO.registerVirtualDisk(dsBackingFile, null, getOwnerDatacenter().first().getName()); VStorageObjectConfigInfo diskConfigInfo = vStorageObject.getConfig(); ((VirtualDisk) device).setVDiskId(diskConfigInfo.getId()); diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualStorageObjectManager.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualStorageObjectManager.java deleted file mode 100644 index 0b6f44ae0b0..00000000000 --- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualStorageObjectManager.java +++ /dev/null @@ -1,58 +0,0 @@ -// 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.vmware.mo; - -import com.vmware.vim25.ID; -import com.vmware.vim25.VStorageObject; -import org.apache.log4j.Logger; - -import com.vmware.vim25.ManagedObjectReference; - -import com.cloud.hypervisor.vmware.util.VmwareContext; - -public class VirtualStorageObjectManager extends BaseMO { - @SuppressWarnings("unused") - private static final Logger s_logger = Logger.getLogger(VirtualStorageObjectManager.class); - - public VirtualStorageObjectManager(VmwareContext context) { - super(context, context.getServiceContent().getVStorageObjectManager()); - } - - public VirtualStorageObjectManager(VmwareContext context, ManagedObjectReference morDiskMgr) { - super(context, morDiskMgr); - } - - public VirtualStorageObjectManager(VmwareContext context, String morType, String morValue) { - super(context, morType, morValue); - } - - public VStorageObject registerVirtualDisk(DatastoreFile datastoreFile, String name, String dcName) throws Exception { - StringBuilder sb = new StringBuilder(); - //https://10.2.2.254/folder/i-2-4-VM/89e3756d9b7444dc92388eb36ddd026b.vmdk?dcPath=datacenter-21&dsName=c84e4af9b6ac33e887a25d9242650091 - sb.append("https://").append(_context.getServerAddress()).append("/folder/"); - sb.append(datastoreFile.getRelativePath()); - sb.append("?dcPath="); - sb.append(dcName); - sb.append("&dsName="); - sb.append(datastoreFile.getDatastoreName()); - return _context.getService().registerDisk(_mor, sb.toString(), name); - } - - public VStorageObject retrieveVirtualDisk (ID id, ManagedObjectReference morDS) throws Exception { - return _context.getService().retrieveVStorageObject(_mor, id, morDS); - } -} diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualStorageObjectManagerMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualStorageObjectManagerMO.java new file mode 100644 index 00000000000..7924dfda646 --- /dev/null +++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualStorageObjectManagerMO.java @@ -0,0 +1,94 @@ +// 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.vmware.mo; + +import com.vmware.vim25.ID; +import com.vmware.vim25.TaskInfo; +import com.vmware.vim25.VStorageObject; +import com.vmware.vim25.VirtualDiskType; +import com.vmware.vim25.VslmCreateSpec; +import com.vmware.vim25.VslmCreateSpecDiskFileBackingSpec; +import org.apache.log4j.Logger; + +import com.vmware.vim25.ManagedObjectReference; + +import com.cloud.hypervisor.vmware.util.VmwareContext; + +public class VirtualStorageObjectManagerMO extends BaseMO { + @SuppressWarnings("unused") + private static final Logger s_logger = Logger.getLogger(VirtualStorageObjectManagerMO.class); + + public VirtualStorageObjectManagerMO(VmwareContext context) { + super(context, context.getServiceContent().getVStorageObjectManager()); + } + + public VirtualStorageObjectManagerMO(VmwareContext context, ManagedObjectReference morDiskMgr) { + super(context, morDiskMgr); + } + + public VirtualStorageObjectManagerMO(VmwareContext context, String morType, String morValue) { + super(context, morType, morValue); + } + + public VStorageObject registerVirtualDisk(DatastoreFile datastoreFile, String name, String dcName) throws Exception { + StringBuilder sb = new StringBuilder(); + //https://10.2.2.254/folder/i-2-4-VM/89e3756d9b7444dc92388eb36ddd026b.vmdk?dcPath=datacenter-21&dsName=c84e4af9b6ac33e887a25d9242650091 + sb.append("https://").append(_context.getServerAddress()).append("/folder/"); + sb.append(datastoreFile.getRelativePath()); + sb.append("?dcPath="); + sb.append(dcName); + sb.append("&dsName="); + sb.append(datastoreFile.getDatastoreName()); + return _context.getService().registerDisk(_mor, sb.toString(), name); + } + + public VStorageObject retrieveVirtualDisk (ID id, ManagedObjectReference morDS) throws Exception { + return _context.getService().retrieveVStorageObject(_mor, id, morDS); + } + + public VStorageObject createDisk(ManagedObjectReference morDS, VirtualDiskType diskType, long currentSizeInBytes, String datastoreFilepath, String filename) throws Exception { + long currentSizeInMB = currentSizeInBytes/(1024*1024); + + VslmCreateSpecDiskFileBackingSpec diskFileBackingSpec = new VslmCreateSpecDiskFileBackingSpec(); + diskFileBackingSpec.setDatastore(morDS); + diskFileBackingSpec.setProvisioningType(diskType.value()); + // path should be just the folder name. For example, instead of '[datastore1] folder1/filename.vmdk' you would just do 'folder1'. + // path is introduced from 6.7. In 6.5 disk will be created in the default folder "fcd" + diskFileBackingSpec.setPath(null); + + VslmCreateSpec vslmCreateSpec = new VslmCreateSpec(); + vslmCreateSpec.setBackingSpec(diskFileBackingSpec); + vslmCreateSpec.setCapacityInMB(currentSizeInMB); + vslmCreateSpec.setName(filename); + + ManagedObjectReference morTask = _context.getService().createDiskTask(_mor, vslmCreateSpec); + boolean result = _context.getVimClient().waitForTask(morTask); + + VStorageObject vStorageObject = null; + if (result) { + _context.waitForTaskProgressDone(morTask); + //_context.getService().reconcileDatastoreInventoryTask(_mor, morDS); + TaskInfo taskInfo = TaskMO.getTaskInfo(_context, morTask); + vStorageObject = (VStorageObject)taskInfo.getResult(); + + } else { + s_logger.error("VMware CreateDisk_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask)); + } + + return vStorageObject; + } +} diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareHelper.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareHelper.java index 181b2ef183f..08b5672760a 100644 --- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareHelper.java +++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareHelper.java @@ -212,35 +212,49 @@ public class VmwareHelper { } // vmdkDatastorePath: [datastore name] vmdkFilePath - public static VirtualDevice prepareDiskDevice(VirtualMachineMO vmMo, int controllerKey, String vmdkDatastorePath, int sizeInMb, ManagedObjectReference morDs, - int deviceNumber, int contextNumber) throws Exception { + public static VirtualDevice prepareDiskDevice(VirtualMachineMO vmMo, VirtualDisk device, int controllerKey, String vmdkDatastorePathChain[], + ManagedObjectReference morDs, int deviceNumber, int contextNumber) throws Exception { - VirtualDisk disk = new VirtualDisk(); + assert (vmdkDatastorePathChain != null); + assert (vmdkDatastorePathChain.length >= 1); - VirtualDiskFlatVer2BackingInfo backingInfo = new VirtualDiskFlatVer2BackingInfo(); - backingInfo.setDiskMode(VirtualDiskMode.PERSISTENT.value()); - backingInfo.setThinProvisioned(true); - backingInfo.setEagerlyScrub(false); - backingInfo.setDatastore(morDs); - backingInfo.setFileName(vmdkDatastorePath); - disk.setBacking(backingInfo); + VirtualDisk disk; + VirtualDiskFlatVer2BackingInfo backingInfo; + if (device != null) { + disk = device; + backingInfo = (VirtualDiskFlatVer2BackingInfo)disk.getBacking(); + } else { + disk = new VirtualDisk(); + backingInfo = new VirtualDiskFlatVer2BackingInfo(); + backingInfo.setDatastore(morDs); + backingInfo.setDiskMode(VirtualDiskMode.PERSISTENT.value()); + disk.setBacking(backingInfo); - int ideControllerKey = vmMo.getIDEDeviceControllerKey(); - if (controllerKey < 0) - controllerKey = ideControllerKey; - if (deviceNumber < 0) { - deviceNumber = vmMo.getNextDeviceNumber(controllerKey); + int ideControllerKey = vmMo.getIDEDeviceControllerKey(); + if (controllerKey < 0) + controllerKey = ideControllerKey; + if (deviceNumber < 0) { + deviceNumber = vmMo.getNextDeviceNumber(controllerKey); + } + + disk.setControllerKey(controllerKey); + disk.setKey(-contextNumber); + disk.setUnitNumber(deviceNumber); + + VirtualDeviceConnectInfo connectInfo = new VirtualDeviceConnectInfo(); + connectInfo.setConnected(true); + connectInfo.setStartConnected(true); + disk.setConnectable(connectInfo); } - disk.setControllerKey(controllerKey); - disk.setKey(-contextNumber); - disk.setUnitNumber(deviceNumber); - disk.setCapacityInKB(sizeInMb * 1024); + backingInfo.setFileName(vmdkDatastorePathChain[0]); + if (vmdkDatastorePathChain.length > 1) { + String[] parentDisks = new String[vmdkDatastorePathChain.length - 1]; + for (int i = 0; i < vmdkDatastorePathChain.length - 1; i++) + parentDisks[i] = vmdkDatastorePathChain[i + 1]; - VirtualDeviceConnectInfo connectInfo = new VirtualDeviceConnectInfo(); - connectInfo.setConnected(true); - connectInfo.setStartConnected(true); - disk.setConnectable(connectInfo); + setParentBackingInfo(backingInfo, morDs, parentDisks); + } return disk; } @@ -314,96 +328,6 @@ public class VmwareHelper { return disk; } - // vmdkDatastorePath: [datastore name] vmdkFilePath - public static VirtualDevice prepareDiskDevice(VirtualMachineMO vmMo, VirtualDisk device, int controllerKey, String vmdkDatastorePathChain[], - ManagedObjectReference morDs, int deviceNumber, int contextNumber) throws Exception { - - assert (vmdkDatastorePathChain != null); - assert (vmdkDatastorePathChain.length >= 1); - - VirtualDisk disk; - VirtualDiskFlatVer2BackingInfo backingInfo; - if (device != null) { - disk = device; - backingInfo = (VirtualDiskFlatVer2BackingInfo)disk.getBacking(); - } else { - disk = new VirtualDisk(); - backingInfo = new VirtualDiskFlatVer2BackingInfo(); - backingInfo.setDatastore(morDs); - backingInfo.setDiskMode(VirtualDiskMode.PERSISTENT.value()); - disk.setBacking(backingInfo); - - int ideControllerKey = vmMo.getIDEDeviceControllerKey(); - if (controllerKey < 0) - controllerKey = ideControllerKey; - if (deviceNumber < 0) { - deviceNumber = vmMo.getNextDeviceNumber(controllerKey); - } - - disk.setControllerKey(controllerKey); - disk.setKey(-contextNumber); - disk.setUnitNumber(deviceNumber); - - VirtualDeviceConnectInfo connectInfo = new VirtualDeviceConnectInfo(); - connectInfo.setConnected(true); - connectInfo.setStartConnected(true); - disk.setConnectable(connectInfo); - } - - backingInfo.setFileName(vmdkDatastorePathChain[0]); - if (vmdkDatastorePathChain.length > 1) { - String[] parentDisks = new String[vmdkDatastorePathChain.length - 1]; - for (int i = 0; i < vmdkDatastorePathChain.length - 1; i++) - parentDisks[i] = vmdkDatastorePathChain[i + 1]; - - setParentBackingInfo(backingInfo, morDs, parentDisks); - } - - return disk; - } - - @SuppressWarnings("unchecked") - public static VirtualDevice prepareDiskDevice(VirtualMachineMO vmMo, int controllerKey, Pair[] vmdkDatastorePathChain, - int deviceNumber, int contextNumber) throws Exception { - - assert (vmdkDatastorePathChain != null); - assert (vmdkDatastorePathChain.length >= 1); - - VirtualDisk disk = new VirtualDisk(); - - VirtualDiskFlatVer2BackingInfo backingInfo = new VirtualDiskFlatVer2BackingInfo(); - backingInfo.setDatastore(vmdkDatastorePathChain[0].second()); - backingInfo.setFileName(vmdkDatastorePathChain[0].first()); - backingInfo.setDiskMode(VirtualDiskMode.PERSISTENT.value()); - if (vmdkDatastorePathChain.length > 1) { - Pair[] parentDisks = new Pair[vmdkDatastorePathChain.length - 1]; - for (int i = 0; i < vmdkDatastorePathChain.length - 1; i++) - parentDisks[i] = vmdkDatastorePathChain[i + 1]; - - setParentBackingInfo(backingInfo, parentDisks); - } - - disk.setBacking(backingInfo); - - int ideControllerKey = vmMo.getIDEDeviceControllerKey(); - if (controllerKey < 0) - controllerKey = ideControllerKey; - if (deviceNumber < 0) { - deviceNumber = vmMo.getNextDeviceNumber(controllerKey); - } - - disk.setControllerKey(controllerKey); - disk.setKey(-contextNumber); - disk.setUnitNumber(deviceNumber); - - VirtualDeviceConnectInfo connectInfo = new VirtualDeviceConnectInfo(); - connectInfo.setConnected(true); - connectInfo.setStartConnected(true); - disk.setConnectable(connectInfo); - - return disk; - } - private static void setParentBackingInfo(VirtualDiskFlatVer2BackingInfo backingInfo, ManagedObjectReference morDs, String[] parentDatastorePathList) { VirtualDiskFlatVer2BackingInfo parentBacking = new VirtualDiskFlatVer2BackingInfo();