CLOUDSTACK-4424: Download RBD volume created from snapshot This failed due to a RAW -> QCOW2 conversion (again).
The current code still makes to much assumptions about everything always being QCOW2 while that is not always true. Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/829dbacc Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/829dbacc Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/829dbacc Branch: refs/heads/4.2 Commit: 829dbaccb470431244f814a9d95fc7823a3e0201 Parents: e39156e Author: Wido den Hollander <[email protected]> Authored: Fri Aug 23 11:21:26 2013 +0200 Committer: Wido den Hollander <[email protected]> Committed: Fri Aug 23 16:23:17 2013 +0200 ---------------------------------------------------------------------- .../hypervisor/kvm/storage/KVMPhysicalDisk.java | 6 +++- .../kvm/storage/KVMStorageProcessor.java | 10 ++++-- .../kvm/storage/LibvirtStorageAdaptor.java | 36 +++++++++++--------- 3 files changed, 32 insertions(+), 20 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/829dbacc/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 7f088fa..6b4d61e 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 @@ -27,7 +27,11 @@ public class KVMPhysicalDisk { String rbdOpts; rbdOpts = "rbd:" + image; - rbdOpts += ":mon_host=" + monHost + "\\\\:" + monPort; + rbdOpts += ":mon_host=" + monHost; + if (monPort != 6789) { + rbdOpts += "\\\\:" + monPort; + } + if (authUserName == null) { rbdOpts += ":auth_supported=none"; } else { http://git-wip-us.apache.org/repos/asf/cloudstack/blob/829dbacc/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java ---------------------------------------------------------------------- diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java index 1d6b58f..08d6052 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java @@ -375,6 +375,10 @@ public class KVMStorageProcessor implements StorageProcessor { public Answer copyVolumeFromPrimaryToSecondary(CopyCommand cmd) { DataTO srcData = cmd.getSrcTO(); DataTO destData = cmd.getDestTO(); + VolumeObjectTO srcVol = (VolumeObjectTO) srcData; + VolumeObjectTO destVol = (VolumeObjectTO) destData; + ImageFormat srcFormat = srcVol.getFormat(); + ImageFormat destFormat = destVol.getFormat(); DataStoreTO srcStore = srcData.getDataStore(); DataStoreTO destStore = destData.getDataStore(); PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO) srcStore; @@ -390,8 +394,9 @@ public class KVMStorageProcessor implements StorageProcessor { try { String volumeName = UUID.randomUUID().toString(); - String destVolumeName = volumeName + ".qcow2"; KVMPhysicalDisk volume = storagePoolMgr.getPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), srcVolumePath); + String destVolumeName = volumeName + "." + destFormat.getFileExtension(); + volume.setFormat(PhysicalDiskFormat.valueOf(srcFormat.toString())); secondaryStoragePool = storagePoolMgr.getStoragePoolByURI( secondaryStorageUrl); secondaryStoragePool.createFolder(destVolumePath); @@ -402,6 +407,7 @@ public class KVMStorageProcessor implements StorageProcessor { destVolumeName,secondaryStoragePool); VolumeObjectTO newVol = new VolumeObjectTO(); newVol.setPath(destVolumePath + File.separator + destVolumeName); + newVol.setFormat(destFormat); return new CopyCmdAnswer(newVol); } catch (CloudRuntimeException e) { return new CopyCmdAnswer(e.toString()); @@ -636,7 +642,7 @@ public class KVMStorageProcessor implements StorageProcessor { * * These bindings will read the snapshot and write the contents to * the secondary storage directly - * + * * It will stop doing so if the amount of time spend is longer then * cmds.timeout */ http://git-wip-us.apache.org/repos/asf/cloudstack/blob/829dbacc/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 f79c8af..4a61f70 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 @@ -480,13 +480,13 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { // if anyone is, undefine the pool so we can define it as requested. // This should be safe since a pool in use can't be removed, and no // volumes are affected by unregistering the pool with libvirt. - s_logger.debug("Didn't find an existing storage pool " + name + s_logger.debug("Didn't find an existing storage pool " + name + " by UUID, checking for pools with duplicate paths"); try { String[] poolnames = conn.listStoragePools(); for (String poolname : poolnames) { - s_logger.debug("Checking path of existing pool " + poolname + s_logger.debug("Checking path of existing pool " + poolname + " against pool we want to create"); StoragePool p = conn.storagePoolLookupByName(poolname); LibvirtStoragePoolDef pdef = getStoragePoolDef(conn, p); @@ -504,7 +504,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { } } } catch (LibvirtException e) { - s_logger.error("Failure in attempting to see if an existing storage pool might " + s_logger.error("Failure in attempting to see if an existing storage pool might " + "be using the path of the pool to be created:" + e); } @@ -547,14 +547,14 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { pool.setCapacity(sp.getInfo().capacity); pool.setUsed(sp.getInfo().allocation); pool.setAvailable(sp.getInfo().available); - + return pool; } catch (LibvirtException e) { String error = e.toString(); if (error.contains("Storage source conflict")) { throw new CloudRuntimeException("A pool matching this location already exists in libvirt, " - + " but has a different UUID/Name. Cannot create new pool without first " - + " removing it. Check for inactive pools via 'virsh pool-list --all'. " + + " but has a different UUID/Name. Cannot create new pool without first " + + " removing it. Check for inactive pools via 'virsh pool-list --all'. " + error); } else { throw new CloudRuntimeException(error); @@ -825,7 +825,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { 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 */ s_logger.debug("Trying to perform a RBD clone (layering) since we are operating in the same storage pool"); - + Rados r = new Rados(srcPool.getAuthUserName()); r.confSet("mon_host", srcPool.getSourceHost() + ":" + srcPool.getSourcePort()); r.confSet("key", srcPool.getAuthSecret()); @@ -895,7 +895,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { sRbd.close(srcImage); dRbd.close(destImage); - + rSrc.ioCtxDestroy(sIO); rDest.ioCtxDestroy(dIO); } @@ -966,12 +966,21 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { for Secondary Storage */ + KVMStoragePool srcPool = disk.getPool(); + PhysicalDiskFormat sourceFormat = disk.getFormat(); + String sourcePath = disk.getPath(); + KVMPhysicalDisk newDisk; if (destPool.getType() != StoragePoolType.RBD) { if (disk.getFormat() == PhysicalDiskFormat.TAR) { newDisk = destPool.createPhysicalDisk(name, PhysicalDiskFormat.DIR, disk.getVirtualSize()); } else { - newDisk = destPool.createPhysicalDisk(name, disk.getVirtualSize()); + /* If the source device is on a RBD storage pool force the new disk to the same format (RAW) */ + if (srcPool.getType() != StoragePoolType.RBD) { + newDisk = destPool.createPhysicalDisk(name, disk.getVirtualSize()); + } else { + newDisk = destPool.createPhysicalDisk(name, sourceFormat, disk.getVirtualSize()); + } } } else { newDisk = new KVMPhysicalDisk(destPool.getSourceDir() + "/" + name, name, destPool); @@ -980,10 +989,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { newDisk.setVirtualSize(disk.getSize()); } - KVMStoragePool srcPool = disk.getPool(); String destPath = newDisk.getPath(); - String sourcePath = disk.getPath(); - PhysicalDiskFormat sourceFormat = disk.getFormat(); PhysicalDiskFormat destFormat = newDisk.getFormat(); QemuImg qemu = new QemuImg(); @@ -1117,11 +1123,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { srcPool.getAuthSecret(), sourcePath)); srcFile.setFormat(sourceFormat); - destFile = new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(destPool.getSourceHost(), - destPool.getSourcePort(), - destPool.getAuthUserName(), - destPool.getAuthSecret(), - destPath)); + destFile = new QemuImgFile(destPath); destFile.setFormat(destFormat); try {
