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>

Reply via email to