Updated Branches:
  refs/heads/rbd-snapshotting 15294979e -> 59c60a88b

rbd: Use librbd to create RBD images

This way the images are in format 2 since libvirt doesn't support this yet


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/59c60a88
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/59c60a88
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/59c60a88

Branch: refs/heads/rbd-snapshotting
Commit: 59c60a88bc745ad92b443900612100978b6aa629
Parents: 1529497
Author: Wido den Hollander <[email protected]>
Authored: Wed Jul 31 10:19:37 2013 +0200
Committer: Wido den Hollander <[email protected]>
Committed: Wed Jul 31 10:19:37 2013 +0200

----------------------------------------------------------------------
 .../kvm/storage/LibvirtStorageAdaptor.java      | 105 +++++++++++++------
 1 file changed, 71 insertions(+), 34 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/59c60a88/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 29c52ea..dae25ae 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
@@ -74,6 +74,8 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
     private String _manageSnapshotPath;
 
     private String rbdTemplateSnapName = "cloudstack-base-snap";
+    private int rbdFeatures = (1<<0); /* Feature 1<<0 means layering in RBD 
format 2 */
+    private int rbdOrder = 0; /* Order 0 means 4MB blocks (the default) */
 
     public LibvirtStorageAdaptor(StorageLayer storage) {
         _storageLayer = storage;
@@ -616,34 +618,76 @@ public class LibvirtStorageAdaptor implements 
StorageAdaptor {
         StoragePool virtPool = libvirtPool.getPool();
         LibvirtStorageVolumeDef.volFormat libvirtformat = null;
 
+        String volPath = null;
+        String volName = null;
+        long volAllocation = 0;
+        long volCapacity = 0;
+
+        /**
+         * To have RBD function properly we want RBD images of format 2
+         * libvirt currently defaults to format 1
+         *
+         * For that reason we use the native RBD bindings to create the
+         * RBD image until libvirt creates RBD format 2 by default
+         */
         if (pool.getType() == StoragePoolType.RBD) {
             format = PhysicalDiskFormat.RAW;
-        }
 
-        if (format == PhysicalDiskFormat.QCOW2) {
-            libvirtformat = LibvirtStorageVolumeDef.volFormat.QCOW2;
-        } else if (format == PhysicalDiskFormat.RAW) {
-            libvirtformat = LibvirtStorageVolumeDef.volFormat.RAW;
-        } else if (format == PhysicalDiskFormat.DIR) {
-            libvirtformat = LibvirtStorageVolumeDef.volFormat.DIR;
-        } else if (format == PhysicalDiskFormat.TAR) {
-            libvirtformat = LibvirtStorageVolumeDef.volFormat.TAR;
-        }
+            try {
+                s_logger.info("Creating RBD image " + pool.getSourcePort() + 
"/" + name + " with size " + size);
 
-        LibvirtStorageVolumeDef volDef = new LibvirtStorageVolumeDef(name,
-                size, libvirtformat, null, null);
-        s_logger.debug(volDef.toString());
-        try {
-            StorageVol vol = virtPool.storageVolCreateXML(volDef.toString(), 
0);
-            KVMPhysicalDisk disk = new KVMPhysicalDisk(vol.getPath(),
-                    vol.getName(), pool);
-            disk.setFormat(format);
-            disk.setSize(vol.getInfo().allocation);
-            disk.setVirtualSize(vol.getInfo().capacity);
-            return disk;
-        } catch (LibvirtException e) {
-            throw new CloudRuntimeException(e.toString());
+                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"));
+
+                IoCTX io = r.ioCtxCreate(pool.getSourceDir());
+                Rbd rbd = new Rbd(io);
+                rbd.create(name, size, this.rbdFeatures, this.rbdOrder);
+
+                r.ioCtxDestroy(io);
+            } catch (RadosException e) {
+                throw new CloudRuntimeException(e.toString());
+            } catch (RbdException e) {
+                throw new CloudRuntimeException(e.toString());
+            }
+
+            volPath = name;
+            volName = name;
+            volCapacity = size;
+            volAllocation = size;
+        } else {
+
+            if (format == PhysicalDiskFormat.QCOW2) {
+                libvirtformat = LibvirtStorageVolumeDef.volFormat.QCOW2;
+            } else if (format == PhysicalDiskFormat.RAW) {
+                libvirtformat = LibvirtStorageVolumeDef.volFormat.RAW;
+            } else if (format == PhysicalDiskFormat.DIR) {
+                libvirtformat = LibvirtStorageVolumeDef.volFormat.DIR;
+            } else if (format == PhysicalDiskFormat.TAR) {
+                libvirtformat = LibvirtStorageVolumeDef.volFormat.TAR;
+            }
+
+            LibvirtStorageVolumeDef volDef = new LibvirtStorageVolumeDef(name,
+                    size, libvirtformat, null, null);
+            s_logger.debug(volDef.toString());
+            try {
+                StorageVol vol = 
virtPool.storageVolCreateXML(volDef.toString(), 0);
+                volPath = vol.getPath();
+                volName = vol.getName();
+                volAllocation = vol.getInfo().allocation;
+                volCapacity = vol.getInfo().capacity;
+            } catch (LibvirtException e) {
+                throw new CloudRuntimeException(e.toString());
+            }
         }
+
+        KVMPhysicalDisk disk = new KVMPhysicalDisk(volPath, volName, pool);
+        disk.setFormat(format);
+        disk.setSize(volAllocation);
+        disk.setVirtualSize(volCapacity);
+        return disk;
     }
 
     @Override
@@ -767,11 +811,6 @@ public class LibvirtStorageAdaptor implements 
StorageAdaptor {
                      * we want to copy it
                      */
 
-                    /* Feature 1<<0 means layering in RBD format 2 */
-                    int rbdFeatures = (1<<0);
-                    /* Order 0 means 4MB blocks (the default) */
-                    int rbdOrder = 0;
-
                     try {
                         if 
((srcPool.getSourceHost().equals(destPool.getSourceHost())) && 
(srcPool.getSourceDir().equals(destPool.getSourceDir()))) {
                             /* We are on the same Ceph cluster, but we require 
RBD format 2 on the source image */
@@ -792,7 +831,7 @@ public class LibvirtStorageAdaptor implements 
StorageAdaptor {
                                 s_logger.debug("The source image " + 
srcPool.getSourceDir() + "/" + template.getName()
                                                + " is RBD format 1. We have to 
perform a regular copy (" + template.getVirtualSize() + " bytes)");
 
-                                rbd.create(disk.getName(), 
template.getVirtualSize(), rbdFeatures, rbdOrder);
+                                rbd.create(disk.getName(), 
template.getVirtualSize(), this.rbdFeatures, this.rbdOrder);
                                 RbdImage destImage = rbd.open(disk.getName());
 
                                 s_logger.debug("Starting to copy " + 
srcImage.getName() +  " to " + destImage.getName() + " in Ceph pool " + 
srcPool.getSourceDir());
@@ -805,7 +844,7 @@ public class LibvirtStorageAdaptor implements 
StorageAdaptor {
                                                + " is RBD format 2. We will 
perform a RBD clone using snapshot "
                                                + this.rbdTemplateSnapName);
                                 /* The source image is format 2, we can do a 
RBD snapshot+clone (layering) */
-                                rbd.clone(template.getName(), 
this.rbdTemplateSnapName, io, disk.getName(), rbdFeatures, rbdOrder);
+                                rbd.clone(template.getName(), 
this.rbdTemplateSnapName, io, disk.getName(), this.rbdFeatures, this.rbdOrder);
                                 s_logger.debug("Succesfully cloned " + 
template.getName() + "@" + this.rbdTemplateSnapName + " to " + disk.getName());
                             }
 
@@ -835,7 +874,7 @@ public class LibvirtStorageAdaptor implements 
StorageAdaptor {
 
                             s_logger.debug("Creating " + disk.getName() + " on 
the destination cluster " + rDest.confGet("mon_host")
                                            + " in pool " + 
destPool.getSourceDir());
-                            dRbd.create(disk.getName(), 
template.getVirtualSize(), rbdFeatures, rbdOrder);
+                            dRbd.create(disk.getName(), 
template.getVirtualSize(), this.rbdFeatures, this.rbdOrder);
 
                             RbdImage srcImage = sRbd.open(template.getName());
                             RbdImage destImage = dRbd.open(disk.getName());
@@ -980,8 +1019,6 @@ public class LibvirtStorageAdaptor implements 
StorageAdaptor {
               */
             s_logger.debug("The source image is not RBD, but the destination 
is. We will convert into RBD format 2");
             String tmpFile = "/tmp/" + name;
-            int rbdFeatures = (1<<0);
-            int rbdOrder = 0;
 
             try {
                 srcFile = new QemuImgFile(sourcePath, sourceFormat);
@@ -1000,7 +1037,7 @@ public class LibvirtStorageAdaptor implements 
StorageAdaptor {
                 Rbd rbd = new Rbd(io);
 
                 s_logger.debug("Creating RBD image " + name + " in Ceph pool " 
+ destPool.getSourceDir() + " with RBD format 2");
-                rbd.create(name, disk.getVirtualSize(), rbdFeatures, rbdOrder);
+                rbd.create(name, disk.getVirtualSize(), this.rbdFeatures, 
this.rbdOrder);
 
                 RbdImage image = rbd.open(name);
 

Reply via email to