2525import java .util .regex .Pattern ;
2626
2727import org .apache .cloudstack .storage .formatinspector .Qcow2Inspector ;
28+ import org .apache .commons .collections .MapUtils ;
2829import org .apache .commons .lang .NotImplementedException ;
2930import org .apache .commons .lang3 .StringUtils ;
3031import org .libvirt .LibvirtException ;
@@ -51,6 +52,7 @@ public class QemuImg {
5152 public static final String ENCRYPT_FORMAT = "encrypt.format" ;
5253 public static final String ENCRYPT_KEY_SECRET = "encrypt.key-secret" ;
5354 public static final String TARGET_ZERO_FLAG = "--target-is-zero" ;
55+ public static final String PREALLOCATION = "preallocation" ;
5456 public static final long QEMU_2_10 = 2010000 ;
5557 public static final long QEMU_5_10 = 5010000 ;
5658
@@ -393,6 +395,17 @@ public void convert(final QemuImgFile srcFile, final QemuImgFile destFile,
393395 convert (srcFile , destFile , options , qemuObjects , srcImageOpts , snapshotName , forceSourceFormat , false );
394396 }
395397
398+ protected Map <String , String > getResizeOptionsFromConvertOptions (final Map <String , String > options ) {
399+ if (MapUtils .isEmpty (options )) {
400+ return null ;
401+ }
402+ Map <String , String > resizeOpts = new HashMap <>();
403+ if (options .containsKey (PREALLOCATION )) {
404+ resizeOpts .put (PREALLOCATION , options .get (PREALLOCATION ));
405+ }
406+ return resizeOpts ;
407+ }
408+
396409 /**
397410 * Converts an image from source to destination.
398411 *
@@ -420,7 +433,6 @@ public void convert(final QemuImgFile srcFile, final QemuImgFile destFile,
420433 public void convert (final QemuImgFile srcFile , final QemuImgFile destFile ,
421434 final Map <String , String > options , final List <QemuObject > qemuObjects , final QemuImageOptions srcImageOpts , final String snapshotName , final boolean forceSourceFormat ,
422435 boolean keepBitmaps ) throws QemuImgException {
423-
424436 Script script = new Script (_qemuImgPath , timeout );
425437 if (StringUtils .isNotBlank (snapshotName )) {
426438 String qemuPath = Script .runSimpleBashScript (getQemuImgPathScript );
@@ -484,7 +496,7 @@ public void convert(final QemuImgFile srcFile, final QemuImgFile destFile,
484496 }
485497
486498 if (srcFile .getSize () < destFile .getSize ()) {
487- this .resize (destFile , destFile .getSize ());
499+ this .resize (destFile , destFile .getSize (), getResizeOptionsFromConvertOptions ( options ) );
488500 }
489501 }
490502
@@ -691,17 +703,29 @@ public void deleteSnapshot(final QemuImageOptions srcImageOpts, final String sna
691703 }
692704 }
693705
694- private void addScriptOptionsFromMap (Map <String , String > options , Script s ) {
695- if (options != null && !options .isEmpty ()) {
696- s .add ("-o" );
697- final StringBuffer optionsBuffer = new StringBuffer ();
698- for (final Map .Entry <String , String > option : options .entrySet ()) {
699- optionsBuffer .append (option .getKey ()).append ('=' ).append (option .getValue ()).append (',' );
700- }
701- String optionsStr = optionsBuffer .toString ();
702- optionsStr = optionsStr .replaceAll (",$" , "" );
703- s .add (optionsStr );
706+ protected void addScriptOptionsFromMap (Map <String , String > options , Script s ) {
707+ if (MapUtils .isEmpty (options )) {
708+ return ;
704709 }
710+ s .add ("-o" );
711+ final StringBuffer optionsBuffer = new StringBuffer ();
712+ for (final Map .Entry <String , String > option : options .entrySet ()) {
713+ optionsBuffer .append (option .getKey ()).append ('=' ).append (option .getValue ()).append (',' );
714+ }
715+ String optionsStr = optionsBuffer .toString ();
716+ optionsStr = optionsStr .replaceAll (",$" , "" );
717+ s .add (optionsStr );
718+ }
719+
720+ protected void addScriptResizeOptionsFromMap (Map <String , String > options , Script s ) {
721+ if (MapUtils .isEmpty (options )) {
722+ return ;
723+ }
724+ if (options .containsKey (PREALLOCATION )) {
725+ s .add (String .format ("--%s=%s" , PREALLOCATION , options .get (PREALLOCATION )));
726+ options .remove (PREALLOCATION );
727+ }
728+ addScriptOptionsFromMap (options , s );
705729 }
706730
707731 /**
@@ -747,19 +771,17 @@ public void rebase(final QemuImgFile file, final QemuImgFile backingFile, final
747771
748772 /**
749773 * Resizes an image.
750- *
774+ * <p>
751775 * This method is a facade for 'qemu-img resize'.
752- *
776+ * <p>
753777 * A negative size value will get prefixed with '-' and a positive with '+'. Sizes are in bytes and will be passed on that way.
754778 *
755- * @param file
756- * The file to be resized.
757- * @param size
758- * The new size.
759- * @param delta
760- * Flag to inform if the new size is a delta.
779+ * @param file The file to be resized.
780+ * @param size The new size.
781+ * @param delta Flag to inform if the new size is a delta.
782+ * @param options Script options for resizing. Takes a Map<String, String> with key value
761783 */
762- public void resize (final QemuImgFile file , final long size , final boolean delta ) throws QemuImgException {
784+ public void resize (final QemuImgFile file , final long size , final boolean delta , Map < String , String > options ) throws QemuImgException {
763785 String newSize = null ;
764786
765787 if (size == 0 ) {
@@ -781,6 +803,7 @@ public void resize(final QemuImgFile file, final long size, final boolean delta)
781803
782804 final Script s = new Script (_qemuImgPath );
783805 s .add ("resize" );
806+ addScriptResizeOptionsFromMap (options , s );
784807 s .add (file .getFileName ());
785808 s .add (newSize );
786809 s .execute ();
@@ -789,7 +812,7 @@ public void resize(final QemuImgFile file, final long size, final boolean delta)
789812 /**
790813 * Resizes an image.
791814 *
792- * This method is a facade for {@link QemuImg#resize(QemuImgFile, long, boolean)}.
815+ * This method is a facade for {@link QemuImg#resize(QemuImgFile, long, boolean, Map )}.
793816 *
794817 * A negative size value will get prefixed with - and a positive with +. Sizes are in bytes and will be passed on that way.
795818 *
@@ -818,18 +841,17 @@ public void resize(final QemuImageOptions imageOptions, final List<QemuObject> q
818841
819842 /**
820843 * Resizes an image.
821- *
822- * This method is a facade for {@link QemuImg#resize(QemuImgFile, long, boolean)}.
823- *
844+ * <p>
845+ * This method is a facade for {@link QemuImg#resize(QemuImgFile, long, boolean, Map )}.
846+ * <p>
824847 * A negative size value will get prefixed with - and a positive with +. Sizes are in bytes and will be passed on that way.
825848 *
826- * @param file
827- * The file to be resized.
828- * @param size
829- * The new size.
849+ * @param file The file to be resized.
850+ * @param size The new size.
851+ * @param options Script options for resizing. Takes a Map<String, String> with key value
830852 */
831- public void resize (final QemuImgFile file , final long size ) throws QemuImgException {
832- this .resize (file , size , false );
853+ public void resize (final QemuImgFile file , final long size , Map < String , String > options ) throws QemuImgException {
854+ this .resize (file , size , false , options );
833855 }
834856
835857 /**
0 commit comments