Description of problem: libvirt cannot detect the format of qcow2 with native luks encryption Version-Release number of selected component (if applicable): libvirt-5.10.0-1.module+el8.2.0+5135+ed3b2489.x86_64 qemu-kvm-4.2.0-4.module+el8.2.0+5220+e82621dc.x86_64 How reproducible: 100% Steps to Reproduce: 1. prepare a qcow2 image with luks encryption # qemu-img create --object secret,id=sec0,data=123456 -f qcow2 -o encrypt.format=luks,encrypt.key-secret=sec0 base.qcow2 1G 2. create another image rebase to base.qcow2 # qemu-img create -f qcow2 no_luks.qcow2 1G Formatting 'no_luks.qcow2', fmt=qcow2 size=1073741824 cluster_size=65536 lazy_refcounts=off refcount_bits=16 # qemu-img create -f qcow2 no_luks.qcow2 1G # qemu-img rebase --object secret,id=sec0,data=123456 --image-opts driver=qcow2,file.filename=no_luks.qcow2 -b 'json:{"encrypt.key-secret": "sec0", "driver": "qcow2", "file": {"driver": "file", "filename": "/home/images/base.qcow2"}}' 3. edit the xml of a vm, use no_luks.qcow2 as its vdb # virsh edit vm1 ... <disk type='file' device='disk'> <driver name='qemu' type='qcow2'/> <source file='/home/images/no_luks.qcow2'/> <backingStore/> <target dev='vdb' bus='virtio'/> <address type='pci' domain='0x0000' bus='0x07' slot='0x00' function='0x0'/> </disk> 4. start the vm and check vdb, the backingstore image base.qcow2 is automatically set as driver=raw ## virsh start vm1 Domain vm1 started [root@dell-per730-58 images]# virsh dumpxml vm1| awk '/<disk/,/<\/disk/' .... <disk type='file' device='disk'> <driver name='qemu' type='qcow2'/> <source file='/home/images/no_luks.qcow2' index='1'/> <backingStore type='file' index='3'> <format type='raw'/> <source file='/home/images/base.qcow2'/> <backingStore/> </backingStore> <target dev='vdb' bus='virtio'/> <alias name='virtio-disk1'/> <address type='pci' domain='0x0000' bus='0x07' slot='0x00' function='0x0'/> </disk> # ps -ef | grep vm1 | grep base.qcow2 qemu 20106 1 12 03:42 ? 00:00:35 /usr/libexec/qemu-kvm -name guest=vm1 ... ... -blockdev {"driver":"file","filename":"/home/images/base.qcow2","node-name":"libvirt-3-storage","auto-read-only":true,"discard":"unmap"} -blockdev {"node-name":"libvirt-3-format","read-only":true,"driver":"raw","file":"libvirt-3-storage"} ... Actual results: As step 4, the backing image is detected as a RAW image, vm will get wrong data from vdb. Expected results: libvirt should detect base.qcow2 as a qcow2 file, and if no encrpytion provided, it will lead to a expected error as follow: # virsh edit vm1 ... <disk type='file' device='disk'> <driver name='qemu' type='qcow2'/> <source file='/home/images/no_luks.qcow2'/> <backingStore type='file'> <format type='qcow2'/> <source file='/home/images/base.qcow2'/> <backingStore/> </backingStore> <target dev='vdb' bus='virtio'/> <address type='pci' domain='0x0000' bus='0x07' slot='0x00' function='0x0'/> </disk> # virsh start vm1 error: Failed to start domain vm1 error: internal error: process exited while connecting to monitor: 2020-01-08T08:59:19.622127Z qemu-kvm: -blockdev {"node-name":"libvirt-2-format","read-only":true,"driver":"qcow2","file":"libvirt-2-storage","backing":null}: Parameter 'encrypt.key-secret' is required for cipher
in reproduce step2 there is a redundant '# qemu-img create -f qcow2 no_luks.qcow2 1G'
(In reply to yisun from comment #0) > Description of problem: > libvirt cannot detect the format of qcow2 with native luks encryption > > Version-Release number of selected component (if applicable): > libvirt-5.10.0-1.module+el8.2.0+5135+ed3b2489.x86_64 > qemu-kvm-4.2.0-4.module+el8.2.0+5220+e82621dc.x86_64 > > How reproducible: > 100% > > Steps to Reproduce: > 1. prepare a qcow2 image with luks encryption > # qemu-img create --object secret,id=sec0,data=123456 -f qcow2 -o > encrypt.format=luks,encrypt.key-secret=sec0 base.qcow2 1G > > 2. create another image rebase to base.qcow2 > # qemu-img create -f qcow2 no_luks.qcow2 1G > Formatting 'no_luks.qcow2', fmt=qcow2 size=1073741824 cluster_size=65536 > lazy_refcounts=off refcount_bits=16 > > # qemu-img create -f qcow2 no_luks.qcow2 1G > > # qemu-img rebase --object secret,id=sec0,data=123456 --image-opts > driver=qcow2,file.filename=no_luks.qcow2 -b 'json:{"encrypt.key-secret": > "sec0", "driver": "qcow2", "file": {"driver": "file", "filename": > "/home/images/base.qcow2"}}' The problem here is that you didn't specify the format of the backing file with the -F parameter. This meas that libvirt assumed the backing format to be raw and thus didn't even try to do anything about it. This was fixed by commit 3615e8b39badf2a526996a69dc91a92b04cf262e Author: Peter Krempa <pkrempa> Date: Tue Dec 17 17:04:04 2019 +0100 util: storage: Don't treat files with missing backing store format as 'raw' Assuming that the backing image format is raw is wrong when doing image detection: 1) In -drive mode qemu will still probe the image format of the backing image. This means it will try to open a backing file of the image which will fail if a more advanced security model is in use. 2) In blockdev mode the image will be opened as raw actually which is wrong since it might be qcow. Not opening the backing images will also end up in the guest seeing corrupted data. Rather than attempt to solve various corner cases when us assuming the storage file being raw and actually being right forbid startup when the guest image doesn't have the format specified in the metadata. https://bugzilla.redhat.com/show_bug.cgi?id=1588373 Signed-off-by: Peter Krempa <pkrempa> Reviewed-by: Michal Privoznik <mprivozn> libvirt will now report an error: error: Requested operation is not valid: format of backing image 'json:{"encrypt.key-secret": "sec0", "driver": "qcow2", "file": {"driver": "file", "filename": "/tmp/base.qcow2"}}' of image '/tmp/copy4.qcow2' was not specified in the image metadata If you don't specify the metadata correctly above. If you use -F the error will be as you expect: error: internal error: process exited while connecting to monitor: 2020-01-10T12:06:56.631797Z qemu-system-x86_64: -blockdev {"node-name":"libvirt-5-format","read-only":true,"driver":"qcow2","file":"libvirt-5-storage","backing":null}: Parameter 'encrypt.key-secret' is required for cipher The rest of the steps here is thus invalid as the format MUST be specified. Moving to post as the patch which produces the error was not tested yet.
Verified with libvirt-6.0.0-4.module+el8.2.0+5642+838f3513.x86_64 and PASSed (and expected result also hit by bz1798148) 1. Create a base image root@yisun-test1 /home/images 03:39:56$ qemu-img create -f qcow2 base.qcow2 1G Formatting 'base.qcow2', fmt=qcow2 size=1073741824 cluster_size=65536 lazy_refcounts=off refcount_bits=16 2. Create another image based on the base image, W/O the ‘-F qcow2’ root@yisun-test1 /home/images 03:39:51$ qemu-img create -f qcow2 layer1.qcow2 1G Formatting 'layer1.qcow2', fmt=qcow2 size=1073741824 cluster_size=65536 lazy_refcounts=off refcount_bits=16 root@yisun-test1 /home/images 03:40:11$ qemu-img rebase -u -f qcow2 -b base.qcow2 layer1.qcow2 3. Start the vm with following xml, not indicating the base image. <disk type='file' device='disk'> <driver name='qemu' type='qcow2'/> <source file='/home/images/layer1.qcow2'/> <target dev='vdb' bus='virtio'/> </disk> 4. Start the vm, failed as expected now. root@yisun-test1 /home/images 03:44:05$ virsh start vm1 error: Failed to start domain vm1 error: Requested operation is not valid: format of backing image 'base.qcow2' of image '/home/images/layer1.qcow2' was not specified in the image metadata (See https://libvirt.org/kbase/backing_chains.html for troubleshooting) 5. Rebase the layer1.qcow2 again with ‘-F qcow2’, vm can be started successfully root@yisun-test1 /home/images 03:49:02$ qemu-img rebase -u -f qcow2 -b base.qcow2 -F qcow2 layer1.qcow2 root@yisun-test1 /home/images 03:47:17$ virsh start vm1 Domain vm1 started root@yisun-test1 /home/images 03:47:33$ ps -ef | grep vm1 | grep layer1.qcow2 … -blockdev {"driver":"file","filename":"/home/images/layer1.qcow2","node-name":"libvirt-1-storage","auto-read-only":true,"discard":"unmap"} -blockdev {"node-name":"libvirt-1-format","read-only":false,"driver":"qcow2","file":"libvirt-1-storage","backing":"libvirt-3-format"}
due to the fix of 'Bug 1798148 - Regression: Requested operation is not valid: format of backing image ... was not specified in the image metadata' the above test result is not valid now, detailed info can be found at that bz
Since the problem described in this bug report should be resolved in a recent advisory, it has been closed with a resolution of ERRATA. For information on the advisory, and where to find the updated files, follow the link below. If the solution does not work for you, open a new bug report. https://access.redhat.com/errata/RHBA-2020:2017