plugin: add qemu_img_create_qcow2_backed

and use it for plugin linked clone

This also enable extended_l2=on, as it's mandatory for backing file
preallocation.

Preallocation was missing previously, so it should increase performance
for linked clone now (around x5 in randwrite 4k)

cluster_size is set to 128k, as it reduce qcow2 overhead (reduce disk,
but also memory needed to cache metadatas)

l2_extended is not enabled yet on base image, but it could help too
to reduce overhead without impacting performance

bench on 100G qcow2 file:

fio --filename=/dev/sdb --direct=1 --rw=randwrite --bs=4k --iodepth=32 --ioengine=libaio --name=test
fio --filename=/dev/sdb --direct=1 --rw=randread --bs=4k --iodepth=32 --ioengine=libaio --name=test

base image:

randwrite 4k: prealloc=metadata, l2_extended=off, cluster_size=64k: 20215
randread 4k: prealloc=metadata, l2_extended=off, cluster_size=64k: 22219
randwrite 4k: prealloc=metadata, l2_extended=on, cluster_size=64k: 20217
randread 4k: prealloc=metadata, l2_extended=on, cluster_size=64k: 21742
randwrite 4k: prealloc=metadata, l2_extended=on, cluster_size=128k: 21599
randread 4k: prealloc=metadata, l2_extended=on, cluster_size=128k: 22037

clone image with backing file:

randwrite 4k: prealloc=metadata, l2_extended=off, cluster_size=64k: 3912
randread 4k: prealloc=metadata, l2_extended=off, cluster_size=64k: 21476
randwrite 4k: prealloc=metadata, l2_extended=on, cluster_size=64k: 20563
randread 4k: prealloc=metadata, l2_extended=on, cluster_size=64k: 22265
randwrite 4k: prealloc=metadata, l2_extended=on, cluster_size=128k: 18016
randread 4k: prealloc=metadata, l2_extended=on, cluster_size=128k: 21611

Signed-off-by: Alexandre Derumier <alexandre.derumier@groupe-cyllene.com>
This commit is contained in:
Alexandre Derumier
2025-07-09 18:21:49 +02:00
committed by Wolfgang Bumiller
parent dd2bd851ca
commit 24fe1bf621

View File

@ -51,6 +51,10 @@ our $RAW_PREALLOCATION = {
full => 1, full => 1,
}; };
my $QCOW2_CLUSTERS = {
backed => ['extended_l2=on', 'cluster_size=128k'],
};
our $MAX_VOLUMES_PER_GUEST = 1024; our $MAX_VOLUMES_PER_GUEST = 1024;
cfs_register_file( cfs_register_file(
@ -654,6 +658,39 @@ sub qemu_img_create {
run_command($cmd, errmsg => "unable to create image"); run_command($cmd, errmsg => "unable to create image");
} }
=pod
=head3 qemu_img_create_qcow2_backed
qemu_img_create_qcow2_backed($scfg, $path, $backing_path, $backing_format)
Create a new qemu qcow2 image C<$path> using an existing backing image C<$backing_path> with backing_format C<$backing_format>.
=cut
sub qemu_img_create_qcow2_backed {
my ($scfg, $path, $backing_path, $backing_format) = @_;
my $cmd = [
'/usr/bin/qemu-img',
'create',
'-F',
$backing_format,
'-b',
$backing_path,
'-f',
'qcow2',
$path,
];
my $options = $QCOW2_CLUSTERS->{backed};
push @$options, preallocation_cmd_option($scfg, 'qcow2');
push @$cmd, '-o', join(',', @$options) if @$options > 0;
run_command($cmd, errmsg => "unable to create image");
}
# Storage implementation # Storage implementation
# called during addition of storage (before the new storage config got written) # called during addition of storage (before the new storage config got written)
@ -941,20 +978,7 @@ sub clone_image {
# Note: we use relative paths, so we need to call chdir before qemu-img # Note: we use relative paths, so we need to call chdir before qemu-img
eval { eval {
local $CWD = $imagedir; local $CWD = $imagedir;
qemu_img_create_qcow2_backed($scfg, $path, "../$basevmid/$basename", $format);
my $cmd = [
'/usr/bin/qemu-img',
'create',
'-b',
"../$basevmid/$basename",
'-F',
$format,
'-f',
'qcow2',
$path,
];
run_command($cmd);
}; };
my $err = $@; my $err = $@;