cloudstack-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From wid...@apache.org
Subject [45/47] git commit: updated refs/heads/rbd-snap-clone to 30acdb7
Date Tue, 14 May 2013 13:58:04 GMT
When downloading a QCOW2 file from Secondary Storage, convert it to
RAW prior to converting it to RBD format 2


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

Branch: refs/heads/rbd-snap-clone
Commit: 664fcb81cbf40358b91bb56d0d2fe8093b0d3948
Parents: efc9897
Author: Wido den Hollander <wido@widodh.nl>
Authored: Tue May 14 15:39:50 2013 +0200
Committer: Wido den Hollander <wido@widodh.nl>
Committed: Tue May 14 15:56:57 2013 +0200

----------------------------------------------------------------------
 .../kvm/storage/LibvirtStorageAdaptor.java         |   76 +++++++++++++--
 1 files changed, 66 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/664fcb81/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 8f1cd73..c15e020 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
@@ -17,6 +17,9 @@
 package com.cloud.hypervisor.kvm.storage;
 
 import java.io.File;
+import java.io.FileInputStream;
+import java.io.BufferedInputStream;
+import java.io.IOException;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.util.ArrayList;
@@ -869,14 +872,70 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
                             + srcFile.getFileName() + " the error was: " + e.getMessage());
                 }
             }
+
+            try {
+                qemu.convert(srcFile, destFile);
+            } catch (QemuImgException e) {
+                s_logger.error("Failed to convert " + srcFile.getFileName() + " to "
+                        + destFile.getFileName() + " the error was: " + e.getMessage());
+            }
+
         } else if ((srcPool.getType() != StoragePoolType.RBD) && (destPool.getType()
== StoragePoolType.RBD))  {
-            srcFile = new QemuImgFile(sourcePath, sourceFormat);
-            destFile = new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(destPool.getSourceHost(),
-                    destPool.getSourcePort(),
-                    destPool.getAuthUserName(),
-                    destPool.getAuthSecret(),
-                    destPath));
-            destFile.setFormat(destFormat);
+            /**
+              * Qemu doesn't support writing to RBD format 2 directly, so we have to write
to a temporary RAW file first
+              * which we then convert to RBD format 2.
+              *
+              * A HUGE performance gain can be achieved here if QCOW2 -> RBD format 2
can be done in one step
+              */
+            String tmpFile = "/tmp/" + destPath;
+            int rbdFeatures = (1<<0);
+            int rbdOrder = 0;
+
+            try {
+                srcFile = new QemuImgFile(sourcePath, sourceFormat);
+                destFile = new QemuImgFile(tmpFile);
+                qemu.convert(srcFile, destFile);
+
+                // We now convert the temporary file to a RBD image with format 2
+                Rados r = new Rados(destPool.getAuthUserName());
+                r.confSet("mon_host", destPool.getSourceHost());
+                r.confSet("key", destPool.getAuthSecret());
+
+                IoCTX io = r.ioCtxCreate(destPool.getSourceDir());
+                Rbd rbd = new Rbd(io);
+                rbd.create(destPath, disk.getVirtualSize(), rbdFeatures, rbdOrder);
+
+                RbdImage image = rbd.open(destPath);
+
+                // We now read the temporary file and write it to the RBD image
+                File fh = new File(tmpFile);
+                BufferedInputStream bis = new BufferedInputStream(new FileInputStream(fh));
+
+                int chunkSize = 4194304;
+                int offset = 0;
+                byte[] buf = new byte[chunkSize];
+                while(true) {
+                    int bytes = bis.read(buf);
+                    if (bytes < 0 ) {
+                        break;
+                    }
+                    image.write(buf, offset);
+                    offset += bytes;
+                }
+                rbd.close(image);
+                r.ioCtxDestroy(io);
+
+            } catch (QemuImgException e) {
+                s_logger.error("Failed to do a temp convert from " + srcFile.getFileName()
+ " to "
+                        + destFile.getFileName() + " the error was: " + e.getMessage());
+            } catch (RadosException e) {
+                s_logger.error("A Ceph RADOS operation failed (" + e.getReturnValue() + ").
The error was: " + e.getMessage());
+            } catch (RbdException e) {
+                s_logger.error("A Ceph RBD operation failed (" + e.getReturnValue() + ").
The error was: " + e.getMessage());
+            } catch (IOException e) {
+                s_logger.error("Failed reading the temporary file during the conversion to
RBD: " + e.getMessage());
+            }
+
         } else {
             /**
                 We let Qemu-Img do the work here. Although we could work with librbd and
have that do the cloning
@@ -894,9 +953,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
                     destPool.getAuthSecret(),
                     destPath));
             destFile.setFormat(destFormat);
-        }
 
-        if (srcFile != null && destFile != null) {
             try {
                 qemu.convert(srcFile, destFile);
             } catch (QemuImgException e) {
@@ -905,7 +962,6 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
             }
         }
 
-
         return newDisk;
     }
 


Mime
View raw message