mirror of
https://github.com/apache/cloudstack.git
synced 2025-11-02 20:02:29 +01:00
Merge branch 'bugfix/CID-1241966'
This commit is contained in:
commit
ec56ee9eb8
@ -211,16 +211,16 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
||||
|
||||
public VolumeVO allocateDuplicateVolumeVO(Volume oldVol, Long templateId) {
|
||||
VolumeVO newVol = new VolumeVO(oldVol.getVolumeType(),
|
||||
oldVol.getName(),
|
||||
oldVol.getDataCenterId(),
|
||||
oldVol.getDomainId(),
|
||||
oldVol.getAccountId(),
|
||||
oldVol.getDiskOfferingId(),
|
||||
oldVol.getProvisioningType(),
|
||||
oldVol.getSize(),
|
||||
oldVol.getMinIops(),
|
||||
oldVol.getMaxIops(),
|
||||
oldVol.get_iScsiName());
|
||||
oldVol.getName(),
|
||||
oldVol.getDataCenterId(),
|
||||
oldVol.getDomainId(),
|
||||
oldVol.getAccountId(),
|
||||
oldVol.getDiskOfferingId(),
|
||||
oldVol.getProvisioningType(),
|
||||
oldVol.getSize(),
|
||||
oldVol.getMinIops(),
|
||||
oldVol.getMaxIops(),
|
||||
oldVol.get_iScsiName());
|
||||
if (templateId != null) {
|
||||
newVol.setTemplateId(templateId);
|
||||
} else {
|
||||
@ -595,16 +595,16 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
||||
maxIops = maxIops != null ? maxIops : offering.getMaxIops();
|
||||
|
||||
VolumeVO vol = new VolumeVO(type,
|
||||
name,
|
||||
vm.getDataCenterId(),
|
||||
owner.getDomainId(),
|
||||
owner.getId(),
|
||||
offering.getId(),
|
||||
offering.getProvisioningType(),
|
||||
size,
|
||||
minIops,
|
||||
maxIops,
|
||||
null);
|
||||
name,
|
||||
vm.getDataCenterId(),
|
||||
owner.getDomainId(),
|
||||
owner.getId(),
|
||||
offering.getId(),
|
||||
offering.getProvisioningType(),
|
||||
size,
|
||||
minIops,
|
||||
maxIops,
|
||||
null);
|
||||
if (vm != null) {
|
||||
vol.setInstanceId(vm.getId());
|
||||
}
|
||||
@ -656,16 +656,16 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
||||
maxIops = maxIops != null ? maxIops : offering.getMaxIops();
|
||||
|
||||
VolumeVO vol = new VolumeVO(type,
|
||||
name,
|
||||
vm.getDataCenterId(),
|
||||
owner.getDomainId(),
|
||||
owner.getId(),
|
||||
offering.getId(),
|
||||
offering.getProvisioningType(),
|
||||
size,
|
||||
minIops,
|
||||
maxIops,
|
||||
null);
|
||||
name,
|
||||
vm.getDataCenterId(),
|
||||
owner.getDomainId(),
|
||||
owner.getId(),
|
||||
offering.getId(),
|
||||
offering.getProvisioningType(),
|
||||
size,
|
||||
minIops,
|
||||
maxIops,
|
||||
null);
|
||||
vol.setFormat(getSupportedImageFormatForCluster(template.getHypervisorType()));
|
||||
if (vm != null) {
|
||||
vol.setInstanceId(vm.getId());
|
||||
@ -682,8 +682,8 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
||||
}
|
||||
|
||||
if (vm.getType() == VirtualMachine.Type.User) {
|
||||
UserVmVO userVm = _userVmDao.findById(vm.getId());
|
||||
vol.setDisplayVolume(userVm.isDisplayVm());
|
||||
UserVmVO userVm = _userVmDao.findById(vm.getId());
|
||||
vol.setDisplayVolume(userVm.isDisplayVm());
|
||||
}
|
||||
|
||||
|
||||
@ -1092,7 +1092,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
||||
if (assignedPool == null && recreate) {
|
||||
assignedPool = _storagePoolDao.findById(vol.getPoolId());
|
||||
}
|
||||
if (assignedPool != null || recreate) {
|
||||
if (assignedPool != null) {
|
||||
Volume.State state = vol.getState();
|
||||
if (state == Volume.State.Allocated || state == Volume.State.Creating) {
|
||||
VolumeTask task = new VolumeTask(VolumeTaskType.RECREATE, vol, null);
|
||||
|
||||
@ -18,11 +18,10 @@ package com.cloud.hypervisor.kvm.storage;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.HashMap;
|
||||
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.log4j.Logger;
|
||||
@ -354,6 +353,9 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
|
||||
storage.create(0);
|
||||
}
|
||||
LibvirtStoragePoolDef spd = getStoragePoolDef(conn, storage);
|
||||
if (spd == null) {
|
||||
throw new CloudRuntimeException("Unable to parse the storage pool definition for storage pool " + uuid);
|
||||
}
|
||||
StoragePoolType type = null;
|
||||
if (spd.getPoolType() == LibvirtStoragePoolDef.poolType.NETFS) {
|
||||
type = StoragePoolType.NetworkFilesystem;
|
||||
@ -375,7 +377,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
|
||||
pool.setLocalPath("");
|
||||
|
||||
if (pool.getType() == StoragePoolType.RBD
|
||||
|| pool.getType() == StoragePoolType.Gluster) {
|
||||
|| pool.getType() == StoragePoolType.Gluster) {
|
||||
pool.setSourceHost(spd.getSourceHost());
|
||||
pool.setSourcePort(spd.getSourcePort());
|
||||
pool.setSourceDir(spd.getSourceDir());
|
||||
@ -633,32 +635,32 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
|
||||
PhysicalDiskFormat format, Storage.ProvisioningType provisioningType, long size) {
|
||||
|
||||
s_logger.info("Attempting to create volume " + name + " (" + pool.getType().toString() + ") in pool "
|
||||
+ pool.getUuid() + " with size " + size);
|
||||
+ pool.getUuid() + " with size " + size);
|
||||
|
||||
switch (pool.getType()){
|
||||
case RBD:
|
||||
return createPhysicalDiskOnRBD(name, pool, format, provisioningType, size);
|
||||
case NetworkFilesystem:
|
||||
case Filesystem:
|
||||
switch (format){
|
||||
case QCOW2:
|
||||
return createPhysicalDiskByQemuImg(name, pool, format, provisioningType, size);
|
||||
case RAW:
|
||||
return createPhysicalDiskByQemuImg(name, pool, format, provisioningType, size);
|
||||
case DIR:
|
||||
return createPhysicalDiskByLibVirt(name, pool, format, provisioningType, size);
|
||||
case TAR:
|
||||
return createPhysicalDiskByLibVirt(name, pool, format, provisioningType, size);
|
||||
default:
|
||||
throw new CloudRuntimeException("Unexpected disk format is specified.");
|
||||
}
|
||||
default:
|
||||
case RBD:
|
||||
return createPhysicalDiskOnRBD(name, pool, format, provisioningType, size);
|
||||
case NetworkFilesystem:
|
||||
case Filesystem:
|
||||
switch (format){
|
||||
case QCOW2:
|
||||
return createPhysicalDiskByQemuImg(name, pool, format, provisioningType, size);
|
||||
case RAW:
|
||||
return createPhysicalDiskByQemuImg(name, pool, format, provisioningType, size);
|
||||
case DIR:
|
||||
return createPhysicalDiskByLibVirt(name, pool, format, provisioningType, size);
|
||||
case TAR:
|
||||
return createPhysicalDiskByLibVirt(name, pool, format, provisioningType, size);
|
||||
default:
|
||||
throw new CloudRuntimeException("Unexpected disk format is specified.");
|
||||
}
|
||||
default:
|
||||
return createPhysicalDiskByLibVirt(name, pool, format, provisioningType, size);
|
||||
}
|
||||
}
|
||||
|
||||
private KVMPhysicalDisk createPhysicalDiskByLibVirt(String name, KVMStoragePool pool,
|
||||
PhysicalDiskFormat format, Storage.ProvisioningType provisioningType, long size) {
|
||||
PhysicalDiskFormat format, Storage.ProvisioningType provisioningType, long size) {
|
||||
LibvirtStoragePool libvirtPool = (LibvirtStoragePool) pool;
|
||||
StoragePool virtPool = libvirtPool.getPool();
|
||||
LibvirtStorageVolumeDef.volFormat libvirtformat = LibvirtStorageVolumeDef.volFormat.getFormat(format);
|
||||
@ -690,7 +692,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
|
||||
|
||||
|
||||
private KVMPhysicalDisk createPhysicalDiskByQemuImg(String name, KVMStoragePool pool,
|
||||
PhysicalDiskFormat format, Storage.ProvisioningType provisioningType, long size) {
|
||||
PhysicalDiskFormat format, Storage.ProvisioningType provisioningType, long size) {
|
||||
String volPath = pool.getLocalPath() + "/" + name;
|
||||
String volName = name;
|
||||
long virtualSize = 0;
|
||||
@ -725,7 +727,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
|
||||
}
|
||||
|
||||
private KVMPhysicalDisk createPhysicalDiskOnRBD(String name, KVMStoragePool pool,
|
||||
PhysicalDiskFormat format, Storage.ProvisioningType provisioningType, long size) {
|
||||
PhysicalDiskFormat format, Storage.ProvisioningType provisioningType, long size) {
|
||||
String volPath = null;
|
||||
|
||||
/**
|
||||
@ -751,7 +753,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
|
||||
|
||||
IoCTX io = r.ioCtxCreate(pool.getSourceDir());
|
||||
Rbd rbd = new Rbd(io);
|
||||
rbd.create(name, size, this.rbdFeatures, this.rbdOrder);
|
||||
rbd.create(name, size, rbdFeatures, rbdOrder);
|
||||
|
||||
r.ioCtxDestroy(io);
|
||||
} catch (RadosException e) {
|
||||
@ -855,7 +857,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
|
||||
r.ioCtxDestroy(io);
|
||||
|
||||
s_logger.debug("Succesfully unprotected and removed any snapshots of " + pool.getSourceDir() + "/" + uuid +
|
||||
" Continuing to remove the RBD image");
|
||||
" Continuing to remove the RBD image");
|
||||
} catch (RadosException e) {
|
||||
throw new CloudRuntimeException(e.toString());
|
||||
} catch (RbdException e) {
|
||||
@ -893,7 +895,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
|
||||
String name, PhysicalDiskFormat format, Storage.ProvisioningType provisioningType, long size, KVMStoragePool destPool, int timeout) {
|
||||
|
||||
s_logger.info("Creating volume " + name + " from template " + template.getName() + " in pool " + destPool.getUuid() +
|
||||
" (" + destPool.getType().toString() + ") with size " + size);
|
||||
" (" + destPool.getType().toString() + ") with size " + size);
|
||||
|
||||
KVMPhysicalDisk disk = null;
|
||||
|
||||
@ -920,15 +922,15 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
|
||||
Map<String, String> options = new HashMap<String, String>();
|
||||
options.put("preallocation", QemuImg.PreallocationType.getPreallocationType(provisioningType).toString());
|
||||
switch(provisioningType){
|
||||
case THIN:
|
||||
QemuImgFile backingFile = new QemuImgFile(template.getPath(), template.getFormat());
|
||||
qemu.create(destFile, backingFile, options);
|
||||
break;
|
||||
case SPARSE:
|
||||
case FAT:
|
||||
QemuImgFile srcFile = new QemuImgFile(template.getPath(), template.getFormat());
|
||||
qemu.convert(srcFile, destFile, options);
|
||||
break;
|
||||
case THIN:
|
||||
QemuImgFile backingFile = new QemuImgFile(template.getPath(), template.getFormat());
|
||||
qemu.create(destFile, backingFile, options);
|
||||
break;
|
||||
case SPARSE:
|
||||
case FAT:
|
||||
QemuImgFile srcFile = new QemuImgFile(template.getPath(), template.getFormat());
|
||||
qemu.convert(srcFile, destFile, options);
|
||||
break;
|
||||
}
|
||||
} else if (format == PhysicalDiskFormat.RAW) {
|
||||
QemuImgFile sourceFile = new QemuImgFile(template.getPath(), template.getFormat());
|
||||
@ -964,7 +966,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
|
||||
So for RBD we don't create the image, but let qemu-img do that for us.
|
||||
|
||||
We then create a KVMPhysicalDisk object that we can return
|
||||
*/
|
||||
*/
|
||||
|
||||
KVMStoragePool srcPool = template.getPool();
|
||||
KVMPhysicalDisk disk = null;
|
||||
@ -1013,7 +1015,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
|
||||
|
||||
try {
|
||||
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 */
|
||||
/* 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());
|
||||
@ -1028,7 +1030,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
|
||||
RbdImage srcImage = rbd.open(template.getName());
|
||||
|
||||
if (srcImage.isOldFormat()) {
|
||||
/* The source image is RBD format 1, we have to do a regular copy */
|
||||
/* The source image is RBD format 1, we have to do a regular copy */
|
||||
s_logger.debug("The source image " + srcPool.getSourceDir() + "/" + template.getName() +
|
||||
" is RBD format 1. We have to perform a regular copy (" + disk.getVirtualSize() + " bytes)");
|
||||
|
||||
@ -1043,12 +1045,12 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
|
||||
} else {
|
||||
s_logger.debug("The source image " + srcPool.getSourceDir() + "/" + template.getName()
|
||||
+ " is RBD format 2. We will perform a RBD clone using snapshot "
|
||||
+ this.rbdTemplateSnapName);
|
||||
/* The source image is format 2, we can do a RBD snapshot+clone (layering) */
|
||||
+ rbdTemplateSnapName);
|
||||
/* The source image is format 2, we can do a RBD snapshot+clone (layering) */
|
||||
|
||||
|
||||
s_logger.debug("Checking if RBD snapshot " + srcPool.getSourceDir() + "/" + template.getName()
|
||||
+ "@" + rbdTemplateSnapName + " exists prior to attempting a clone operation.");
|
||||
+ "@" + rbdTemplateSnapName + " exists prior to attempting a clone operation.");
|
||||
|
||||
List<RbdSnapInfo> snaps = srcImage.snapList();
|
||||
s_logger.debug("Found " + snaps.size() + " snapshots on RBD image " + srcPool.getSourceDir() + "/" + template.getName());
|
||||
@ -1056,7 +1058,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
|
||||
for (RbdSnapInfo snap : snaps) {
|
||||
if (rbdTemplateSnapName.equals(snap.name)) {
|
||||
s_logger.debug("RBD snapshot " + srcPool.getSourceDir() + "/" + template.getName()
|
||||
+ "@" + rbdTemplateSnapName + " already exists.");
|
||||
+ "@" + rbdTemplateSnapName + " already exists.");
|
||||
snapFound = true;
|
||||
break;
|
||||
}
|
||||
@ -1069,14 +1071,14 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
|
||||
srcImage.snapProtect(rbdTemplateSnapName);
|
||||
}
|
||||
|
||||
rbd.clone(template.getName(), this.rbdTemplateSnapName, io, disk.getName(), this.rbdFeatures, this.rbdOrder);
|
||||
s_logger.debug("Succesfully cloned " + template.getName() + "@" + this.rbdTemplateSnapName + " to " + disk.getName());
|
||||
rbd.clone(template.getName(), rbdTemplateSnapName, io, disk.getName(), rbdFeatures, rbdOrder);
|
||||
s_logger.debug("Succesfully cloned " + template.getName() + "@" + rbdTemplateSnapName + " to " + disk.getName());
|
||||
}
|
||||
|
||||
rbd.close(srcImage);
|
||||
r.ioCtxDestroy(io);
|
||||
} else {
|
||||
/* The source pool or host is not the same Ceph cluster, we do a simple copy with Qemu-Img */
|
||||
/* The source pool or host is not the same Ceph cluster, we do a simple copy with Qemu-Img */
|
||||
s_logger.debug("Both the source and destination are RBD, but not the same Ceph cluster. Performing a copy");
|
||||
|
||||
Rados rSrc = new Rados(srcPool.getAuthUserName());
|
||||
@ -1240,16 +1242,13 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
|
||||
* To do so it's mandatory that librbd on the system is at least 0.67.7 (Ceph Dumpling)
|
||||
*/
|
||||
s_logger.debug("The source image is not RBD, but the destination is. We will convert into RBD format 2");
|
||||
String sourceFile;
|
||||
boolean useTmpFile = false;
|
||||
|
||||
try {
|
||||
srcFile = new QemuImgFile(sourcePath, sourceFormat);
|
||||
String rbdDestFile = KVMPhysicalDisk.RBDStringBuilder(destPool.getSourceHost(),
|
||||
destPool.getSourcePort(),
|
||||
destPool.getAuthUserName(),
|
||||
destPool.getAuthSecret(),
|
||||
destPool.getSourceDir() + "/" + name);
|
||||
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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user