Hi Mac,
For creating RDM we need to do the following:
Create the VirtualDeviceConfigSpec and set its properties.
Create VirtualMachineConfigSpec object and set the VirtualDeviceConfigSpec to the device change property of VirtualMachineConfigSpec object.
3. Call the ReconfigVM_Task.
If I follow the process 1 specified below getting the error “Incompatible device backing specified for device 0 “ as it is unable to create the vmdk file with the path specified in
backingInfo->fileName. If I specify backingInfo->fileName=”[datastorename]” then it is creating Virtual Disk with unknown size which is not RDM.
But if I follow the process 2 , first create vmdk file and then specify this file in backingInfo->fileName, its working fine.
But the problem is it works only in case of ESXServer not Virtual Center because for creating VirtualDisk_Task, it takes VirtualDiskManager as
Parameter which is not set in case of Virtual Center.
So we are unable to understand why it is failing to create the RDM in process 1.
I am also enclosing the link where the guy is able to create RDM using Process 1.
We came to know how to set the values for the following properties also
backingInfo->lunUuid
vdCfgSpec->device->unitNumber
vdCfgSpec->device->controllerKey
I also tried setting the below property in process 1 but no use
vdCfgSpec ->fileOperation = VirtualDeviceConfigSpecFileOperation::create;
vdCfgSpec ->fileOperationSpecified = true;
I am still working on this, but if you find any solution on process 1, please let me know.
Thanks & Regards
Neela
1.Process to create a RDM (Error : Incompatible device backing specified for device 0)
==================
/// Create VirtualDeviceConfigSpec object and set its properties
VimApi::VirtualDeviceConfigSpec^ vdCfgSpec = gcnew VimApi::VirtualDeviceConfigSpec();
vdCfgSpec->operation = VirtualDeviceConfigSpecOperation::add;
vdCfgSpec->operationSpecified = true;
vdCfgSpec->device = gcnew VirtualDisk();
VirtualDiskRawDiskMappingVer1BackingInfo^ backingInfo = gcnew VirtualDiskRawDiskMappingVer1BackingInfo();
backingInfo->compatibilityMode = "physicalMode";
/// Need to be changed to the canonical name
backingInfo->deviceName = "vmhba1:1:17:0"; //p_VDisk->;
backingInfo->diskMode = "independent_persistent";
backingInfo->lunUuid = 01002d00003030303032374443303030374d61676e6974; // uuid we can get from the Host
backingInfo->fileName = "[Primary] vm.vmdk";
// Note: set any *Specified values to true
vdCfgSpec->device->backing = backingInfo;
vdCfgSpec->device->connectable = gcnew VirtualDeviceConnectInfo();
vdCfgSpec->device->connectable->allowGuestControl = true;
vdCfgSpec->device->connectable->connected = true;
vdCfgSpec->device->connectable->startConnected = true;
vdCfgSpec->device->controllerKey = 1000;//vdary[iSCSIControllerIndex].key; // you may have one already, or have to create one in this same spec.
vdCfgSpec->device->controllerKeySpecified = true;
vdCfgSpec->device->key = -1; // all devices can be -1, but. all SCSI controllers must have unique -ve values
vdCfgSpec->device->unitNumber = 3; // next device # in SCSI chain... vdCfgSpec[0].device.unitNumberSpecified = true;
vdCfgSpec->device->unitNumberSpecified = true;
VimApi::Description^ deviceInfo = gcnew VimApi::Description();
deviceInfo->label = "HardDisk123";
deviceInfo->summary = "";
vdCfgSpec->device->deviceInfo = deviceInfo;
/// Create the Virtual Machine managed object
VimApi::ManagedObjectReference ^vm = gcnew VimApi::ManagedObjectReference();
vm->type = "VirtualMachine";
Morpheus::Model::VMW_ModelObjectId^ VMobj = safe_cast<Morpheus::Model::VMW_ModelObjectId^> (this->ObjectId);
vm->Value = VMobj->MOB->Value;
// Create the VirtualMachineConfigSpec object
VimApi::VirtualMachineConfigSpec^ virtualMacConfigSpec = gcnew VimApi::VirtualMachineConfigSpec();
virtualMacConfigSpec->deviceChange = gcnew array<VimApi::VirtualDeviceConfigSpec^> ;
m_pVimSvc->ReconfigVM_Task(vm,virtualMacConfigSpec);
2. Process to create a RDM by creating the vmdk file first and then creating RDM (But works only with ESXServer not Virtual Center)
================================================================================================
// Create the VirtualDiskManager MO
VimApi::ManagedObjectReference ^virtualDiskManager = gcnew VimApi::ManagedObjectReference();
virtualDiskManager->type = "VirtualDiskManager";
virtualDiskManager->Value = "ha-vdiskmanager";
/// create a DeviceBackedVirtualDiskSpec ob
VimApi::DeviceBackedVirtualDiskSpec^ virtualDiskSpec = gcnew VimApi::DeviceBackedVirtualDiskSpec();
virtualDiskSpec->diskType = "rdm";
virtualDiskSpec->adapterType = "lsiLogic";
virtualDiskSpec->device = p_VDisk->VMWDevicepath;
pVim->CreateVirtualDisk_Task(virtualDiskManager,"[Primary] vm.vmdk",nullptr,virtualDiskSpec);
/// Create VirtualDeviceConfigSpec object and set its properties
VimApi::VirtualDeviceConfigSpec^ vdCfgSpec = gcnew VimApi::VirtualDeviceConfigSpec();
vdCfgSpec->operation = VirtualDeviceConfigSpecOperation::add;
vdCfgSpec->operationSpecified = true;
vdCfgSpec->device = gcnew VirtualDisk();
VirtualDiskRawDiskMappingVer1BackingInfo^ backingInfo = gcnew VirtualDiskRawDiskMappingVer1BackingInfo();
backingInfo->compatibilityMode = "physicalMode";
/// Need to be changed to the canonical name
backingInfo->deviceName = "vmhba1:1:17:0"; //p_VDisk->;
backingInfo->diskMode = "independent_persistent";
backingInfo->lunUuid = 01002d00003030303032374443303030374d61676e6974; // uuid we can get from the Host
backingInfo->fileName = "[Primary] vm.vmdk";
// Note: set any *Specified values to true
vdCfgSpec->device->backing = backingInfo;
vdCfgSpec->device->connectable = gcnew VirtualDeviceConnectInfo();
vdCfgSpec->device->connectable->allowGuestControl = true;
vdCfgSpec->device->connectable->connected = true;
vdCfgSpec->device->connectable->startConnected = true;
vdCfgSpec->device->controllerKey = 1000;//vdary[iSCSIControllerIndex].key; // you may have one already, or have to create one in this same spec.
vdCfgSpec->device->controllerKeySpecified = true;
vdCfgSpec->device->key = -1; // all devices can be -1, but. all SCSI controllers must have unique -ve values
vdCfgSpec->device->unitNumber = 3; // next device # in SCSI chain... vdCfgSpec[0].device.unitNumberSpecified = true;
vdCfgSpec->device->unitNumberSpecified = true;
VimApi::Description^ deviceInfo = gcnew VimApi::Description();
deviceInfo->label = "HardDisk123";
deviceInfo->summary = "";
vdCfgSpec->device->deviceInfo = deviceInfo;
/// Create the Virtual Machine managed object
VimApi::ManagedObjectReference ^vm = gcnew VimApi::ManagedObjectReference();
vm->type = "VirtualMachine";
Morpheus::Model::VMW_ModelObjectId^ VMobj = safe_cast<Morpheus::Model::VMW_ModelObjectId^> (this->ObjectId);
vm->Value = VMobj->MOB->Value;
// Create the VirtualMachineConfigSpec object
VimApi::VirtualMachineConfigSpec^ virtualMacConfigSpec = gcnew VimApi::VirtualMachineConfigSpec();
virtualMacConfigSpec->deviceChange = gcnew array<VimApi::VirtualDeviceConfigSpec^> ;
m_pVimSvc->ReconfigVM_Task(vm,virtualMacConfigSpec);
Regards
Neela
The question is do we need to create vmdk file in before hand or will it be created automatically by creating rdm using the file name specified in file path?
Thanks in advance
Regards
Neela
Hi,
I am now getting the new error "Failed to power on scic0:6(/vmfs/volumes/.......).
What is the problem.Any help from anyone.
Thanks Neela
I understand this is 6 years old, and I was unable to find an answer for RDM using any language/API - and came across this post.
I figured it out, so thought I'd post here in case anyone else has the same issue.
There are two strands to achieving this.
1) Create the VirtualDisk VMDK file with backing for the RDM mapping
2) Attach the VirtualDisk to the VM
I'm using pyVmomi, so the breakdown in these strands are:
Preparation) Collect the data you will need.
a) Using your scsiLun object, retrieve the scsiLun.capacity.block and scsiLun.capacity.blockSize attributes.
calculte the capacityInKB value with scsiLun.capacity.block * scsiLun.capacity.blockSize / 1024
b) You need to find the controllerKey from the VirtualMachine object.
Iterate virtualMachine.config.hardware.device looking for each device being an instance of:
vim.vm.device.ParaVirtualSCSIController
vim.vm.device.VirtualLsiLogicController
vim.vm.device.VirtualLsiLogicSASController
vim.vm.device.VirtualBusLogicController
You need to store these somewhere - these are your scsi controller devices in the VM, they will have a .key value that you need.
Next (or at the same time as above - I separated them out) you need to iterate virtualMachine.config.hardware.device looking for
vim.vm.device.VirtualDisk instances
Each of these devices will have two attributes .controllerKey and .unitNumber
The controllerKey will correspond to the .key values discovered when looking for the scsiControllers. This tells you which controller "connects" this VirtualDisk.
The unitNumber is the controller scsiid - every disk needs a unique number between 0-15 (but don't use 7 as that is for the controller itself).
Using the above information you can calculate the controllerKey and unitNumber value for your new disk. My method is to walk the controllers, and walk each disk on that specific controller. I remove the unitNumber from a prepopulated array/list of 0..6,8..15. If by the end of the walk, the array size is > 0 then I choose that controllerKey and the first element in the list (will be the first unused unitNumber).
c) Find the Datacenter used by your VirtualMachine (needed for the CreateVirtualDisk method)
To do this I take the virtualMachine object and if it has an attribute .parent then I recursively follow the .parent objects until I find one of the instance type vim.Datacenter
d) Figure out where to store the .vmdk - If you want, like me, to put it with the VM files:
rdmFilename = os.path.dirname(virtualMachine.config.files.vmPathName) + "/" + scsiLun.canonicalName + ".vmdk"
1) Create the RDM VirtualDisk device
#Create the devicespec
newVirtualDiskSpec = vim.VirtualDiskManager.DeviceBackedVirtualDiskSpec(diskType="rdm",
adapterType="lsiLogic",
device=scsiLun.deviceName)
#And create the disk with a task
createDiskTask = self.vmContent.virtualDiskManager.CreateVirtualDisk(name=rdmFilename,
datacenter=vmDatacenter,
spec=newVirtualDiskSpec)
Like all tasks, you need to wait for it to complete (or error)
2) Attach the VirtualDisk for the VM
It might appear that most of this information should be above in the VMDK, but really we're now just describing the above VMDK RDM container to to the VM.
deviceBlockCount = scsiLun.capacity.block
deviceBlockSize = scsiLun.capacity.blockSize
deviceSizeInKB = (deviceBlockSize * deviceBlockCount) / 1024
newdisk = vim.vm.device.VirtualDisk()
newdisk.deviceInfo = vim.Description()
newdisk.deviceInfo.label = scsiLun.deviceName
newdisk.deviceInfo.summary = str(deviceSizeInKB/1024/1024) + " GB"
newdisk.backing = vim.vm.device.VirtualDisk.RawDiskMappingVer1BackingInfo()
newdisk.backing.compatibilityMode = vim.vm.device.VirtualDiskOption.CompatibilityMode.physicalMode
newdisk.backing.diskMode = vim.vm.device.VirtualDiskOption.DiskMode.independent_persistent
newdisk.backing.fileName = rdmFilename # same as above in step 1
newdisk.backing.deviceName = scsiLun.deviceName
newdisk.backing.lunUuid = scsiLun.uuid
newdisk.capacityInKB = deviceSizeInKB # calculated from lun attributes
newdisk.controllerKey = scsiControllerKey # one we discovered in this VM
newdisk.unitNumber = unitNumber # calculated unused scsiid
# Create the new DiskDevice object
newdiskDevice = vim.vm.device.VirtualDeviceSpec()
newdiskDevice.device = newdisk
newdiskDevice.operation = vim.vm.device.VirtualDeviceSpec.Operation.add
# And attach it to the VM via a ReconfigVM_Task
configSpec = vim.vm.ConfigSpec(deviceChange=[newdiskDevice])
reconfigTask = virtualMachine.ReconfigVM_Task(configSpec)
And again wait for the task to complete/
Tearing it down involves finding the VirtualDisk object (I'm searching vmdisk.backing.lunUuid for the WWN I'm interested in) and
# Create a config to remove the virtualdisk
diskDevice = vim.vm.device.VirtualDeviceSpec()
diskDevice.device = vDisk
diskDevice.operation = vim.vm.device.VirtualDeviceSpec.Operation.remove
# And remove it from the VM
configSpec = vim.vm.ConfigSpec(deviceChange=[diskDevice])
reconfigTask = testVm.ReconfigVM_Task(configSpec)
Note we still have the VMDK for the RDM lying in the VM's datastore directory, so we remove that with
# Finally, delete the vmdk from the datastore
deleteDiskTask = self.vmContent.virtualDiskManager.DeleteVirtualDisk(
name=vDisk.backing.fileName,
datacenter=vmDatacenter)
#Wait for the DeleteVirtualDisk task to complete
Hope this helps.
I am trying to connect a iSCSI LUN to VM using vSphere Web Services SDK (C#). I am able to get scsiLun object from HostStorageDeviceInfo,
I am trying to follow the steps given above to connect iSCSI LUN as RDM to VM, As you mentions in comment. I am not able to get scsiLun.capacity and scsiLun.deviceName
The parameters available are as follows
scsiLun {durableName*,key*,lunType,model*,operationalState,queueDepth*,revision*,scsiLevel*,serialNumber*,standardInquiry*,uuid,vendor*,vStorageSupport*} [Link]
Also not able to find VirtualDiskManager.
Thank you so much for posting this!! This helped me out tremendously!
Just one thing I had to do when following what you wrote, maybe this recently changed, but instead of using "vim.host.ScsiLun" object, I used "vim.host.ScsiDisk".
Thanks again!