Dear VMWare Friends and Family
We are trying to expand the disk on an existing VM using VIJava. More specifically, we want to resize a 10 GB disk to 30 GB on a powered-off VM without losing any data on the disk. We've tried a few different approaches, and so far none of them have worked:
1) We tried using VirtualDiskManager#extendVirtualDisk, which is listed as “experimental” in vCenter 2.5. Unfortunatley getVirtualDiskManager() on ServiceContent returns nil, so we weren’t able to go further to test this option. We are guessing this may be turned off on the vCenter level.
2) We tried taking various samples and posts on the community site, converting them to JRuby, and applying those to an existing VM with 10 gigs of space. We have the latest code below, which raises an exception: "com.vmware.vim25.InvalidDeviceSpec: null". We've also seen the task return successfully but no change happen at the vCenter level in the disk space.
We are using vCenter 2.5, VIJava (the latest release), Java 6, JRuby 1.2, and Redhat-based VMs.
Below is the relevant code sample. (It's JRuby, so all method names are lower-cased and underscored versions of the Java methods. JRuby does this translation automatically).
# retrieve the VM object for a specified name vm = find_by_name # pull back all devices, find the SCSI Controller, and get the controller key devices = vm.managed_object.config.hardware.device current_controller = devices.find {|d| d.device_info.label == "SCSI Controller 0"} controller_key = current_controller.controller_key # determine the next unit_number unit_number = devices.length + 1; # create a new backing file for the expanded disk disk_backing_info = VirtualDiskFlatVer2BackingInfo.new disk_backing_info.disk_mode = "persistent" disk_backing_info.file_name = "#{datastore_name} #{vm_name}/#{vm_name}.vmdk" # assemble the VirtualDisk, 30 gigs in size disk = VirtualDisk.new disk.backing = disk_backing_info disk.key = -1 # specifying a negative key makes it unique disk.controller_key = 1000 disk.unit_number = unit_number disk.capacity_in_kb = 30 * 1024 * 1024 # assemble spec telling vCenter to edit the existing disk and replace it device_config_spec = VirtualDeviceConfigSpec.new device_config_spec.operation = VirtualDeviceConfigSpecOperation.edit device_config_spec.file_operation = VirtualDeviceConfigSpecFileOperation.replace device_config_spec.device = disk # go from Ruby Array to Java Array of VirtualDeviceConfigSpec, and set it on the config spec device_config_spec_array = [device_config_spec].to_java(VirtualDeviceConfigSpec) vm_config_spec = VirtualMachineConfigSpec.new vm_config_spec.device_change = device_config_spec_array # finally kick off the reconfig task with the config spec task = vm.managed_object.reconfigVM_Task(vm_config_spec); task.waitForMe
Can you think of anything that might be causing this issue? Any insight or suggestions you can offer are much appreciated.
Thanks,
Rob
ReconfigVM_Task is the correct API to perform the task. The error you reported implies that there is some wrong value assigned to one of the attributes of your DeviceSpec. Please check the key of your existing "SCSI Controller", is that value is '1000'? You have specified the value for controllerKey attribute of your VirtualDisk as '1000' while it should be a key of a valid SCSI Controller Device. Also check if the unitNumber value exceeds 14. UnitNumber is a unique number of a device on its controller and as a single Controller supports only 15 devices on it. Incase value of unitNumber assigned exceeds 14, it gave an error. Hope you this information might resolve the issue at your end.
You can also refer the Java SDK sample "VMReconfig.java" shipped with VI SDK for reference.
Thanks, Seemankij. That was a big help.
We have now successfully resized a disk for an existing VM. Here's a summary of the changes we had to make:
Instead of using the key, controller_key, and unit_number for the SCSI Controller, we had to use the key, controller_key, and unit_number for the Hard Disk. (And that makes sense, of course, since we're resizing the disk, not the SCSI Controller).
We had to remove the code that set the VirtualDeviceConfigSpecFileOperation to VirtualDeviceConfigSpecFileOperation.replace. Instead of setting it to "replace", we don't set it at all.
With those two changes, we can successfully resize the disk for an existing VM.
Here's an updated code snippet:
# create a new backing file for the expanded disk disk_backing_info = VirtualDiskFlatVer2BackingInfo.new disk_backing_info.disk_mode = "persistent" disk_backing_info.file_name = "#{datastore_name} #{vm_name}/#{vm_name}.vmdk" # assemble the VirtualDisk, 20 gigs in size disk = VirtualDisk.new disk.backing = disk_backing_info disk.key = 2000 disk.controller_key = 1000 disk.unit_number = 0 disk.capacity_in_kb = 20 * 1024 * 1024 # assemble spec telling vCenter to edit the existing disk and replace it device_config_spec = VirtualDeviceConfigSpec.new device_config_spec.operation = VirtualDeviceConfigSpecOperation.edit # device_config_spec.file_operation = VirtualDeviceConfigSpecFileOperation.replace device_config_spec.device = disk # go from Ruby Array to Java Array of VirtualDeviceConfigSpec, and set it on the config spec device_config_spec_array = [device_config_spec].to_java(VirtualDeviceConfigSpec) vm_config_spec = VirtualMachineConfigSpec.new vm_config_spec.device_change = device_config_spec_array # finally kick off the reconfig task with the config spec task = vm.managed_object.reconfigVM_Task(vm_config_spec); task.waitForMe
After seeing the resize succeed in the vCenter, we ssh'ed into the VM and of course realized that Linux knew nothing about the expanded disk. Is there a standard pattern for how to do this resize and then update things at the OS level so it can see the new disk space?
Thanks,
Rob
Resizing a partition will depend on your OS and the filesystem. Nothing standard per say.
For Linux, assuming you are using ext2 or ext3 partition(s) resize2fs should be able to do an online resize if you expand the partition. I think the kernel has to support it as well, so you'll need Kernel 2.6. You'll have to take the partition offline to do a size decrease.