From 8d39f6bcf21a7c76e29c270b9304c978bbf2e8ba Mon Sep 17 00:00:00 2001 From: Nir Soffer Date: Fri, 1 Nov 2019 22:56:18 +0100 Subject: [PATCH] v2v: Optimize convert for images with small holes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "qemu-img convert" detects zeroes in allocated areas and punch holes in the destination image. This may save space on the destination image, but slows down conversion when using outputs such as rhv-upload, which have very large overhead per requests. Using the -S flag, we can treat small areas filled with zeroes as data, limiting the number of requests, and speeding the operation. Here is an example converting Fedora 30 image: $ virt-builder fedora-30 -o src.img ... $ qemu-img map -f raw --output json src.img | wc -l 213 $ qemu-img convert -f raw -O raw -t none -T none src.img dst.img $ qemu-img map -f raw --output json dst.img | wc -l 1443 $ ls -lhs *.img 1.2G -rw-r--r--. 1 nsoffer nsoffer 6.0G Nov  1 21:48 dst.img 1.2G -rw-r--r--. 1 nsoffer nsoffer 6.0G Nov  1 21:46 src.img Qemu did 1443 writes instead of 213 (5.8X). Lets repeat this conversion with the -S option: $ qemu-img convert -f raw -O raw -t none -T none -S 64k src.img dst.img $ qemu-img map -f raw --output json dst.img | wc -l 213 $ ls -lhs *.img 1.2G -rw-r--r--. 1 nsoffer nsoffer 6.0G Nov  1 21:48 dst.img 1.2G -rw-r--r--. 1 nsoffer nsoffer 6.0G Nov  1 21:46 src.img Picking a good value for -S is not easy. Testing show that 64k is best value for this test image for limiting the number of requests: $ for size in 4k 8k 16k 32k 64k; do \ printf "%5s: " $size; \ qemu-img convert -f raw -O raw -t none -T none -S $size src.img dst.img; \ qemu-img map -f raw --output json dst.img | wc -l; \ done    4k: 1443    8k: 731   16k: 521   32k: 387   64k: 213 We need more testing with oVirt to measure the performance improvement and pick a good value. This should probably be an option, but lets start with a minimal change. (cherry picked from commit 2aa78ade2d48e926b7b04050338ebd8a0c5e3f05 in virt-v2v) --- v2v/v2v.ml | 1 + 1 file changed, 1 insertion(+) diff --git a/v2v/v2v.ml b/v2v/v2v.ml index d7a868659..a81a2320a 100644 --- a/v2v/v2v.ml +++ b/v2v/v2v.ml @@ -754,6 +754,7 @@ and copy_targets cmdline targets input output = (if not (quiet ()) then [ "-p" ] else []) @ [ "-n"; "-f"; "qcow2"; "-O"; t.target_format ] @ (if cmdline.compressed then [ "-c" ] else []) @ + [ "-S"; "64k" ] @ [ overlay_file; filename ] in let start_time = gettimeofday () in if run_command cmd <> 0 then -- 2.24.1