Updated Branches: refs/heads/4.2 e40043fc3 -> 97cad491a refs/heads/master efa861cd5 -> 3c35faaf5
CLOUDSTACK-4278: Fix resizing RBD volumes Although libvirt supports resizing RBD volumes (and other formats) the Java bindings (libvirt-java) don't. Right now we use the Java bindings for librbd to handle the resizing for us, but in the future this should be done by libvirt rather then these Java bindings. Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/3c35faaf Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/3c35faaf Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/3c35faaf Branch: refs/heads/master Commit: 3c35faaf5a62ed181d163cdcd62ef90e9b210f63 Parents: efa861c Author: Wido den Hollander <[email protected]> Authored: Wed Aug 14 16:13:30 2013 +0200 Committer: Wido den Hollander <[email protected]> Committed: Wed Aug 14 16:15:09 2013 +0200 ---------------------------------------------------------------------- .../kvm/resource/LibvirtComputingResource.java | 81 ++++++++++++++------ .../kvm/storage/LibvirtStorageAdaptor.java | 11 ++- pom.xml | 2 +- 3 files changed, 65 insertions(+), 29 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3c35faaf/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java ---------------------------------------------------------------------- diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java index be0a49e..c3efb9c 100755 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java @@ -1564,35 +1564,66 @@ ServerResource { String path = vol.getPath(); String type = getResizeScriptType(pool, vol); - if (type == null) { - return new ResizeVolumeAnswer(cmd, false, "Unsupported volume format: pool type '" - + pool.getType() + "' and volume format '" + vol.getFormat() + "'"); - } else if (type.equals("QCOW2") && shrinkOk) { - return new ResizeVolumeAnswer(cmd, false, "Unable to shrink volumes of type " + type); - } - - s_logger.debug("got to the stage where we execute the volume resize, params:" - + path + "," + currentSize + "," + newSize + "," + type + "," + vmInstanceName + "," + shrinkOk); - final Script resizecmd = new Script(_resizeVolumePath, - _cmdsTimeout, s_logger); - resizecmd.add("-s",String.valueOf(newSize)); - resizecmd.add("-c",String.valueOf(currentSize)); - resizecmd.add("-p",path); - resizecmd.add("-t",type); - resizecmd.add("-r",String.valueOf(shrinkOk)); - resizecmd.add("-v",vmInstanceName); - String result = resizecmd.execute(); + /** + * RBD volumes can't be resized via a Bash script or via libvirt + * + * libvirt-java doesn't implemented resizing volumes, so we have to do this manually + * + * Future fix would be to hand this over to libvirt + */ + if (pool.getType() == StoragePoolType.RBD) { + try { + Rados r = new Rados(pool.getAuthUserName()); + r.confSet("mon_host", pool.getSourceHost() + ":" + pool.getSourcePort()); + r.confSet("key", pool.getAuthSecret()); + r.connect(); + s_logger.debug("Succesfully connected to Ceph cluster at " + r.confGet("mon_host")); - if (result == null) { + IoCTX io = r.ioCtxCreate(pool.getSourceDir()); + Rbd rbd = new Rbd(io); + RbdImage image = rbd.open(vol.getName()); - /* fetch new size as seen from libvirt, don't want to assume anything */ - pool = _storagePoolMgr.getStoragePool(spool.getType(), spool.getUuid()); - long finalSize = pool.getPhysicalDisk(volid).getVirtualSize(); - s_logger.debug("after resize, size reports as " + finalSize + ", requested " + newSize); - return new ResizeVolumeAnswer(cmd, true, "success", finalSize); + s_logger.debug("Resizing RBD volume " + vol.getName() + " to " + newSize + " bytes"); + image.resize(newSize); + rbd.close(image); + + r.ioCtxDestroy(io); + s_logger.debug("Succesfully resized RBD volume " + vol.getName() + " to " + newSize + " bytes"); + } catch (RadosException e) { + return new ResizeVolumeAnswer(cmd, false, e.toString()); + } catch (RbdException e) { + return new ResizeVolumeAnswer(cmd, false, e.toString()); + } + } else { + if (type == null) { + return new ResizeVolumeAnswer(cmd, false, "Unsupported volume format: pool type '" + + pool.getType() + "' and volume format '" + vol.getFormat() + "'"); + } else if (type.equals("QCOW2") && shrinkOk) { + return new ResizeVolumeAnswer(cmd, false, "Unable to shrink volumes of type " + type); + } + + s_logger.debug("got to the stage where we execute the volume resize, params:" + + path + "," + currentSize + "," + newSize + "," + type + "," + vmInstanceName + "," + shrinkOk); + final Script resizecmd = new Script(_resizeVolumePath, + _cmdsTimeout, s_logger); + resizecmd.add("-s",String.valueOf(newSize)); + resizecmd.add("-c",String.valueOf(currentSize)); + resizecmd.add("-p",path); + resizecmd.add("-t",type); + resizecmd.add("-r",String.valueOf(shrinkOk)); + resizecmd.add("-v",vmInstanceName); + String result = resizecmd.execute(); + + if (result != null) { + return new ResizeVolumeAnswer(cmd, false, result); + } } - return new ResizeVolumeAnswer(cmd, false, result); + /* fetch new size as seen from libvirt, don't want to assume anything */ + pool = _storagePoolMgr.getStoragePool(spool.getType(), spool.getUuid()); + long finalSize = pool.getPhysicalDisk(volid).getVirtualSize(); + s_logger.debug("after resize, size reports as " + finalSize + ", requested " + newSize); + return new ResizeVolumeAnswer(cmd, true, "success", finalSize); } catch (CloudRuntimeException e) { String error = "failed to resize volume: " + e; s_logger.debug(error); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3c35faaf/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java ---------------------------------------------------------------------- diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java index f93eb37..d487e3c 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java @@ -414,7 +414,14 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { disk = new KVMPhysicalDisk(vol.getPath(), vol.getName(), pool); disk.setSize(vol.getInfo().allocation); disk.setVirtualSize(vol.getInfo().capacity); - if (voldef.getFormat() == null) { + + /** + * libvirt returns format = 'unknow', so we have to force + * the format to RAW for RBD storage volumes + */ + if (pool.getType() == StoragePoolType.RBD) { + disk.setFormat(PhysicalDiskFormat.RAW); + } else if (voldef.getFormat() == null) { File diskDir = new File(disk.getPath()); if (diskDir.exists() && diskDir.isDirectory()) { disk.setFormat(PhysicalDiskFormat.DIR); @@ -423,8 +430,6 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { } else { disk.setFormat(pool.getDefaultFormat()); } - } else if (pool.getType() == StoragePoolType.RBD) { - disk.setFormat(PhysicalDiskFormat.RAW); } else if (voldef.getFormat() == LibvirtStorageVolumeDef.volFormat.QCOW2) { disk.setFormat(PhysicalDiskFormat.QCOW2); } else if (voldef.getFormat() == LibvirtStorageVolumeDef.volFormat.RAW) { http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3c35faaf/pom.xml ---------------------------------------------------------------------- diff --git a/pom.xml b/pom.xml index 3772735..1f54797 100644 --- a/pom.xml +++ b/pom.xml @@ -82,7 +82,7 @@ <cs.java-ipv6.version>0.10</cs.java-ipv6.version> <cs.replace.properties>build/replace.properties</cs.replace.properties> <cs.libvirt-java.version>0.4.9</cs.libvirt-java.version> - <cs.rados-java.version>0.1.2</cs.rados-java.version> + <cs.rados-java.version>0.1.3</cs.rados-java.version> <cs.target.dir>target</cs.target.dir> <cs.daemon.version>1.0.10</cs.daemon.version> <cs.jna.version>3.0.9</cs.jna.version>
