linstor: Improve copyPhysicalDisk performance (#9417)

Tell qemu-img that we don't want to use a write cache (we are a block device)
and also specify that we have zeroed devices in most cases.
This commit is contained in:
Rene Peinthor 2024-08-20 11:17:57 +02:00 committed by GitHub
parent 2e0024e216
commit 27f23f4f75
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -54,6 +54,7 @@ import com.linbit.linstor.api.model.ResourceGroupSpawn;
import com.linbit.linstor.api.model.ResourceMakeAvailable;
import com.linbit.linstor.api.model.ResourceWithVolumes;
import com.linbit.linstor.api.model.StoragePool;
import com.linbit.linstor.api.model.Volume;
import com.linbit.linstor.api.model.VolumeDefinition;
@StorageAdaptorInfo(storagePoolType=Storage.StoragePoolType.Linstor)
@ -473,6 +474,40 @@ public class LinstorStorageAdaptor implements StorageAdaptor {
return copyPhysicalDisk(disk, name, destPool, timeout, null, null, null);
}
/**
* Checks if all diskful resource are on a zeroed block device.
* @param destPool Linstor pool to use
* @param resName Linstor resource name
* @return true if all resources are on a provider with zeroed blocks.
*/
private boolean resourceSupportZeroBlocks(KVMStoragePool destPool, String resName) {
final DevelopersApi api = getLinstorAPI(destPool);
try {
List<ResourceWithVolumes> resWithVols = api.viewResources(
Collections.emptyList(),
Collections.singletonList(resName),
Collections.emptyList(),
Collections.emptyList(),
null,
null);
if (resWithVols != null) {
return resWithVols.stream()
.allMatch(res -> {
Volume vol0 = res.getVolumes().get(0);
return vol0 != null && (vol0.getProviderKind() == ProviderKind.LVM_THIN ||
vol0.getProviderKind() == ProviderKind.ZFS ||
vol0.getProviderKind() == ProviderKind.ZFS_THIN ||
vol0.getProviderKind() == ProviderKind.DISKLESS);
} );
}
} catch (ApiException apiExc) {
s_logger.error(apiExc.getMessage());
}
return false;
}
@Override
public KVMPhysicalDisk copyPhysicalDisk(KVMPhysicalDisk disk, String name, KVMStoragePool destPools, int timeout, byte[] srcPassphrase, byte[] destPassphrase, Storage.ProvisioningType provisioningType)
{
@ -489,8 +524,10 @@ public class LinstorStorageAdaptor implements StorageAdaptor {
destFile.setFormat(dstDisk.getFormat());
destFile.setSize(disk.getVirtualSize());
boolean zeroedDevice = resourceSupportZeroBlocks(destPools, LinstorUtil.RSC_PREFIX + name);
try {
final QemuImg qemu = new QemuImg(timeout);
final QemuImg qemu = new QemuImg(timeout, zeroedDevice, true);
qemu.convert(srcFile, destFile);
} catch (QemuImgException | LibvirtException e) {
s_logger.error(e);