5454import com .linbit .linstor .api .model .ResourceMakeAvailable ;
5555import com .linbit .linstor .api .model .ResourceWithVolumes ;
5656import com .linbit .linstor .api .model .StoragePool ;
57+ import com .linbit .linstor .api .model .Volume ;
5758import com .linbit .linstor .api .model .VolumeDefinition ;
5859
5960@ StorageAdaptorInfo (storagePoolType =Storage .StoragePoolType .Linstor )
@@ -473,6 +474,40 @@ public KVMPhysicalDisk copyPhysicalDisk(KVMPhysicalDisk disk, String name, KVMSt
473474 return copyPhysicalDisk (disk , name , destPool , timeout , null , null , null );
474475 }
475476
477+ /**
478+ * Checks if all diskful resource are on a zeroed block device.
479+ * @param destPool Linstor pool to use
480+ * @param resName Linstor resource name
481+ * @return true if all resources are on a provider with zeroed blocks.
482+ */
483+ private boolean resourceSupportZeroBlocks (KVMStoragePool destPool , String resName ) {
484+ final DevelopersApi api = getLinstorAPI (destPool );
485+
486+ try {
487+ List <ResourceWithVolumes > resWithVols = api .viewResources (
488+ Collections .emptyList (),
489+ Collections .singletonList (resName ),
490+ Collections .emptyList (),
491+ Collections .emptyList (),
492+ null ,
493+ null );
494+
495+ if (resWithVols != null ) {
496+ return resWithVols .stream ()
497+ .allMatch (res -> {
498+ Volume vol0 = res .getVolumes ().get (0 );
499+ return vol0 != null && (vol0 .getProviderKind () == ProviderKind .LVM_THIN ||
500+ vol0 .getProviderKind () == ProviderKind .ZFS ||
501+ vol0 .getProviderKind () == ProviderKind .ZFS_THIN ||
502+ vol0 .getProviderKind () == ProviderKind .DISKLESS );
503+ } );
504+ }
505+ } catch (ApiException apiExc ) {
506+ s_logger .error (apiExc .getMessage ());
507+ }
508+ return false ;
509+ }
510+
476511 @ Override
477512 public KVMPhysicalDisk copyPhysicalDisk (KVMPhysicalDisk disk , String name , KVMStoragePool destPools , int timeout , byte [] srcPassphrase , byte [] destPassphrase , Storage .ProvisioningType provisioningType )
478513 {
@@ -489,8 +524,10 @@ public KVMPhysicalDisk copyPhysicalDisk(KVMPhysicalDisk disk, String name, KVMSt
489524 destFile .setFormat (dstDisk .getFormat ());
490525 destFile .setSize (disk .getVirtualSize ());
491526
527+ boolean zeroedDevice = resourceSupportZeroBlocks (destPools , LinstorUtil .RSC_PREFIX + name );
528+
492529 try {
493- final QemuImg qemu = new QemuImg (timeout );
530+ final QemuImg qemu = new QemuImg (timeout , zeroedDevice , true );
494531 qemu .convert (srcFile , destFile );
495532 } catch (QemuImgException | LibvirtException e ) {
496533 s_logger .error (e );
0 commit comments