Repository: cloudstack Updated Branches: refs/heads/master d5333f459 -> 9763faf85
rbd: Use qemu-img to convert from QCOW2 templates to RBD directly. This saves the step of writing to a temporary image in /tmp first before writing to RBD. This is possible due to a new version in librbd. With the rbd_default_format setting we can now force qemu-img to create format 2 RBD images. This is available since Ceph version 0.67.5 (Dumpling). Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/9763faf8 Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/9763faf8 Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/9763faf8 Branch: refs/heads/master Commit: 9763faf85e3f54ac84d5ca1d5ad6e89c7fcc87ee Parents: d5333f4 Author: Wido den Hollander <[email protected]> Authored: Mon Mar 24 16:35:13 2014 +0100 Committer: Wido den Hollander <[email protected]> Committed: Mon Mar 24 16:35:13 2014 +0100 ---------------------------------------------------------------------- .../hypervisor/kvm/storage/KVMPhysicalDisk.java | 4 ++ .../kvm/storage/LibvirtStorageAdaptor.java | 60 +++++--------------- 2 files changed, 17 insertions(+), 47 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/9763faf8/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMPhysicalDisk.java ---------------------------------------------------------------------- diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMPhysicalDisk.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMPhysicalDisk.java index 7726727..669bd0b 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMPhysicalDisk.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMPhysicalDisk.java @@ -39,6 +39,10 @@ public class KVMPhysicalDisk { rbdOpts += ":id=" + authUserName; rbdOpts += ":key=" + authSecret; } + + rbdOpts += ":rbd_default_format=2"; + rbdOpts += ":client_mount_timeout=30"; + return rbdOpts; } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/9763faf8/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 5de8bd2..c1a5043 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 @@ -16,10 +16,7 @@ // under the License. package com.cloud.hypervisor.kvm.storage; -import java.io.BufferedInputStream; import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -1096,19 +1093,19 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { boolean useTmpFile = false; try { - if (sourceFormat != destFormat) { - srcFile = new QemuImgFile(sourcePath, sourceFormat); - destFile = new QemuImgFile("/tmp/" + name); - s_logger.debug("Converting " + srcFile.getFileName() + " to " + destFile.getFileName() + " as a temporary file for RBD conversion"); - qemu.convert(srcFile, destFile); - sourceFile = destFile.getFileName(); - useTmpFile = true; - } else { - // Source file is RAW, we can write directly to RBD - sourceFile = sourcePath; - } + srcFile = new QemuImgFile(sourcePath, sourceFormat); + String rbdDestFile = KVMPhysicalDisk.RBDStringBuilder(destPool.getSourceHost(), + destPool.getSourcePort(), + destPool.getAuthUserName(), + destPool.getAuthSecret(), + destPool.getSourceDir() + "/" + name); + destFile = new QemuImgFile(rbdDestFile, destFormat); + + s_logger.debug("Starting copy from source image " + srcFile.getFileName() + " to RBD image " + destPool.getSourceDir() + "/" + name); + qemu.convert(srcFile, destFile); + s_logger.debug("Succesfully converted source image " + srcFile.getFileName() + " to RBD image " + destPool.getSourceDir() + "/" + name); - // We now convert the temporary file to a RBD image with format 2 + /* We still have to create and protect a RBD snapshot in order to do cloning */ Rados r = new Rados(destPool.getAuthUserName()); r.confSet("mon_host", destPool.getSourceHost() + ":" + destPool.getSourcePort()); r.confSet("key", destPool.getAuthSecret()); @@ -1119,35 +1116,8 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { IoCTX io = r.ioCtxCreate(destPool.getSourceDir()); 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); - RbdImage image = rbd.open(name); - File fh = new File(sourceFile); - BufferedInputStream bis = new BufferedInputStream(new FileInputStream(fh)); - - int chunkSize = 4194304; - long offset = 0; - s_logger.debug("Reading file " + sourceFile + " (" + fh.length() + " bytes) into RBD image " + name + " in chunks of " + chunkSize + " bytes"); - while (true) { - byte[] buf = new byte[chunkSize]; - - int bytes = bis.read(buf); - if (bytes <= 0) { - break; - } - image.write(buf, offset, bytes); - offset += bytes; - } - s_logger.debug("Completed writing " + sourceFile + " to RBD image " + name + ". Bytes written: " + offset); - bis.close(); - - if (useTmpFile) { - s_logger.debug("Removing temporary file " + sourceFile); - fh.delete(); - } - /* Snapshot the image and protect that snapshot so we can clone (layer) from it */ s_logger.debug("Creating RBD snapshot " + rbdTemplateSnapName + " on image " + name); image.snapCreate(rbdTemplateSnapName); @@ -1157,7 +1127,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { 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()); + s_logger.error("Failed to convert from " + srcFile.getFileName() + " to " + destFile.getFileName() + " the error was: " + e.getMessage()); newDisk = null; } catch (RadosException e) { s_logger.error("A Ceph RADOS operation failed (" + e.getReturnValue() + "). The error was: " + e.getMessage()); @@ -1165,11 +1135,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { } catch (RbdException e) { s_logger.error("A Ceph RBD operation failed (" + e.getReturnValue() + "). The error was: " + e.getMessage()); newDisk = null; - } catch (IOException e) { - s_logger.error("Failed reading the temporary file during the conversion to RBD: " + e.getMessage()); - newDisk = null; } - } else { /** We let Qemu-Img do the work here. Although we could work with librbd and have that do the cloning
