You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by wi...@apache.org on 2013/05/13 22:27:32 UTC
[2/2] git commit: updated refs/heads/rbd-snap-clone to 9dc6dce
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 <wi...@42on.com>
Authored: Mon May 13 22:25:40 2013 +0200
Committer: Wido den Hollander <wi...@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() +