VMware {code} Community
hishivahere
Contributor
Contributor

RDM (What could be the problem)

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.

Link :

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

5 Replies
hishivahere
Contributor
Contributor

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

0 Kudos
hishivahere
Contributor
Contributor

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

0 Kudos
pgregg
Contributor
Contributor

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.

mahesh_ryussi
Contributor
Contributor

@pgregg


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.



0 Kudos
tcng889
Contributor
Contributor

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!

0 Kudos