Bug 1788850 - libvirt cannot detect the format of qcow2 with native luks encryption
Summary: libvirt cannot detect the format of qcow2 with native luks encryption
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Red Hat Enterprise Linux Advanced Virtualization
Classification: Red Hat
Component: libvirt
Version: 8.2
Hardware: All
OS: Linux
medium
medium
Target Milestone: rc
: 8.0
Assignee: Peter Krempa
QA Contact: yisun
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2020-01-08 08:59 UTC by yisun
Modified: 2020-11-06 03:31 UTC (History)
8 users (show)

Fixed In Version: libvirt-6.0.0-1.el8
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Environment:
Last Closed: 2020-05-05 09:55:17 UTC
Type: Bug
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)


Links
System ID Private Priority Status Summary Last Updated
Red Hat Product Errata RHBA-2020:2017 0 None None None 2020-05-05 09:56:58 UTC

Description yisun 2020-01-08 08:59:59 UTC
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

Comment 1 yisun 2020-01-08 09:04:56 UTC
in reproduce step2 there is a redundant '# qemu-img create -f qcow2 no_luks.qcow2 1G'

Comment 2 Peter Krempa 2020-01-10 12:12:44 UTC
(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.

Comment 4 yisun 2020-02-12 08:54:29 UTC
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"}

Comment 5 yisun 2020-04-20 12:19:09 UTC
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

Comment 7 errata-xmlrpc 2020-05-05 09:55:17 UTC
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


Note You need to log in before you can comment on or make changes to this bug.