2727import com .cloud .hypervisor .kvm .resource .LibvirtComputingResource ;
2828import com .cloud .hypervisor .kvm .resource .LibvirtConnection ;
2929import com .cloud .hypervisor .kvm .resource .LibvirtStoragePoolDef ;
30- import com .cloud .hypervisor .kvm .resource .LibvirtStorageVolumeDef ;
3130import com .cloud .storage .Storage ;
3231import com .cloud .storage .Storage .StoragePoolType ;
3332import com .cloud .storage .StorageLayer ;
@@ -145,12 +144,11 @@ public KVMPhysicalDisk getPhysicalDisk(String volumeUuid, KVMStoragePool pool) {
145144 return getPhysicalDiskWithClvmFallback (volumeUuid , pool , libvirtPool );
146145 }
147146
148- LibvirtStorageVolumeDef voldef = getStorageVolumeDef ( libvirtPool . getPool (). getConnect (), vol );
147+ boolean isQcow2 = StoragePoolType . CLVM_NG . equals ( pool . getType () );
149148 KVMPhysicalDisk disk = new KVMPhysicalDisk (vol .getPath (), vol .getName (), pool );
150149 disk .setSize (vol .getInfo ().allocation );
151- disk .setVirtualSize (vol .getInfo ().capacity );
152- disk .setFormat (voldef .getFormat () == LibvirtStorageVolumeDef .VolumeFormat .QCOW2
153- ? PhysicalDiskFormat .QCOW2 : PhysicalDiskFormat .RAW );
150+ disk .setVirtualSize (isQcow2 ? getQcow2VirtualSize (vol .getPath ()) : vol .getInfo ().capacity );
151+ disk .setFormat (isQcow2 ? PhysicalDiskFormat .QCOW2 : PhysicalDiskFormat .RAW );
154152 return disk ;
155153 } catch (LibvirtException e ) {
156154 logger .warn ("LibvirtException looking up volume {}: {}" , volumeUuid , e .getMessage ());
@@ -400,12 +398,11 @@ private KVMPhysicalDisk getPhysicalDiskWithClvmFallback(String volumeUuid, KVMSt
400398 StorageVol vol = getVolume (libvirtPool .getPool (), volumeUuid );
401399 if (vol != null ) {
402400 logger .info ("Volume found after pool refresh: {}" , volumeUuid );
403- LibvirtStorageVolumeDef voldef = getStorageVolumeDef ( libvirtPool . getPool (). getConnect (), vol );
401+ boolean isQcow2 = StoragePoolType . CLVM_NG . equals ( pool . getType () );
404402 KVMPhysicalDisk disk = new KVMPhysicalDisk (vol .getPath (), vol .getName (), pool );
405403 disk .setSize (vol .getInfo ().allocation );
406- disk .setVirtualSize (vol .getInfo ().capacity );
407- disk .setFormat (voldef .getFormat () == LibvirtStorageVolumeDef .VolumeFormat .QCOW2
408- ? PhysicalDiskFormat .QCOW2 : PhysicalDiskFormat .RAW );
404+ disk .setVirtualSize (isQcow2 ? getQcow2VirtualSize (vol .getPath ()) : vol .getInfo ().capacity );
405+ disk .setFormat (isQcow2 ? PhysicalDiskFormat .QCOW2 : PhysicalDiskFormat .RAW );
409406 return disk ;
410407 }
411408 } catch (LibvirtException refreshEx ) {
@@ -588,7 +585,7 @@ private KVMPhysicalDisk createPhysicalDiskFromClvmLv(String lvPath, String volum
588585 KVMPhysicalDisk disk = new KVMPhysicalDisk (lvPath , volumeUuid , pool );
589586 disk .setFormat (diskFormat );
590587 disk .setSize (size );
591- disk .setVirtualSize (size );
588+ disk .setVirtualSize (diskFormat == PhysicalDiskFormat . QCOW2 ? getQcow2VirtualSize ( lvPath ) : size );
592589
593590 logger .info ("Successfully accessed CLVM/CLVM_NG volume via direct block device: {} with format: {} and size: {} bytes" ,
594591 lvPath , diskFormat , size );
@@ -753,10 +750,9 @@ private long getVgPhysicalExtentSize(String vgName) {
753750
754751 /**
755752 * Calculate LVM LV size for CLVM_NG volume allocation.
753+ * {@code peSize} must be the Physical Extent size of the VG (from {@link #getVgPhysicalExtentSize}).
756754 */
757- private long calculateClvmNgLvSize (long virtualSize , String vgName ) {
758- long peSize = getVgPhysicalExtentSize (vgName );
759-
755+ private long calculateClvmNgLvSize (long virtualSize , long peSize ) {
760756 long clusterSize = 64 * 1024L ;
761757 long l2Multiplier = 4096L ;
762758
@@ -782,6 +778,7 @@ private long getQcow2VirtualSize(String imagePath) {
782778 Script qemuImg = new Script ("qemu-img" , 300000 , logger );
783779 qemuImg .add ("info" );
784780 qemuImg .add ("--output=json" );
781+ qemuImg .add ("-U" );
785782 qemuImg .add (imagePath );
786783
787784 OutputInterpreter .AllLinesParser parser = new OutputInterpreter .AllLinesParser ();
@@ -825,11 +822,14 @@ private long getQcow2PhysicalSize(String imagePath) {
825822 private KVMPhysicalDisk createClvmNgDiskWithBacking (String volumeUuid , int timeout , long virtualSize , String backingFile ,
826823 KVMStoragePool pool , Storage .ProvisioningType provisioningType ) {
827824 String vgName = getVgName (pool .getLocalPath ());
828- long lvSize = calculateClvmNgLvSize (virtualSize , vgName );
825+ // Query PE size once and reuse for both the QCOW2 virtual-size alignment and the
826+ long peSize = getVgPhysicalExtentSize (vgName );
827+ long peAlignedVirtualSize = ((virtualSize + peSize - 1 ) / peSize ) * peSize ;
828+ long lvSize = calculateClvmNgLvSize (peAlignedVirtualSize , peSize );
829829 String volumePath = "/dev/" + vgName + "/" + volumeUuid ;
830830
831- logger .debug ("Creating CLVM_NG volume {} with LV size {} bytes (virtual size : {} bytes, provisioning: {})" ,
832- volumeUuid , lvSize , virtualSize , provisioningType );
831+ logger .debug ("Creating CLVM_NG volume {} with LV size {} bytes (requested virtual: {} bytes, PE-aligned virtual : {} bytes, provisioning: {})" ,
832+ volumeUuid , lvSize , virtualSize , peAlignedVirtualSize , provisioningType );
833833
834834 Script lvcreate = new Script ("lvcreate" , Duration .millis (timeout ), logger );
835835 lvcreate .add ("-n" , volumeUuid );
@@ -860,7 +860,7 @@ private KVMPhysicalDisk createClvmNgDiskWithBacking(String volumeUuid, int timeo
860860
861861 qemuImg .add ("-o" , qcow2Options .toString ());
862862 qemuImg .add (volumePath );
863- qemuImg .add (virtualSize + "" );
863+ qemuImg .add (peAlignedVirtualSize + "" );
864864
865865 result = qemuImg .execute ();
866866 if (result != null ) {
@@ -872,10 +872,10 @@ private KVMPhysicalDisk createClvmNgDiskWithBacking(String volumeUuid, int timeo
872872 KVMPhysicalDisk disk = new KVMPhysicalDisk (volumePath , volumeUuid , pool );
873873 disk .setFormat (PhysicalDiskFormat .QCOW2 );
874874 disk .setSize (actualSize );
875- disk .setVirtualSize (actualSize );
875+ disk .setVirtualSize (peAlignedVirtualSize );
876876
877- logger .info ("Successfully created CLVM_NG volume {} (LV size: {}, virtual size: {}, provisioning: {}, preallocation: {})" ,
878- volumeUuid , lvSize , virtualSize , provisioningType , preallocation );
877+ logger .info ("Successfully created CLVM_NG volume {} (LV size: {}, PE-aligned virtual size: {}, provisioning: {}, preallocation: {})" ,
878+ volumeUuid , lvSize , peAlignedVirtualSize , provisioningType , preallocation );
879879
880880 return disk ;
881881 }
0 commit comments