Bug 1445598

Summary: LUKS encrypted img not supported by "domblkthreshold"
Product: Red Hat Enterprise Linux 7 Reporter: yisun
Component: libvirtAssignee: Peter Krempa <pkrempa>
Status: CLOSED ERRATA QA Contact: yisun
Severity: medium Docs Contact:
Priority: medium    
Version: 7.4CC: hhan, jiyan, lmen, pkrempa, rbalakri, xuzhang
Target Milestone: rc   
Target Release: ---   
Hardware: x86_64   
OS: Linux   
Whiteboard:
Fixed In Version: libvirt-3.7.0-1.el7 Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2018-04-10 10:43:32 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On: 760547    
Bug Blocks:    

Description yisun 2017-04-26 05:23:06 UTC
Description of problem:
LUKS encrypted img not supported by "domblkthreshold"

Version-Release number of selected component (if applicable):
libvirt-3.2.0-2.el7.x86_64
qemu-kvm-rhev-2.9.0-1.el7.x86_64

How reproducible:
100%

Steps to Reproduce:
## qemu-img info /var/lib/libvirt/images/luks_1.img
image: /var/lib/libvirt/images/luks_1.img
file format: luks
virtual size: 1.0G (1073741824 bytes)
disk size: 33M
encrypted: yes
Format specific information:
    ivgen alg: plain64
    hash alg: sha256
    cipher alg: aes-256
    uuid: 37b40f65-3a2e-45ed-bdae-004b06ea601c
    cipher mode: xts

## virsh dumpxml vm1 | grep vdb -a10
...
    <disk type='file' device='disk'>
      <driver name='qemu' type='raw'/>
      <source file='/var/lib/libvirt/images/luks_1.img'/>
      <backingStore/>
      <target dev='vdb' bus='virtio'/>
      <encryption format='luks'>
        <secret type='passphrase' uuid='f981dd17-143f-45bc-88e6-ed1fe20ce9da'/>
      </encryption>
      <alias name='virtio-disk1'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x09' function='0x0'/>
    </disk>

## virsh start vm1
Domain vm1 started

## virsh domblklist vm1
Target     Source
------------------------------------------------
vda        /var/lib/libvirt/images/rhel7.3.qcow2
vdb        /var/lib/libvirt/images/luks_1.img


## virsh domblkthreshold vm1 vdb 100M
error: Operation not supported: threshold currently can't be set for block device 'vdb'

Actual results:
Error happened

Expected results:
No error and work well

Additional info:
This is separated from bz 1181659

Comment 2 Peter Krempa 2017-05-02 13:05:41 UTC
So the problem is that qemu reports the filename of the LUKS layer differently from the file name of the backing file:

"file": "json:{\"driver\": \"luks\", \"file\": {\"driver\": \"file\", \"filename\": \"/tmp/luks\"}, \"key-secret\": \"ide0-0-1-luks-secret0\"}"

vs.

"file": "/tmp/luks"

This means that the best-effort node name detection code is not able to figure out the node-name of the backing file.

This will be fixed by libvirt switching to provide node-names manually when starting qemu, rather than adding a temporary hack to the detection code.

Comment 4 Peter Krempa 2017-07-27 11:22:19 UTC
Upstream fixes this in the refactor of the node detection code:

commit 0175dc6ea024d4edd0f59571c3f5fa80d1ec1c0e
Author: Peter Krempa <pkrempa>
Date:   Wed Jul 26 09:36:21 2017 +0200

    qemu: block: Refactor node name detection code
    
    Remove the complex and unreliable code which inferred the node name
    hierarchy only from data returned by 'query-named-block-nodes'. It turns
    out that query-blockstats contain the full hierarchy of nodes as
    perceived by qemu so the inference code is not necessary.
    
    In query blockstats, the 'parent' object corresponds to the storage
    behind a storage volume and 'backing' corresponds to the lower level of
    backing chain. Since all have node names this data can be really easily
    used to detect node names.
    
    In addition to the code refactoring the one remaining test case needed
    to be fixed along.

Following test case shows that libvirt can detect the node name for the LUKS volume:

commit 86d8d11c148d6c99e53bbd92867c13d353530e5d
Author: Peter Krempa <pkrempa>
Date:   Thu Jul 27 10:26:41 2017 +0200

    tests: qemumonitorjson: Test extraction of LUKS node names
    
    Test file created by:
    
    qemu-img create -f luks /var/lib/libvirt/images/luks 10M \
            -o key-secret=asdf --object secret,id=asdf,format=raw,data=asdf
    
    Used in libvirt as:
     <disk type='file' device='disk'>
       <driver name='qemu' type='raw'/>
       <source file='/var/lib/libvirt/images/luks'/>
       <target dev='vda' bus='virtio'/>
       <encryption format='luks'>
         <secret type='passphrase' uuid='9b2c831a-fdb9-4c09-873c-1959580589e1'/>
       </encryption>
     </disk>

Comment 6 yisun 2017-10-31 08:10:26 UTC
Verified on: 
libvirt-3.8.0-1.el7.x86_64

PASSED


## cat secret
      <secret ephemeral='no' private='yes'>
         <description>LUKS Sample Secret</description>
         <usage type='volume'>
            <volume>/var/lib/libvirt/images/luks.img</volume>
         </usage>
      </secret>

## virsh secret-define secret 
Secret 55e8fb24-e630-4dc7-9de0-a1c2e2f7456a created

## MYSECRET=`printf %s "redhat" | base64`

## virsh secret-set-value 55e8fb24-e630-4dc7-9de0-a1c2e2f7456a $MYSECRET
Secret value set

## qemu-img create -f luks --object secret,id=sec0,data=`printf %s "redhat" | base64`,format=base64 -o key-secret=sec0 /var/lib/libvirt/images/luks.img 1G

## qemu-img create -f luks --object secret,id=sec0,data=`printf %s "redhat" | base64`,format=base64 -o key-secret=sec0 /var/lib/libvirt/images/luks.img 1G
Formatting '/var/lib/libvirt/images/luks.img', fmt=luks size=1073741824 key-secret=sec0

## virsh dumpxml v | grep secret -a6
...
    <disk type='file' device='disk'>
      <driver name='qemu' type='raw'/>
      <source file='/var/lib/libvirt/images/luks.img'/>
      <target dev='vdb' bus='virtio'/>
      <encryption format='luks'>
        <secret type='passphrase' uuid='55e8fb24-e630-4dc7-9de0-a1c2e2f7456a'/>
      </encryption>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </disk>
...

## virsh domblklist v
Target     Source
------------------------------------------------
...
vdb        /var/lib/libvirt/images/luks.img

## virsh domblkthreshold v vdb 100M; echo $?
0

## virsh domstats v --block | grep threshold
  block.1.threshold=104857600

## virsh event --event block-threshold --loop

use virt-manager or another termianl to login the VM, and in VM, run:
root@vm # dd if=/dev/urandom of=/dev/vda bs=1M count=101
101+0 records in
101+0 records out
105906176 bytes (106 MB) copied, 1.46398 s, 72.3 MB/s

back to test host, and event captrued as follow:
## virsh event --event block-threshold --loop
event 'block-threshold' for domain v: dev: vdb(/var/lib/libvirt/images/luks.img) 104857600 4096

Comment 10 errata-xmlrpc 2018-04-10 10:43:32 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/RHEA-2018:0704