Search code examples
virtual-machineqemuzstd

How to change zstd level for qcow2 image?


There is an option compression_type=zstd to enable zstd compression for qcow2 according to wiki.

But it always uses zstd level 3, how could I do to compress it with level 19? This image is read-only and I just want the max compression level.

The command I use now is:

qemu-img convert -p -f qcow2 -O qcow2 -c -o compression_type=zstd,preallocation=off win10.qcow2 win10-zstd.qcow2

Other info:

Linux fedora 5.17.5-300.fc36.x86_64
qemu-img.x86_64 2:6.2.0-9.fc36  

Solution

  • There are not a command line option, so we need to modify the source code. On On ./block/qcow2-threads.c (QEMU v8.2.0):

      224 |  */
    +     | ZSTD_CCtx_setParameter(cctx, ZSTD_c_strategy, ZSTD_btultra2);
    +     | ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, ZSTD_maxCLevel());
    +     | ZSTD_CCtx_setParameter(cctx, ZSTD_c_enableLongDistanceMatching, 1);
      225 | zstd_ret = ZSTD_compressStream2(cctx, &output, &input, ZSTD_e_end);
    

    Compiling by yourself or use my prebuilt binary (built on GitHub Actions).

    Now we found qemu-img at ./build/softemu. Try to convert a file:

    ./qemu-img convert -p -f qcow2 -O qcow2 -c -o compression_type=zstd win10.qcow2 win10-2.qcow2
    

    We got it:

    [kkocdko@fedora tmpfs]$ ls -l
    total 3411264
    -rw-r--r--. 1 kkocdko kkocdko 1651638272 Jun 12 01:57  win10-2.qcow2
    -rw-r--r--. 1 kkocdko kkocdko 1841496064 May 25 18:21  win10.qcow2
    

    Also posted on my blog.