From 56874291234fbdfbd2d7bc1522c2adb1596ba127 Mon Sep 17 00:00:00 2001 From: Marcus Sorensen Date: Mon, 3 Mar 2014 11:08:55 -0700 Subject: [PATCH] CLOUDSTACK-6181: resize root volumes via resizeVolume api call resize volumes in allocated state via resizeVolume api call --- .../cloud/storage/VolumeApiServiceImpl.java | 48 ++++++++++--------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/com/cloud/storage/VolumeApiServiceImpl.java index 50aa87ee2d9..71636b13e4f 100644 --- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java @@ -697,27 +697,16 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic newDiskOffering = _diskOfferingDao.findById(cmd.getNewDiskOfferingId()); - /* - * Volumes with no hypervisor have never been assigned, and can be - * resized by recreating. perhaps in the future we can just update the - * db entry for the volume - */ - if (_volsDao.getHypervisorType(volume.getId()) == HypervisorType.None) { - throw new InvalidParameterValueException("Can't resize a volume that has never been attached, not sure which hypervisor type. Recreate volume to resize."); + /* Only works for KVM/Xen/VMware for now, and volumes with 'None' since they're just allocated in db */ + if (_volsDao.getHypervisorType(volume.getId()) != HypervisorType.KVM + && _volsDao.getHypervisorType(volume.getId()) != HypervisorType.XenServer + && _volsDao.getHypervisorType(volume.getId()) != HypervisorType.VMware + && _volsDao.getHypervisorType(volume.getId()) != HypervisorType.None) { + throw new InvalidParameterValueException("Cloudstack currently only supports volumes marked as KVM, VMware, XenServer hypervisor for resize"); } - /* Only works for KVM/Xen 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"); - } - - if (volume.getState() != Volume.State.Ready) { - throw new InvalidParameterValueException("Volume should be in ready state before attempting a resize"); - } - - if (!volume.getVolumeType().equals(Volume.Type.DATADISK)) { - throw new InvalidParameterValueException("Can only resize DATA volumes"); + if (volume.getState() != Volume.State.Ready || volume.getState() != Volume.State.Allocated) { + throw new InvalidParameterValueException("Volume should be in ready or allocated state before attempting a resize"); } /* @@ -725,7 +714,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic * required, get the correct size value */ if (newDiskOffering == null) { - if (diskOffering.isCustomized()) { + if (diskOffering.isCustomized() || volume.getVolumeType().equals(Volume.Type.ROOT)) { newSize = cmd.getSize(); if (newSize == null) { @@ -737,6 +726,9 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic throw new InvalidParameterValueException("current offering" + volume.getDiskOfferingId() + " cannot be resized, need to specify a disk offering"); } } else { + if (!volume.getVolumeType().equals(Volume.Type.DATADISK)) { + throw new InvalidParameterValueException("Can only resize Data volumes via new disk offering"); + } if (newDiskOffering.getRemoved() != null || !DiskOfferingVO.Type.Disk.equals(newDiskOffering.getType())) { throw new InvalidParameterValueException("Disk offering ID is missing or invalid"); @@ -780,8 +772,6 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic /* does the caller have the authority to act on this volume? */ _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, true, volume); - UserVmVO userVm = _userVmDao.findById(volume.getInstanceId()); - long currentSize = volume.getSize(); /* @@ -801,6 +791,20 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic - currentSize)); } + /* If this volume has never been beyond allocated state, short circuit everything and simply update the database */ + if (volume.getState() == Volume.State.Allocated) { + s_logger.debug("Volume is allocated, but never created, simply updating database with new size"); + volume.setSize(newSize); + if (newDiskOffering != null) { + volume.setDiskOfferingId(cmd.getNewDiskOfferingId()); + } + _volsDao.update(volume.getId(), volume); + return volume; + } + + UserVmVO userVm = _userVmDao.findById(volume.getInstanceId()); + + if (userVm != null) { // serialize VM operation AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();