Skip to content

Commit

Permalink
linstor: Improve copyPhysicalDisk performance (apache#9417)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
rp- authored Aug 20, 2024
1 parent 2e0024e commit 27f23f4
Showing 1 changed file with 38 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
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)
Expand Down Expand Up @@ -473,6 +474,40 @@ public KVMPhysicalDisk copyPhysicalDisk(KVMPhysicalDisk disk, String name, KVMSt
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)
{
Expand All @@ -489,8 +524,10 @@ public KVMPhysicalDisk copyPhysicalDisk(KVMPhysicalDisk disk, String name, KVMSt
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);
Expand Down

0 comments on commit 27f23f4

Please sign in to comment.