cloudstack-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From wid...@apache.org
Subject [2/2] git commit: updated refs/heads/rbd-snap-clone to 9dc6dce
Date Mon, 13 May 2013 20:27:32 GMT
rbd: When creating a disk from a template, use cloning when possible.

Cloning (aka layering) makes sure we have one base image with multiple childs.


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

Branch: refs/heads/rbd-snap-clone
Commit: 9dc6dce14e50d7a91fe49a05cb2b18fa0d5e25a9
Parents: bba731c
Author: Wido den Hollander <wido@42on.com>
Authored: Mon May 13 22:25:40 2013 +0200
Committer: Wido den Hollander <wido@42on.com>
Committed: Mon May 13 22:26:43 2013 +0200

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


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/9dc6dce1/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 8f58719..41b6401 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
@@ -37,6 +37,12 @@ import org.libvirt.StoragePool;
 import org.libvirt.StoragePoolInfo;
 import org.libvirt.StorageVol;
 import org.libvirt.StoragePoolInfo.StoragePoolState;
+import com.ceph.rados.Rados;
+import com.ceph.rados.RadosException;
+import com.ceph.rados.IoCTX;
+import com.ceph.rbd.Rbd;
+import com.ceph.rbd.RbdImage;
+import com.ceph.rbd.RbdException;
 
 import com.cloud.agent.api.ManageSnapshotCommand;
 import com.cloud.hypervisor.kvm.resource.LibvirtConnection;
@@ -689,16 +695,68 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
 
                 if (srcPool.getType() != StoragePoolType.RBD) {
                     srcFile = new QemuImgFile(template.getPath(), template.getFormat());
+                    qemu.convert(srcFile, destFile);
                 } else {
-                    template.setFormat(PhysicalDiskFormat.RAW);
-                    srcFile = new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(srcPool.getSourceHost(),
-                            srcPool.getSourcePort(),
-                            srcPool.getAuthUserName(),
-                            srcPool.getAuthSecret(),
-                            template.getPath()));
-                    srcFile.setFormat(template.getFormat());
+
+                    /**
+                     * We have to find out if the source file is in the same RBD pool and
has
+                     * RBD format 2 before we can do a layering/clone operation on the RBD
image
+                     */
+
+                    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 */
+                        try {
+                            Rados r = new Rados(srcPool.getAuthUserName());
+                            r.confSet("mon_host", srcPool.getSourceHost());
+                            r.confSet("key", srcPool.getAuthSecret());
+
+                            IoCTX io = r.ioCtxCreate(srcPool.getSourceDir());
+                            Rbd rbd = new Rbd(io);
+                            RbdImage image = rbd.open(template.getPath());
+
+                            if (image.isOldFormat()) {
+                                /* The source image is RBD format 1, we have to do a regular
copy */
+                                template.setFormat(PhysicalDiskFormat.RAW);
+                                srcFile = new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(srcPool.getSourceHost(),
+                                        srcPool.getSourcePort(),
+                                        srcPool.getAuthUserName(),
+                                        srcPool.getAuthSecret(),
+                                        template.getPath()));
+                                srcFile.setFormat(template.getFormat());
+                                qemu.convert(srcFile, destFile);
+                            } else {
+                                /* The source image is format 2, we can do a RBD snapshot+clone
(layering) */
+                                String snapName = "snapfortemplate";
+
+                                /* Feature 1<<0 means layering in RBD format 2 */
+                                int rbdFeatures = (1<<0);
+                                int rbdOrder = 0;
+
+                                image.snapCreate(snapName);
+                                image.snapProtect(snapName);
+                                rbd.clone(template.getPath(), snapName, io, disk.getPath(),
rbdFeatures, rbdOrder);
+                            }
+
+                            rbd.close(image);
+                            r.ioCtxDestroy(io);
+                        } catch (RadosException e) {
+                            s_logger.error("Failed to perform a RADOS action on the Ceph
cluster, the error was: " + e.getMessage());
+                        } catch (RbdException e) {
+                            s_logger.error("Failed to perform a RBD action on the Ceph cluster,
the error was: " + e.getMessage());
+                        }
+
+                    } else {
+                        /* The source pool or host is not the same Ceph cluster, we do a
simple copy with Qemu-Img */
+                        template.setFormat(PhysicalDiskFormat.RAW);
+                        srcFile = new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(srcPool.getSourceHost(),
+                                srcPool.getSourcePort(),
+                                srcPool.getAuthUserName(),
+                                srcPool.getAuthSecret(),
+                                template.getPath()));
+                        srcFile.setFormat(template.getFormat());
+                        qemu.convert(srcFile, destFile);
+                    }
                 }
-                qemu.convert(srcFile, destFile);
             }
         } catch (QemuImgException e) {
             s_logger.error("Failed to create " + disk.getPath() +


Mime
View raw message