@@ -1407,6 +1407,8 @@ public KVMPhysicalDisk createPhysicalDisk(String name, KVMStoragePool pool,
14071407 createPhysicalDiskByQemuImg (name , pool , PhysicalDiskFormat .RAW , provisioningType , size , passphrase );
14081408 } else if (StoragePoolType .CLVM_NG .equals (poolType )) {
14091409 return createClvmNgDiskWithBacking (name , 0 , size , null , pool , provisioningType );
1410+ } else if (StoragePoolType .CLVM .equals (poolType )) {
1411+ return createClvmVolume (name , size , pool );
14101412 } else if (StoragePoolType .NetworkFilesystem .equals (poolType ) || StoragePoolType .Filesystem .equals (poolType )) {
14111413 switch (format ) {
14121414 case QCOW2 :
@@ -2207,75 +2209,23 @@ to support snapshots(backuped) as qcow2 files. */
22072209 disk .getFormat () : PhysicalDiskFormat .RAW ;
22082210 String sourcePath = disk .getPath ();
22092211
2210- boolean isSourceClvm = srcPool .getType () == StoragePoolType .CLVM || srcPool .getType () == StoragePoolType .CLVM_NG ;
2211- boolean isDestClvm = destPool .getType () == StoragePoolType .CLVM || destPool .getType () == StoragePoolType .CLVM_NG ;
2212-
2213- String clvmLockVolume = null ;
2214- boolean shouldDeactivateSource = false ;
2215-
2216- try {
2217- if (isSourceClvm ) {
2218- logger .info ("Activating source CLVM volume {} in shared mode for copy" , sourcePath );
2219- LibvirtComputingResource .setClvmVolumeToSharedMode (sourcePath );
2220- shouldDeactivateSource = !isDestClvm ;
2221- }
2222-
2223- KVMPhysicalDisk newDisk ;
2224- logger .debug ("copyPhysicalDisk: disk size:{}, virtualsize:{} format:{}" , toHumanReadableSize (disk .getSize ()), toHumanReadableSize (disk .getVirtualSize ()), disk .getFormat ());
2225- if (destPool .getType () != StoragePoolType .RBD ) {
2226- if (disk .getFormat () == PhysicalDiskFormat .TAR ) {
2227- newDisk = destPool .createPhysicalDisk (name , PhysicalDiskFormat .DIR , Storage .ProvisioningType .THIN , disk .getVirtualSize (), null );
2228- } else {
2229- newDisk = destPool .createPhysicalDisk (name , Storage .ProvisioningType .THIN , disk .getVirtualSize (), null );
2230- }
2212+ KVMPhysicalDisk newDisk ;
2213+ logger .debug ("copyPhysicalDisk: disk size:{}, virtualsize:{} format:{}" , toHumanReadableSize (disk .getSize ()), toHumanReadableSize (disk .getVirtualSize ()), disk .getFormat ());
2214+ if (destPool .getType () != StoragePoolType .RBD ) {
2215+ if (disk .getFormat () == PhysicalDiskFormat .TAR ) {
2216+ newDisk = destPool .createPhysicalDisk (name , PhysicalDiskFormat .DIR , Storage .ProvisioningType .THIN , disk .getVirtualSize (), null );
22312217 } else {
2232- newDisk = new KVMPhysicalDisk (destPool .getSourceDir () + "/" + name , name , destPool );
2233- newDisk .setFormat (PhysicalDiskFormat .RAW );
2234- newDisk .setSize (disk .getVirtualSize ());
2235- newDisk .setVirtualSize (disk .getSize ());
2236- }
2237-
2238- String destPath = newDisk .getPath ();
2239- PhysicalDiskFormat destFormat = newDisk .getFormat ();
2240-
2241- if (isDestClvm ) {
2242- logger .info ("Activating destination CLVM volume {} in shared mode for copy" , destPath );
2243- LibvirtComputingResource .setClvmVolumeToSharedMode (destPath );
2244- clvmLockVolume = destPath ;
2245- }
2246-
2247- boolean formatConversion = sourceFormat != destFormat ;
2248- if (formatConversion ) {
2249- logger .info ("Format conversion required: {} -> {}" , sourceFormat , destFormat );
2250- }
2251-
2252- return performCopy (disk , name , destPool , timeout , srcPool , sourceFormat ,
2253- sourcePath , newDisk , destPath , destFormat , formatConversion );
2254-
2255- } finally {
2256- if (isSourceClvm && shouldDeactivateSource ) {
2257- try {
2258- logger .info ("Deactivating source CLVM volume {} after copy" , sourcePath );
2259- LibvirtComputingResource .deactivateClvmVolume (sourcePath );
2260- } catch (Exception e ) {
2261- logger .warn ("Failed to deactivate source CLVM volume {}: {}" , sourcePath , e .getMessage ());
2262- }
2263- }
2264- if (isDestClvm && clvmLockVolume != null ) {
2265- try {
2266- logger .info ("Claiming exclusive lock on destination CLVM volume {} after copy" , clvmLockVolume );
2267- LibvirtComputingResource .activateClvmVolumeExclusive (clvmLockVolume );
2268- } catch (Exception e ) {
2269- logger .warn ("Failed to claim exclusive lock on destination CLVM volume {}: {}" , clvmLockVolume , e .getMessage ());
2270- }
2218+ newDisk = destPool .createPhysicalDisk (name , Storage .ProvisioningType .THIN , disk .getVirtualSize (), null );
22712219 }
2220+ } else {
2221+ newDisk = new KVMPhysicalDisk (destPool .getSourceDir () + "/" + name , name , destPool );
2222+ newDisk .setFormat (PhysicalDiskFormat .RAW );
2223+ newDisk .setSize (disk .getVirtualSize ());
2224+ newDisk .setVirtualSize (disk .getSize ());
22722225 }
2273- }
22742226
2275- private KVMPhysicalDisk performCopy (KVMPhysicalDisk disk , String name , KVMStoragePool destPool , int timeout ,
2276- KVMStoragePool srcPool , PhysicalDiskFormat sourceFormat , String sourcePath ,
2277- KVMPhysicalDisk newDisk , String destPath , PhysicalDiskFormat destFormat ,
2278- boolean formatConversion ) {
2227+ String destPath = newDisk .getPath ();
2228+ PhysicalDiskFormat destFormat = newDisk .getFormat ();
22792229
22802230 QemuImg qemu ;
22812231
@@ -2376,8 +2326,8 @@ private KVMPhysicalDisk performCopy(KVMPhysicalDisk disk, String name, KVMStorag
23762326 }
23772327 } else {
23782328 /**
2379- We let Qemu-Img do the work here. Although we could work with librbd and have that do the cloning
2380- it doesn't benefit us. It's better to keep the current code in place which works
2329+ We let Qemu-Img do the work here. Although we could work with librbd and have that do the cloning
2330+ it doesn't benefit us. It's better to keep the current code in place which works
23812331 */
23822332 srcFile = new QemuImgFile (KVMPhysicalDisk .RBDStringBuilder (srcPool , sourcePath ));
23832333 srcFile .setFormat (sourceFormat );
@@ -2786,4 +2736,41 @@ private void removeLvOnFailure(String lvPath, int timeout) {
27862736 lvremove .add (lvPath );
27872737 lvremove .execute ();
27882738 }
2739+
2740+ /**
2741+ * Creates a raw LV volume for CLVM pools using direct LVM commands.
2742+ * This bypasses libvirt since CLVM pools are kept inactive in libvirt.
2743+ *
2744+ * @param volumeName the name of the volume to create
2745+ * @param size the size of the volume in bytes
2746+ * @param pool the CLVM storage pool
2747+ * @return the created KVMPhysicalDisk
2748+ */
2749+ private KVMPhysicalDisk createClvmVolume (String volumeName , long size , KVMStoragePool pool ) {
2750+ String vgName = getVgName (pool .getLocalPath ());
2751+ String volumePath = "/dev/" + vgName + "/" + volumeName ;
2752+ int timeout = 30000 ; // 30 seconds timeout for LV creation
2753+
2754+ logger .info ("Creating CLVM volume {} in VG {} with size {} bytes" , volumeName , vgName , size );
2755+
2756+ Script lvcreate = new Script ("lvcreate" , Duration .millis (timeout ), logger );
2757+ lvcreate .add ("-n" , volumeName );
2758+ lvcreate .add ("-L" , size + "B" );
2759+ lvcreate .add (vgName );
2760+
2761+ String result = lvcreate .execute ();
2762+ if (result != null ) {
2763+ throw new CloudRuntimeException ("Failed to create CLVM volume: " + result );
2764+ }
2765+
2766+ logger .info ("Successfully created CLVM volume {} at {} with size {}" , volumeName , volumePath , toHumanReadableSize (size ));
2767+
2768+ long actualSize = getClvmVolumeSize (volumePath );
2769+ KVMPhysicalDisk disk = new KVMPhysicalDisk (volumePath , volumeName , pool );
2770+ disk .setFormat (PhysicalDiskFormat .RAW );
2771+ disk .setSize (actualSize );
2772+ disk .setVirtualSize (actualSize );
2773+
2774+ return disk ;
2775+ }
27892776}
0 commit comments