Bug 1406803 - RFE: native integration of LUKS and qcow2
Summary: RFE: native integration of LUKS and qcow2
Status: CLOSED ERRATA
Alias: None
Product: Red Hat Enterprise Linux 7
Classification: Red Hat
Component: qemu-kvm-rhev
Version: 7.4
Hardware: Unspecified
OS: Unspecified
high
unspecified
Target Milestone: rc
: 7.4
Assignee: Daniel Berrange
QA Contact: Ping Li
URL:
Whiteboard: epm-rr
Keywords: FutureFeature
Depends On:
Blocks: 1440112 1449793 1461180 1518999 1522983 1230405 1273812 1305024 1352501 1406805 1558125
TreeView+ depends on / blocked
 
Reported: 2016-12-21 14:19 UTC by Daniel Berrange
Modified: 2018-04-11 00:15 UTC (History)
27 users (show)

(edit)
Clone Of:
(edit)
Last Closed: 2018-04-11 00:12:33 UTC


Attachments (Terms of Use)


External Trackers
Tracker ID Priority Status Summary Last Updated
Red Hat Product Errata RHSA-2018:1104 None None None 2018-04-11 00:15 UTC

Description Daniel Berrange 2016-12-21 14:19:10 UTC
Description of problem:
While there is a generic LUKS driver for QEMU that can be layered above or below any block backend, neither of these options are desirable in combination with QCow2.

If layered below qcow2, both the header & payload are encrypted making it impossible to query basic info about the qcow2 volume (eg its size) without decrypting it first.

If layered above qcow2, the payload is encrypted using virtual disk sector numbers as the input for initialization vectors. This is insecure when combined with qcow2 internal snapshots, since data in each snapshot will use the same initialization vector for any given guest sector.

Thus native integration of LUKS & qcow2 is required to provide a hybrid approach. Only the disk payload will be encrypted, but IVs will use the physical sector offset to guarantee unique IVs for snapshots.

Version-Release number of selected component (if applicable):
2.8.0-1.el7

Comment 4 Daniel Berrange 2017-06-27 08:57:36 UTC
Latest upstream posting:

  https://lists.gnu.org/archive/html/qemu-devel/2017-06/msg05391.html

this is getting pretty close to acceptable for merge - only nit-picking comments remain.

Comment 5 Ping Li 2017-09-27 06:07:30 UTC
Hi Daniel,

As the flag rhel-7.5.0+ is set, QE wonder to know whether the issue will be fixed in rhel 7.5? Then qe can add it to RHEL 7.5 test plan for disk format. 

If we have plan to fix it in rhel 7.5, could you help to share how to verify this issue?

Thanks.

Comment 6 Daniel Berrange 2017-09-27 15:41:30 UTC
This feature was included in the upstream 2.10 release of QEMU, so will come into RHEL as part of the rebase in 7.5

Comment 7 Ping Li 2017-09-27 15:59:06 UTC
(In reply to Daniel Berrange from comment #6)
> This feature was included in the upstream 2.10 release of QEMU, so will come
> into RHEL as part of the rebase in 7.5

Could you help to share how does QE verify this bug? Thanks in advance

Comment 8 Daniel Berrange 2017-10-02 10:42:00 UTC
Here is a simple example of creating some images and booting a VM with them

First create a base image:

$ qemu-img create --object secret,id=sec0,data=123456 -f qcow2 -o encrypt.format=luks,encrypt.key-secret=sec0 base.qcow2 1G

Boot a VM and install onto this encrypted disk

$ qemu-system-x86_64 --object secret,id=sec0,data=123456 -drive driver=qcow2,file.filename=base.qcow2,encrypt.key-secret=sec0 -cdrom ...path to install ISO...   ...other args...


Now shutdown the VM, and lets create a layered qcow2 image using a *different* password

$ qemu-img create --object secret,id=sec0,data=654321 -f qcow2 -o encrypt.format=luks,encrypt.key-secret=sec0,backing_file=demo.qcow2,backing_fmt=qcow2 new.qcow2 1G


and now boot the VM with this layered image

$ qemu-system-x86_64 --object secret,id=sec0,data=654321 --object secret,id=sec1,data=123456 -drive driver=qcow2,file.filename=new.qcow2,encrypt.key-secret=sec0,backing.encrypt.key-secret=sec1

notice how we have to give 2 passwords - one for each layer.

Finally inspect with qemu-img info to see it reporting encryption usage

qemu-img info new.qcow2 
image: new.qcow2
file format: qcow2
virtual size: 1.0G (1073741824 bytes)
disk size: 480K
encrypted: yes
cluster_size: 65536
backing file: demo.qcow2
backing file format: qcow2
Format specific information:
    compat: 1.1
    lazy refcounts: false
    refcount bits: 16
    encrypt:
        ivgen alg: plain64
        hash alg: sha256
        cipher alg: aes-256
        uuid: 99bf5b9a-90f7-42e8-9a06-60e1b3a50430
        format: luks
        cipher mode: xts
        slots:
            [0]:
                active: true
                iters: 1643246
                key offset: 4096
                stripes: 4000
            [1]:
                active: false
                key offset: 262144
            [2]:
                active: false
                key offset: 520192
            [3]:
                active: false
                key offset: 778240
            [4]:
                active: false
                key offset: 1036288
            [5]:
                active: false
                key offset: 1294336
            [6]:
                active: false
                key offset: 1552384
            [7]:
                active: false
                key offset: 1810432
        payload offset: 2068480
        master key iters: 414560
    corrupt: false


Notice the info about 'luks' and key-slots there.

This is not an exhaustive list of all things that need to be tested - other common operations dealing with qcow2 files should be tested with luks enabled - the syntax shown above illustrates how to deal with it.

Comment 10 Ping Li 2017-10-12 11:26:39 UTC
Hi Daniel,

After tried the function according to your guidance, found below issues. Could you help to check it?

Version-Release number of selected component:
kernel-3.10.0-734.el7.x86_64
qemu-kvm-rhev-2.10.0-1.el7

Q1: Sub-command check needs specifying encryption key, but info can be executed without the key.
Q2: Only the difference between specify encryption key and without key for info is image name. One is the normal name, the other one is the name with json format.

# qemu-img check base.qcow2
qemu-img: Could not open 'base.qcow2': Parameter 'encrypt.key-secret' is required for cipher

# qemu-img check --object secret,id=sec0,data=base --image-opts driver=qcow2,encrypt.key-secret=sec0,file.filename=base.qcow2 
No errors were found on the image.
Image end offset: 2359296

# qemu-img info base.qcow2    --------> command returns successfully without specify encryption key
image: base.qcow2    --------> display image name
file format: qcow2
virtual size: 5.0G (5368709120 bytes)
disk size: 540K
encrypted: yes
cluster_size: 65536
Format specific information:
    compat: 1.1
    lazy refcounts: false
    refcount bits: 16
    encrypt:
        ivgen alg: plain64
        hash alg: sha256
        cipher alg: aes-256
        uuid: 4bd800f8-14a7-48e9-a28f-17bde6b5ef5b
        format: luks
        cipher mode: xts
        slots:
            [0]:
                active: true
                iters: 1672598
                key offset: 4096
                stripes: 4000
            [1]:
                active: false
                key offset: 262144
            [2]:
                active: false
                key offset: 520192
            [3]:
                active: false
                key offset: 778240
            [4]:
                active: false
                key offset: 1036288
            [5]:
                active: false
                key offset: 1294336
            [6]:
                active: false
                key offset: 1552384
            [7]:
                active: false
                key offset: 1810432
        payload offset: 2068480
        master key iters: 416670
    corrupt: false

# qemu-img info --object secret,id=sec0,data=base --image-opts driver=qcow2,encrypt.key-secret=sec0,file.filename=base.qcow2    --------> command returns successfully without specify encryption key
image: json:{"encrypt.key-secret": "sec0", "driver": "qcow2", "file": {"driver": "file", "filename": "base.qcow2"}}    --------> json format

Q3: Failed to create snapshot as what you created

1) don't specify image size
# qemu-img create --object secret,id=sec1,data=snapshot -f qcow2 -o encrypt.format=luks,encrypt.key-secret=sec1,backing_file=base.qcow2,backing_fmt=qcow2 sn.qcow2
qemu-img: sn.qcow2: Parameter 'encrypt.key-secret' is required for cipher
Could not open backing image to determine size.

2)specify image size. Success due to bug 1213786, and got warning message. 
# qemu-img create --object secret,id=sec1,data=snapshot -f qcow2 -o encrypt.format=luks,encrypt.key-secret=sec1,backing_file=base.qcow2,backing_fmt=qcow2 sn.qcow2 5G
qemu-img: warning: Could not verify backing image. This may become an error in future versions.
Parameter 'encrypt.key-secret' is required for cipher
Formatting 'sn.qcow2', fmt=qcow2 size=5368709120 backing_file=base.qcow2 backing_fmt=qcow2 encrypt.format=luks encrypt.key-secret=sec1 cluster_size=65536 lazy_refcounts=off refcount_bits=16

3) Success using json format to specify backing file and snapshot could boot up smoothly
# qemu-img create --object secret,id=sec0,data=base --object secret,id=sec1,data=snapshot -f qcow2 -o encrypt.format=luks,encrypt.key-secret=sec1 -b 'json:{"encrypt.key-secret": "sec0", "driver": "qcow2", "file": {"driver": "file", "filename": "/home/tests/diskfile/base.qcow2"}}' sn.qcow2
Formatting 'sn.qcow2', fmt=qcow2 size=5368709120 backing_file=json:{"encrypt.key-secret": "sec0",, "driver": "qcow2",, "file": {"driver": "file",, "filename": "/home/tests/diskfile/base.qcow2"}} encrypt.format=luks encrypt.key-secret=sec1 cluster_size=65536 lazy_refcounts=off refcount_bits=16

Q4. Success to check snapshot but failed to get the info of snapshot when specify the encryption key.
# qemu-img check --object secret,id=sec0,data=base --object secret,id=sec1,data=snapshot --image-opts driver=qcow2,encrypt.key-secret=sec1,file.filename=sn.qcow2,backing.encrypt.key-secret=sec0
No errors were found on the image.
Image end offset: 2359296
# qemu-img info --object secret,id=sec0,data=base --object secret,id=sec1,data=snapshot --image-opts driver=qcow2,encrypt.key-secret=sec1,file.filename=sn.qcow2,backing.encrypt.key-secret=sec0
qemu-img: Could not open 'driver=qcow2,encrypt.key-secret=sec1,file.filename=sn.qcow2,backing.encrypt.key-secret=sec0': Block format 'qcow2' does not support the option 'backing.encrypt.key-secret'

# qemu-img info sn.qcow2 
image: sn.qcow2
file format: qcow2
virtual size: 5.0G (5368709120 bytes)
disk size: 540K
encrypted: yes
cluster_size: 65536
backing file: json:{"encrypt.key-secret": "sec0", "driver": "qcow2", "file": {"driver": "file", "filename": "/home/tests/diskfile/base.qcow2"}}
Format specific information:
    compat: 1.1
    lazy refcounts: false
    refcount bits: 16
    encrypt:
        ivgen alg: plain64
        hash alg: sha256
        cipher alg: aes-256
        uuid: 472d8cb0-13a5-47d4-acdb-92009e349b94
        format: luks
        cipher mode: xts
        slots:
            [0]:
                active: true
                iters: 1703656
                key offset: 4096
                stripes: 4000
            [1]:
                active: false
                key offset: 262144
            [2]:
                active: false
                key offset: 520192
            [3]:
                active: false
                key offset: 778240
            [4]:
                active: false
                key offset: 1036288
            [5]:
                active: false
                key offset: 1294336
            [6]:
                active: false
                key offset: 1552384
            [7]:
                active: false
                key offset: 1810432
        payload offset: 2068480
        master key iters: 416708
    corrupt: false

Comment 11 Ping Li 2017-10-27 16:25:13 UTC
Hi Daniel,

I have tested the feature according to the comment https://bugzilla.redhat.com/show_bug.cgi?id=1406803#c8.
Below problems are found during my test. Could you help to check it? Thanks in advance.

1) When specifying wrong password for encryption key, image information could be gotten successfully(refer to 1.4).
I think it should be failed to get it.   
2) Failed to create snapshot, if don't specify encryption key for backing file(refer 3.1). The only approach I found 
to create snapshot is using json format to specify the encryption key of backing file(refer to 3.2). Shall we have 
some other options to specify it?
3) Behavior for qemu-img info and check set option backing.encrypt.key-secret(refer to 3.4). 
4) Fail to boot snapshot according to the cml in comment 8(refer to 3.5).
5) After commit snapshot to backing file, snapshot cannot be opened(refer to 4.2).
6) Change the encryption key of image through amend will make qemu-img to be aborted(refer to 6.1).
7) Fail to check snapshot, after change the backing file of the image(refer to 7.2)
8) How can i specify the encryption key for sub-command compare?
compare [--object objectdef] [--image-opts] [-f fmt] [-F fmt] [-T src_cache] [-p] [-q] [-s] [-U] filename1 filename2
9) Fail to create image with luks enabled on fedora(refer to additional info)


Packages tested:
kernel-3.10.0-745.el7.x86_64
qemu-kvm-rhev-2.10.0-3.el7

Test steps:
1. Create a base image.
1.1 create image
# qemu-img create --object secret,id=sec0,data=backing -f qcow2 -o encrypt.format=luks,encrypt.key-secret=sec0 base.qcow2 5G
Formatting 'base.qcow2', fmt=qcow2 size=5368709120 encrypt.format=luks encrypt.key-secret=sec0 cluster_size=65536 lazy_refcounts=off refcount_bits=16

1.2 Run qemu-img info & check on the image without specifying encryption key:
# qemu-img info base.qcow2      ------> Also pass to get information
image: base.qcow2      ------> Show image name as usual
file format: qcow2
virtual size: 5.0G (5368709120 bytes)
disk size: 540K
encrypted: yes
cluster_size: 65536
Format specific information:
    compat: 1.1
    lazy refcounts: false
    refcount bits: 16
    encrypt:
        ivgen alg: plain64
        hash alg: sha256
        cipher alg: aes-256
        uuid: 4d609a17-de8d-44ba-88fd-8b65869ab665
        format: luks
        cipher mode: xts
        slots:
            [0]:
                active: true
                iters: 647574
                key offset: 4096
                stripes: 4000
            [1]:
                active: false
                key offset: 262144
            [2]:
                active: false
                key offset: 520192
            [3]:
                active: false
                key offset: 778240
            [4]:
                active: false
                key offset: 1036288
            [5]:
                active: false
                key offset: 1294336
            [6]:
                active: false
                key offset: 1552384
            [7]:
                active: false
                key offset: 1810432
        payload offset: 2068480
        master key iters: 161897
    corrupt: false

# qemu-img check base.qcow2      ------> Failed to check the image, it should be as expected.
qemu-img: Could not open 'base.qcow2': Parameter 'encrypt.key-secret' is required for cipher

1.3 Run qemu-img info & check on the image with specifying encryption key:
# qemu-img info --object secret,id=sec0,data=backing --image-opts driver=qcow2,encrypt.key-secret=sec0,file.filename=base.qcow2 
image: json:{"encrypt.key-secret": "sec0", "driver": "qcow2", "file": {"driver": "file", "filename": "base.qcow2"}}      ------> Show image name with json format. It should be as expected, as i used different format to give information.
file format: qcow2
virtual size: 5.0G (5368709120 bytes)
disk size: 540K
encrypted: yes
cluster_size: 65536
Format specific information:
    compat: 1.1
    lazy refcounts: false
    refcount bits: 16
    encrypt:
        ivgen alg: plain64
        hash alg: sha256
        cipher alg: aes-256
        uuid: 4d609a17-de8d-44ba-88fd-8b65869ab665
        format: luks
        cipher mode: xts
        slots:
            [0]:
                active: true
                iters: 647574
                key offset: 4096
                stripes: 4000
            [1]:
                active: false
                key offset: 262144
            [2]:
                active: false
                key offset: 520192
            [3]:
                active: false
                key offset: 778240
            [4]:
                active: false
                key offset: 1036288
            [5]:
                active: false
                key offset: 1294336
            [6]:
                active: false
                key offset: 1552384
            [7]:
                active: false
                key offset: 1810432
        payload offset: 2068480
        master key iters: 161897
    corrupt: false

# qemu-img check --object secret,id=sec0,data=backing --image-opts driver=qcow2,encrypt.key-secret=sec0,file.filename=base.qcow2 
No errors were found on the image.
Image end offset: 2359296

1.4 Run qemu-img info & check with specifying wrong encryption key:
# qemu-img info --object secret,id=sec0,data=wrong --image-opts driver=qcow2,encrypt.key-secret=sec0,file.filename=base.qcow2
image: json:{"encrypt.key-secret": "sec0", "driver": "qcow2", "file": {"driver": "file", "filename": "base.qcow2"}}
file format: qcow2
virtual size: 5.0G (5368709120 bytes)
disk size: 1.2G
encrypted: yes
cluster_size: 65536
Format specific information:
    compat: 1.1
    lazy refcounts: false
    refcount bits: 16
    encrypt:
        ivgen alg: plain64
        hash alg: sha256
        cipher alg: aes-256
        uuid: 4d609a17-de8d-44ba-88fd-8b65869ab665
        format: luks
        cipher mode: xts
        slots:
            [0]:
                active: true
                iters: 647574
                key offset: 4096
                stripes: 4000
            [1]:
                active: false
                key offset: 262144
            [2]:
                active: false
                key offset: 520192
            [3]:
                active: false
                key offset: 778240
            [4]:
                active: false
                key offset: 1036288
            [5]:
                active: false
                key offset: 1294336
            [6]:
                active: false
                key offset: 1552384
            [7]:
                active: false
                key offset: 1810432
        payload offset: 2068480
        master key iters: 161897
    corrupt: false
# qemu-img check --object secret,id=sec0,data=wrong --image-opts driver=qcow2,encrypt.key-secret=sec0,file.filename=base.qcow2
qemu-img: Could not open 'driver=qcow2,encrypt.key-secret=sec0,file.filename=base.qcow2': Invalid password, cannot unlock any keyslot

2. Boot a guest and install OS on the image.
    --object secret,id=sec0,data=backing \
    -drive id=drive_image1,driver=qcow2,file.filename=/home/tests/test/base.qcow2,encrypt.key-secret=sec0,if=none,snapshot=off,aio=native,cache=none \
    -device virtio-blk-pci,id=image1,drive=drive_image1,bootindex=0,bus=pci.0,addr=0x3 \
or
    --object secret,id=sec0,data=backing \
    -drive id=drive_image1,encrypt.key-secret=sec0,if=none,snapshot=off,aio=native,cache=none,format=qcow2,file=/home/tests/test/base.qcow2 \
    -device virtio-blk-pci,id=image1,drive=drive_image1,bootindex=0,bus=pci.0,addr=0x3 \

(qemu) info block
drive_image1 (#block163): json:{"encrypt.key-secret": "sec0", "driver": "qcow2", "file": {"driver": "file", "filename": "/home/tests/test/base.qcow2"}} (qcow2, encrypted)
    Attached to:      /machine/peripheral/image1/virtio-backend
    Cache mode:       writeback, direct

3. Create a snapshot using a different password.
3.1 Create snapshot without specifying encryption key for backing file.      ------> Snapshot created due to bug 1213786. Snapshot cannot be created if don't specify image size.
# qemu-img create --object secret,id=sec1,data=snaphot -f qcow2 -o encrypt.format=luks,encrypt.key-secret=sec1,backing_file=base.qcow2,backing_fmt=qcow2 sn.qcow2 5G
qemu-img: warning: Could not verify backing image. This may become an error in future versions.
Parameter 'encrypt.key-secret' is required for cipher
Formatting 'sn.qcow2', fmt=qcow2 size=5368709120 backing_file=base.qcow2 backing_fmt=qcow2 encrypt.format=luks encrypt.key-secret=sec1 cluster_size=65536 lazy_refcounts=off refcount_bits=16

3.2 Create snapshot using json format to specify backing file.
# qemu-img create --object secret,id=sec0,data=backing --object secret,id=sec1,data=snaphot -f qcow2 -o encrypt.format=luks,encrypt.key-secret=sec1 -b 'json:{"encrypt.key-secret": "sec0", "driver": "qcow2", "file": {"driver": "file", "filename": "/home/tests/test/base.qcow2"}}' sn.qcow2
Formatting 'sn.qcow2', fmt=qcow2 size=21474836480 backing_file=json:{"encrypt.key-secret": "sec0",, "driver": "qcow2",, "file": {"driver": "file",, "filename": "/home/tests/test/base.qcow2"}} encrypt.format=luks encrypt.key-secret=sec1 cluster_size=65536 lazy_refcounts=off refcount_bits=16

3.3 Run qemu-img info & check on the image with specifying encryption key:
# qemu-img check --object secret,id=sec0,data=backing --object secret,id=sec1,data=snaphot --image-opts driver=qcow2,encrypt.key-secret=sec1,file.filename=sn.qcow2
No errors were found on the image.
Image end offset: 2359296

# qemu-img info --object secret,id=sec0,data=backing --object secret,id=sec1,data=snaphot --image-opts driver=qcow2,encrypt.key-secret=sec1,file.filename=sn.qcow2
image: json:{"encrypt.key-secret": "sec1", "driver": "qcow2", "file": {"driver": "file", "filename": "sn.qcow2"}}
file format: qcow2
virtual size: 5.0G (5368709120 bytes)
disk size: 540K
encrypted: yes
cluster_size: 65536
backing file: json:{"encrypt.key-secret": "sec0", "driver": "qcow2", "file": {"driver": "file", "filename": "/home/tests/test/base.qcow2"}}
Format specific information:
    compat: 1.1
    lazy refcounts: false
    refcount bits: 16
    encrypt:
        ivgen alg: plain64
        hash alg: sha256
        cipher alg: aes-256
        uuid: 2b9e3e2b-9c30-4e25-9990-8e02cd3819e2
        format: luks
        cipher mode: xts
        slots:
            [0]:
                active: true
                iters: 647574
                key offset: 4096
                stripes: 4000
            [1]:
                active: false
                key offset: 262144
            [2]:
                active: false
                key offset: 520192
            [3]:
                active: false
                key offset: 778240
            [4]:
                active: false
                key offset: 1036288
            [5]:
                active: false
                key offset: 1294336
            [6]:
                active: false
                key offset: 1552384
            [7]:
                active: false
                key offset: 1810432
        payload offset: 2068480
        master key iters: 161897
    corrupt: false

3.4 Run qemu-img info & check on the image using option backing.encrypt.key-secret.      ------> Should give same error prompt "Block format 'qcow2' does not support the option 'backing.encrypt.key-secret'"
# qemu-img check --object secret,id=sec0,data=backing --object secret,id=sec1,data=snaphot --image-opts driver=qcow2,encrypt.key-secret=sec1,file.filename=sn.qcow2,backing.encrypt.key-secret=sec0
No errors were found on the image.
Image end offset: 2359296
# qemu-img info --object secret,id=sec0,data=backing --object secret,id=sec1,data=snaphot --image-opts driver=qcow2,encrypt.key-secret=sec1,file.filename=sn.qcow2,backing.encrypt.key-secret=sec0
qemu-img: Could not open 'driver=qcow2,encrypt.key-secret=sec1,file.filename=sn.qcow2,backing.encrypt.key-secret=sec0': Block format 'qcow2' does not support the option 'backing.encrypt.key-secret'

3.5 Boot a guest with snapshot
    --object secret,id=sec0,data=backing \
    --object secret,id=sec1,data=snapshot \
    -drive id=drive_image1,driver=qcow2,file.filename=/home/tests/test/sn.qcow2,encrypt.key-secret=sec1,backing.encrypt.key-secret=sec0,if=none,snapshot=off,aio=native,cache=none \
    -device virtio-blk-pci,id=image1,drive=drive_image1,bootindex=0,bus=pci.0,addr=0x3 \

qemu-kvm: -drive id=drive_image1,driver=qcow2,file.filename=/home/tests/test/sn.qcow2,encrypt.key-secret=sec1,backing.encrypt.key-secret=sec0,if=none,snapshot=off,aio=native,cache=none: Invalid password, cannot unlock any keyslot

4. Commit the changes to backing file
4.1 Commit snapshot to base.
# qemu-img commit --object secret,id=sec0,data=backing --object secret,id=sec1,data=snaphot --image-opts driver=qcow2,encrypt.key-secret=sec1,file.filename=sn.qcow2
Image committed.

4.2 Get information and check image
# qemu-img check --object secret,id=sec0,data=backing --object secret,id=sec1,data=snaphot --image-opts driver=qcow2,encrypt.key-secret=sec1,file.filename=sn.qcow2
qemu-img: Could not open 'driver=qcow2,encrypt.key-secret=sec1,file.filename=sn.qcow2': Volume is not in LUKS format

# qemu-img info --object secret,id=sec0,data=backing --object secret,id=sec1,data=snaphot --image-opts driver=qcow2,encrypt.key-secret=sec1,file.filename=sn.qcow2
qemu-img: Could not open 'driver=qcow2,encrypt.key-secret=sec1,file.filename=sn.qcow2': Volume is not in LUKS format

# qemu-img info sn.qcow2 
qemu-img: Could not open 'sn.qcow2': Volume is not in LUKS format

5. Convert base image to a qcow2 image using a different password
5.1 Convert image
# qemu-img convert -p --object secret,id=sec0,data=backing --object secret,id=sec2,data=convert --image-opts driver=qcow2,encrypt.key-secret=sec0,file.filename=base.qcow2 -O qcow2 -o encrypt.format=luks,encrypt.key-secret=sec2 convert.qcow2

5.2 Get information and check image(Both info and check operation can be executed successfully)
# qemu-img info --object secret,id=sec2,data=convert --image-opts driver=qcow2,encrypt.key-secret=sec2,file.filename=convert.qcow2
# qemu-img check --object secret,id=sec2,data=convert --image-opts driver=qcow2,encrypt.key-secret=sec2,file.filename=convert.qcow2

6. Amend the converted image
6.1 Change the encryption key      ------> Should be a bug, qemu-img is aborted
# qemu-img amend --object secret,id=sec2,data=convert --object secret,id=sec3,data=amend --image-opts driver=qcow2,encrypt.key-secret=sec2,file.filename=convert.qcow2 -o encrypt.key-secret=sec3
Aborted

6.2 Downgrade the version of qcow2 image
# qemu-img amend -p --object secret,id=sec2,data=convert --image-opts driver=qcow2,encrypt.key-secret=sec2,file.filename=convert.qcow2 -o compat=0.10
# qemu-img info convert.qcow2 
image: convert.qcow2
file format: qcow2
virtual size: 5.0G (5368709120 bytes)
disk size: 2.0G
encrypted: yes
cluster_size: 65536
Format specific information:
    compat: 0.10
    ...

7. Rebase the snapshot to the converted image
7.1 Rebase image
# qemu-img rebase --object secret,id=sec0,data=backing --object secret,id=sec1,data=snaphot --object secret,id=sec2,data=convert --image-opts driver=qcow2,encrypt.key-secret=sec1,file.filename=sn.qcow2 -b 'json:{"encrypt.key-secret": "sec2", "driver": "qcow2", "file": {"driver": "file", "filename": "/home/tests/test/convert.qcow2"}}'

7.2 Get information and check image
# qemu-img info sn.qcow2 
image: sn.qcow2
file format: qcow2
virtual size: 5.0G (5368709120 bytes)
disk size: 16M
encrypted: yes
cluster_size: 65536
backing file: json:{"encrypt.key-secret": "sec2", "driver": "qcow2", "file": {"driver": "file", "filename": "/home/tests/test/convert.qcow2"}}
Format specific information:
    compat: 1.1
    lazy refcounts: false
    refcount bits: 16
    encrypt:
        ivgen alg: plain64
        hash alg: sha256
        cipher alg: aes-256
        uuid: 2b9e3e2b-9c30-4e25-9990-8e02cd3819e2
        format: luks
        cipher mode: xts
        slots:
            [0]:
                active: true
                iters: 647574
                key offset: 4096
                stripes: 4000
            [1]:
                active: false
                key offset: 262144
            [2]:
                active: false
                key offset: 520192
            [3]:
                active: false
                key offset: 778240
            [4]:
                active: false
                key offset: 1036288
            [5]:
                active: false
                key offset: 1294336
            [6]:
                active: false
                key offset: 1552384
            [7]:
                active: false
                key offset: 1810432
        payload offset: 2068480
        master key iters: 161897
    corrupt: false

# qemu-img check --object secret,id=sec1,data=snapshot --object secret,id=sec2,data=convert --image-opts driver=qcow2,encrypt.key-secret=sec1,file.filename=sn.qcow2
qemu-img: Could not open 'driver=qcow2,encrypt.key-secret=sec1,file.filename=sn.qcow2': Invalid password, cannot unlock any keyslot

8. Change image size
8.1 Resize image
# qemu-img resize --object secret,id=sec0,data=backing --image-opts driver=qcow2,encrypt.key-secret=sec0,file.filename=base.qcow2 +1G 
Image resized.

8.2 Get information and check image
# qemu-img info --object secret,id=sec0,data=backing --image-opts driver=qcow2,encrypt.key-secret=sec0,file.filename=base.qcow2
image: json:{"encrypt.key-secret": "sec0", "driver": "qcow2", "file": {"driver": "file", "filename": "base.qcow2"}}
file format: qcow2
virtual size: 6.0G (6442450944 bytes)
disk size: 3.2G
encrypted: yes

# qemu-img check --object secret,id=sec0,data=backing --image-opts driver=qcow2,encrypt.key-secret=sec0,file.filename=base.qcow2
No errors were found on the image.
20441/98304 = 20.79% allocated, 13.69% fragmented, 0.00% compressed clusters
Image end offset: 1342701568

Additional info:
When i tried it on Fedora, found error below:
$ /home/pingl/workspace/software/qemu-2.10.1/qemu-img create --object secret,id=sec0,data=123456 -f qcow2 -o encrypt.format=luks,encrypt.key-secret=sec0 base.qcow2 1G
Formatting 'base.qcow2', fmt=qcow2 size=1073741824 encrypt.format=luks encrypt.key-secret=sec0 cluster_size=65536 lazy_refcounts=off refcount_bits=16
qemu-img: base.qcow2: No crypto library supporting PBKDF in this build: Function not implemented

Comment 12 Daniel Berrange 2017-11-03 11:01:39 UTC
(In reply to pingl from comment #10)
> Q1: Sub-command check needs specifying encryption key, but info can be
> executed without the key.

This is correct. The 'info' command never requires the key, as users must be able to query any image, without knowing what format it is.


> Q3: Failed to create snapshot as what you created
> 
> 1) don't specify image size
> # qemu-img create --object secret,id=sec1,data=snapshot -f qcow2 -o
> encrypt.format=luks,encrypt.key-secret=sec1,backing_file=base.qcow2,
> backing_fmt=qcow2 sn.qcow2
> qemu-img: sn.qcow2: Parameter 'encrypt.key-secret' is required for cipher
> Could not open backing image to determine size.

Yeah, IIUC, this is a limitation of the backing_file option - to avoid that we need
to use the json syntax for backing file as you have shown in 3).

> 2)specify image size. Success due to bug 1213786, and got warning message. 
> # qemu-img create --object secret,id=sec1,data=snapshot -f qcow2 -o
> encrypt.format=luks,encrypt.key-secret=sec1,backing_file=base.qcow2,
> backing_fmt=qcow2 sn.qcow2 5G
> qemu-img: warning: Could not verify backing image. This may become an error
> in future versions.
> Parameter 'encrypt.key-secret' is required for cipher
> Formatting 'sn.qcow2', fmt=qcow2 size=5368709120 backing_file=base.qcow2
> backing_fmt=qcow2 encrypt.format=luks encrypt.key-secret=sec1
> cluster_size=65536 lazy_refcounts=off refcount_bits=16

Yep, this is ok (for now)

> 3) Success using json format to specify backing file and snapshot could boot
> up smoothly
> # qemu-img create --object secret,id=sec0,data=base --object
> secret,id=sec1,data=snapshot -f qcow2 -o
> encrypt.format=luks,encrypt.key-secret=sec1 -b 'json:{"encrypt.key-secret":
> "sec0", "driver": "qcow2", "file": {"driver": "file", "filename":
> "/home/tests/diskfile/base.qcow2"}}' sn.qcow2
> Formatting 'sn.qcow2', fmt=qcow2 size=5368709120
> backing_file=json:{"encrypt.key-secret": "sec0",, "driver": "qcow2",,
> "file": {"driver": "file",, "filename": "/home/tests/diskfile/base.qcow2"}}
> encrypt.format=luks encrypt.key-secret=sec1 cluster_size=65536
> lazy_refcounts=off refcount_bits=16

Yes. That's fine

> Q4. Success to check snapshot but failed to get the info of snapshot when
> specify the encryption key.


> # qemu-img info --object secret,id=sec0,data=base --object
> secret,id=sec1,data=snapshot --image-opts
> driver=qcow2,encrypt.key-secret=sec1,file.filename=sn.qcow2,backing.encrypt.
> key-secret=sec0
> qemu-img: Could not open
> 'driver=qcow2,encrypt.key-secret=sec1,file.filename=sn.qcow2,backing.encrypt.
> key-secret=sec0': Block format 'qcow2' does not support the option
> 'backing.encrypt.key-secret'

The 'qemu-img info' command does not allow specification of any 'backing.*' options. Even if it did, there is no need to pass a key secret because querying 'info' does not need decryption

Comment 13 Daniel Berrange 2017-11-03 13:10:06 UTC
(In reply to Ping Li from comment #11)
> Hi Daniel,
> 
> I have tested the feature according to the comment
> https://bugzilla.redhat.com/show_bug.cgi?id=1406803#c8.
> Below problems are found during my test. Could you help to check it? Thanks
> in advance.
> 
> 1) When specifying wrong password for encryption key, image information
> could be gotten successfully(refer to 1.4).
> I think it should be failed to get it.   

Encryption *only* protects the image payload, not the metadata. The 'info' command never needs the password, so whatever value you provide is ignored.

> 2) Failed to create snapshot, if don't specify encryption key for backing
> file(refer 3.1). The only approach I found 
> to create snapshot is using json format to specify the encryption key of
> backing file(refer to 3.2). Shall we have 
> some other options to specify it?

Yes, specifying either the size, or using JSON syntax is required


> 3) Behavior for qemu-img info and check set option
> backing.encrypt.key-secret(refer to 3.4). 

The 'info' command doesn't accept (or need) any 'backing.*' options

> 4) Fail to boot snapshot according to the cml in comment 8(refer to 3.5).

You have a typo in the password used.

> 5) After commit snapshot to backing file, snapshot cannot be opened(refer to
> 4.2).

Yes, this is a serious image corruption bug


> 6) Change the encryption key of image through amend will make qemu-img to be
> aborted(refer to 6.1).

This is a minor bug - it should report an error message instead of aborting.


> 7) Fail to check snapshot, after change the backing file of the image(refer
> to 7.2)

You have a typo in your password again here.

> 8) How can i specify the encryption key for sub-command compare?
> compare [--object objectdef] [--image-opts] [-f fmt] [-F fmt] [-T src_cache]
> [-p] [-q] [-s] [-U] filename1 filename2

The same kind of syntax as other commands

eg 

$ qemu-img compare --object secret,id=sec1,data=one --object secret,id=sec2,data=two --image-opts driver=qcow2,encrypt.key-secret=sec1,file.filename=one.qcow2  driver=qcow2,encrypt.key-secret=sec2,file.filename=two.qcow2


> 9) Fail to create image with luks enabled on fedora(refer to additional info)


Seems you have mis-built the Fedora QEMU




> 1.4 Run qemu-img info & check with specifying wrong encryption key:

'info' doesn't use the encryption key, so leave that bit out.

> # qemu-img check --object secret,id=sec0,data=wrong --image-opts
> driver=qcow2,encrypt.key-secret=sec0,file.filename=base.qcow2
> qemu-img: Could not open
> 'driver=qcow2,encrypt.key-secret=sec0,file.filename=base.qcow2': Invalid
> password, cannot unlock any keyslot

This is good though

> 3. Create a snapshot using a different password.
> 3.1 Create snapshot without specifying encryption key for backing file.     
> ------> Snapshot created due to bug 1213786. Snapshot cannot be created if
> don't specify image size.
> # qemu-img create --object secret,id=sec1,data=snaphot -f qcow2 -o
> encrypt.format=luks,encrypt.key-secret=sec1,backing_file=base.qcow2,
> backing_fmt=qcow2 sn.qcow2 5G
> qemu-img: warning: Could not verify backing image. This may become an error
> in future versions.
> Parameter 'encrypt.key-secret' is required for cipher
> Formatting 'sn.qcow2', fmt=qcow2 size=5368709120 backing_file=base.qcow2
> backing_fmt=qcow2 encrypt.format=luks encrypt.key-secret=sec1
> cluster_size=65536 lazy_refcounts=off refcount_bits=16

This is expected behaviour


> 3.4 Run qemu-img info & check on the image using option
> backing.encrypt.key-secret.      ------> Should give same error prompt
> "Block format 'qcow2' does not support the option
> 'backing.encrypt.key-secret'"
> # qemu-img check --object secret,id=sec0,data=backing --object
> secret,id=sec1,data=snaphot --image-opts
> driver=qcow2,encrypt.key-secret=sec1,file.filename=sn.qcow2,backing.encrypt.
> key-secret=sec0
> No errors were found on the image.
> Image end offset: 2359296
> # qemu-img info --object secret,id=sec0,data=backing --object
> secret,id=sec1,data=snaphot --image-opts
> driver=qcow2,encrypt.key-secret=sec1,file.filename=sn.qcow2,backing.encrypt.
> key-secret=sec0
> qemu-img: Could not open
> 'driver=qcow2,encrypt.key-secret=sec1,file.filename=sn.qcow2,backing.encrypt.
> key-secret=sec0': Block format 'qcow2' does not support the option
> 'backing.encrypt.key-secret'

This is expected, because the 'info' command does not accept any 'backing.*' options


> 
> 3.5 Boot a guest with snapshot
>     --object secret,id=sec0,data=backing \
>     --object secret,id=sec1,data=snapshot \
>     -drive
> id=drive_image1,driver=qcow2,file.filename=/home/tests/test/sn.qcow2,encrypt.
> key-secret=sec1,backing.encrypt.key-secret=sec0,if=none,snapshot=off,
> aio=native,cache=none \
>     -device
> virtio-blk-pci,id=image1,drive=drive_image1,bootindex=0,bus=pci.0,addr=0x3 \
> 
> qemu-kvm: -drive
> id=drive_image1,driver=qcow2,file.filename=/home/tests/test/sn.qcow2,encrypt.
> key-secret=sec1,backing.encrypt.key-secret=sec0,if=none,snapshot=off,
> aio=native,cache=none: Invalid password, cannot unlock any keyslot

You had a typo in the password when you ran 'qemu-img create' - you used 'snaphot' when creating, but here you use 'snapshot'. If you fix the typo when creating the image, this check works.


> 4. Commit the changes to backing file
> 4.1 Commit snapshot to base.
> # qemu-img commit --object secret,id=sec0,data=backing --object
> secret,id=sec1,data=snaphot --image-opts
> driver=qcow2,encrypt.key-secret=sec1,file.filename=sn.qcow2
> Image committed.
> 
> 4.2 Get information and check image
> # qemu-img check --object secret,id=sec0,data=backing --object
> secret,id=sec1,data=snaphot --image-opts
> driver=qcow2,encrypt.key-secret=sec1,file.filename=sn.qcow2
> qemu-img: Could not open
> 'driver=qcow2,encrypt.key-secret=sec1,file.filename=sn.qcow2': Volume is not
> in LUKS format
> 
> # qemu-img info --object secret,id=sec0,data=backing --object
> secret,id=sec1,data=snaphot --image-opts
> driver=qcow2,encrypt.key-secret=sec1,file.filename=sn.qcow2
> qemu-img: Could not open
> 'driver=qcow2,encrypt.key-secret=sec1,file.filename=sn.qcow2': Volume is not
> in LUKS format
> 
> # qemu-img info sn.qcow2 
> qemu-img: Could not open 'sn.qcow2': Volume is not in LUKS format


This does indeed look like a serious bug, with image corruption.


> 5. Convert base image to a qcow2 image using a different password
> 5.1 Convert image
> # qemu-img convert -p --object secret,id=sec0,data=backing --object
> secret,id=sec2,data=convert --image-opts
> driver=qcow2,encrypt.key-secret=sec0,file.filename=base.qcow2 -O qcow2 -o
> encrypt.format=luks,encrypt.key-secret=sec2 convert.qcow2
> 
> 5.2 Get information and check image(Both info and check operation can be
> executed successfully)
> # qemu-img info --object secret,id=sec2,data=convert --image-opts
> driver=qcow2,encrypt.key-secret=sec2,file.filename=convert.qcow2
> # qemu-img check --object secret,id=sec2,data=convert --image-opts
> driver=qcow2,encrypt.key-secret=sec2,file.filename=convert.qcow2
> 
> 6. Amend the converted image
> 6.1 Change the encryption key      ------> Should be a bug, qemu-img is
> aborted
> # qemu-img amend --object secret,id=sec2,data=convert --object
> secret,id=sec3,data=amend --image-opts
> driver=qcow2,encrypt.key-secret=sec2,file.filename=convert.qcow2 -o
> encrypt.key-secret=sec3
> Aborted

Changing encryption key is not supported right now, but this should report an
error message instead of aborting. So yes, this is another bug.


> 6.2 Downgrade the version of qcow2 image
> # qemu-img amend -p --object secret,id=sec2,data=convert --image-opts
> b
> compat=0.10
> # qemu-img info convert.qcow2 
> image: convert.qcow2
> file format: qcow2
> virtual size: 5.0G (5368709120 bytes)
> disk size: 2.0G
> encrypted: yes
> cluster_size: 65536
> Format specific information:
>     compat: 0.10
>     ...
> 
> 7. Rebase the snapshot to the converted image
> 7.1 Rebase image
> # qemu-img rebase --object secret,id=sec0,data=backing --object
> secret,id=sec1,data=snaphot --object secret,id=sec2,data=convert
> --image-opts driver=qcow2,encrypt.key-secret=sec1,file.filename=sn.qcow2 -b
> 'json:{"encrypt.key-secret": "sec2", "driver": "qcow2", "file": {"driver":
> "file", "filename": "/home/tests/test/convert.qcow2"}}'
> 
> 7.2 Get information and check image
> # qemu-img info sn.qcow2 
> image: sn.qcow2
> file format: qcow2
> virtual size: 5.0G (5368709120 bytes)
> disk size: 16M
> encrypted: yes
> cluster_size: 65536
> backing file: json:{"encrypt.key-secret": "sec2", "driver": "qcow2", "file":
> {"driver": "file", "filename": "/home/tests/test/convert.qcow2"}}
> Format specific information:
>     compat: 1.1
>     lazy refcounts: false
>     refcount bits: 16
>     encrypt:
>         ivgen alg: plain64
>         hash alg: sha256
>         cipher alg: aes-256
>         uuid: 2b9e3e2b-9c30-4e25-9990-8e02cd3819e2
>         format: luks
>         cipher mode: xts
>         slots:
>             [0]:
>                 active: true
>                 iters: 647574
>                 key offset: 4096
>                 stripes: 4000
>             [1]:
>                 active: false
>                 key offset: 262144
>             [2]:
>                 active: false
>                 key offset: 520192
>             [3]:
>                 active: false
>                 key offset: 778240
>             [4]:
>                 active: false
>                 key offset: 1036288
>             [5]:
>                 active: false
>                 key offset: 1294336
>             [6]:
>                 active: false
>                 key offset: 1552384
>             [7]:
>                 active: false
>                 key offset: 1810432
>         payload offset: 2068480
>         master key iters: 161897
>     corrupt: false
> 
> # qemu-img check --object secret,id=sec1,data=snapshot --object
> secret,id=sec2,data=convert --image-opts
> driver=qcow2,encrypt.key-secret=sec1,file.filename=sn.qcow2
> qemu-img: Could not open
> 'driver=qcow2,encrypt.key-secret=sec1,file.filename=sn.qcow2': Invalid
> password, cannot unlock any keyslot

You have your password typo again - 'snapshot' vs 'snaphot'.


> 
> 8. Change image size
> 8.1 Resize image
> # qemu-img resize --object secret,id=sec0,data=backing --image-opts
> driver=qcow2,encrypt.key-secret=sec0,file.filename=base.qcow2 +1G 
> Image resized.
> 
> 8.2 Get information and check image
> # qemu-img info --object secret,id=sec0,data=backing --image-opts
> driver=qcow2,encrypt.key-secret=sec0,file.filename=base.qcow2
> image: json:{"encrypt.key-secret": "sec0", "driver": "qcow2", "file":
> {"driver": "file", "filename": "base.qcow2"}}
> file format: qcow2
> virtual size: 6.0G (6442450944 bytes)
> disk size: 3.2G
> encrypted: yes
> 
> # qemu-img check --object secret,id=sec0,data=backing --image-opts
> driver=qcow2,encrypt.key-secret=sec0,file.filename=base.qcow2
> No errors were found on the image.
> 20441/98304 = 20.79% allocated, 13.69% fragmented, 0.00% compressed clusters
> Image end offset: 1342701568
> 
> Additional info:
> When i tried it on Fedora, found error below:
> $ /home/pingl/workspace/software/qemu-2.10.1/qemu-img create --object
> secret,id=sec0,data=123456 -f qcow2 -o
> encrypt.format=luks,encrypt.key-secret=sec0 base.qcow2 1G
> Formatting 'base.qcow2', fmt=qcow2 size=1073741824 encrypt.format=luks
> encrypt.key-secret=sec0 cluster_size=65536 lazy_refcounts=off
> refcount_bits=16
> qemu-img: base.qcow2: No crypto library supporting PBKDF in this build:
> Function not implemented

This looks like you have built QEMU without having gnutls-devel/nettle-devel installed.

Comment 14 Daniel Berrange 2017-11-06 14:57:32 UTC
(In reply to Daniel Berrange from comment #13)
> (In reply to Ping Li from comment #11)

> > 5) After commit snapshot to backing file, snapshot cannot be opened(refer to
> > 4.2).
> 
> Yes, this is a serious image corruption bug

Possible fix posted at:

https://lists.gnu.org/archive/html/qemu-devel/2017-11/msg00434.html

> > 6) Change the encryption key of image through amend will make qemu-img to be
> > aborted(refer to 6.1).
> 
> This is a minor bug - it should report an error message instead of aborting.

Possible fix posted at:

https://lists.gnu.org/archive/html/qemu-devel/2017-11/msg00433.html

Comment 15 Ping Li 2017-11-08 10:53:11 UTC
Packages tested:
kernel-3.10.0-768.el7
qemu-kvm-rhev-2.10.0-4.el7

Test steps:
1. Create a base image.
1.1 create image.
# qemu-img create --object secret,id=sec0,data=backing -f qcow2 -o encrypt.format=luks,encrypt.key-secret=sec0 base.qcow2 5G
Formatting 'base.qcow2', fmt=qcow2 size=5368709120 encrypt.format=luks encrypt.key-secret=sec0 cluster_size=65536 lazy_refcounts=off refcount_bits=16

1.2 Get information of the image.
# qemu-img info base.qcow2 
image: base.qcow2
file format: qcow2
virtual size: 5.0G (5368709120 bytes)
disk size: 540K
encrypted: yes
cluster_size: 65536
Format specific information:
    compat: 1.1
    lazy refcounts: false
    refcount bits: 16
    encrypt:
        ivgen alg: plain64
        hash alg: sha256
        cipher alg: aes-256
        uuid: 868fc9a9-7243-4334-8594-6175345f4eca
        format: luks
        cipher mode: xts
        slots:
            [0]:
                active: true
                iters: 1390512
                key offset: 4096
                stripes: 4000
            [1]:
                active: false
                key offset: 262144
            [2]:
                active: false
                key offset: 520192
            [3]:
                active: false
                key offset: 778240
            [4]:
                active: false
                key offset: 1036288
            [5]:
                active: false
                key offset: 1294336
            [6]:
                active: false
                key offset: 1552384
            [7]:
                active: false
                key offset: 1810432
        payload offset: 2068480
        master key iters: 337456
    corrupt: false

1.3 Check the image with right and wrong password.
# qemu-img check --object secret,id=sec0,data=backing --image-opts driver=qcow2,encrypt.key-secret=sec0,file.filename=base.qcow2 
No errors were found on the image.
Image end offset: 2359296
# qemu-img check --object secret,id=sec0,data=wrong --image-opts driver=qcow2,encrypt.key-secret=sec0,file.filename=base.qcow2
qemu-img: Could not open 'driver=qcow2,encrypt.key-secret=sec0,file.filename=base.qcow2': Invalid password, cannot unlock any keyslot

2. Boot a guest and install OS on the image.
    --object secret,id=sec0,data=backing \
    -drive id=drive_image1,if=none,snapshot=off,aio=native,cache=none,format=qcow2,file=/home/tests/diskfile/base.qcow2,encrypt.key-secret=sec0 \
    -device virtio-blk-pci,id=image1,drive=drive_image1,bootindex=0,bus=pci.0,addr=0x3 \

(qemu) info block
drive_image1 (#block119): json:{"encrypt.key-secret": "sec0", "driver": "qcow2", "file": {"driver": "file", "filename": "/home/tests/diskfile/base.qcow2"}} (qcow2, encrypted)
    Attached to:      /machine/peripheral/image1/virtio-backend
    Cache mode:       writethrough, direct

3 Create a snapshot
3.1 Create a snapshot using a different password.
# qemu-img create --object secret,id=sec0,data=backing --object secret,id=sec1,data=snapshot -f qcow2 -o encrypt.format=luks,encrypt.key-secret=sec1 -b 'json:{"encrypt.key-secret": "sec0", "driver": "qcow2", "file": {"driver": "file", "filename": "/home/tests/diskfile/base.qcow2"}}' sn.qcow2
Formatting 'sn.qcow2', fmt=qcow2 size=5368709120 backing_file=json:{"encrypt.key-secret": "sec0",, "driver": "qcow2",, "file": {"driver": "file",, "filename": "/home/tests/diskfile/base.qcow2"}} encrypt.format=luks encrypt.key-secret=sec1 cluster_size=65536 lazy_refcounts=off refcount_bits=16

3.2 Get information of the snapshot
# qemu-img info sn.qcow2 
image: sn.qcow2
file format: qcow2
virtual size: 5.0G (5368709120 bytes)
disk size: 540K
encrypted: yes
cluster_size: 65536
backing file: json:{"encrypt.key-secret": "sec0", "driver": "qcow2", "file": {"driver": "file", "filename": "/home/tests/diskfile/base.qcow2"}}
Format specific information:
    compat: 1.1
    lazy refcounts: false
    refcount bits: 16
    encrypt:
        ivgen alg: plain64
        hash alg: sha256
        cipher alg: aes-256
        uuid: 4d864927-6c0a-4b4b-86a7-53905603a389
        format: luks
        cipher mode: xts
        slots:
            [0]:
                active: true
                iters: 1384498
                key offset: 4096
                stripes: 4000
            [1]:
                active: false
                key offset: 262144
            [2]:
                active: false
                key offset: 520192
            [3]:
                active: false
                key offset: 778240
            [4]:
                active: false
                key offset: 1036288
            [5]:
                active: false
                key offset: 1294336
            [6]:
                active: false
                key offset: 1552384
            [7]:
                active: false
                key offset: 1810432
        payload offset: 2068480
        master key iters: 347678
    corrupt: false

3.3 Check the snapshot
# qemu-img check --object secret,id=sec0,data=backing --object secret,id=sec1,data=snapshot --image-opts driver=qcow2,encrypt.key-secret=sec1,file.filename=sn.qcow2,backing.encrypt.key-secret=sec0
No errors were found on the image.
Image end offset: 2359296

3.4 Boot the snaoshot
    --object secret,id=sec0,data=backing \
    --object secret,id=sec1,data=snapshot \
    -drive id=drive_image1,if=none,snapshot=off,aio=native,cache=none,format=qcow2,file=/home/tests/diskfile/sn.qcow2,encrypt.key-secret=sec1,backing.encrypt.key-secret=sec0 \
    -device virtio-blk-pci,id=image1,drive=drive_image1,bootindex=0,bus=pci.0,addr=0x3 \

(qemu) info block
drive_image1 (#block170): json:{"encrypt.key-secret": "sec1", "driver": "qcow2", "file": {"driver": "file", "filename": "/home/tests/diskfile/sn.qcow2"}} (qcow2, encrypted)
    Attached to:      /machine/peripheral/image1/virtio-backend
    Cache mode:       writethrough, direct
    Backing file:     json:{"encrypt.key-secret": "sec0", "driver": "qcow2", "file": {"driver": "file", "filename": "/home/tests/diskfile/base.qcow2"}} (chain depth: 1)

4. Commit the changes to backing file
4.1 Commit the changes
# qemu-img commit --object secret,id=sec0,data=backing --object secret,id=sec1,data=snapshot --image-opts driver=qcow2,encrypt.key-secret=sec1,file.filename=sn.qcow2,backing.encrypt.key-secret=sec0
Image committed.

4.2 Get information of snapshot
# qemu-img info sn.qcow2 
qemu-img: Could not open 'sn.qcow2': Volume is not in LUKS format    ------> Confirmed with Daniel,  this is a serious image corruption bug

4.3 Check the snapshot
# qemu-img check --object secret,id=sec0,data=backing --object secret,id=sec1,data=snapshot --image-opts driver=qcow2,encrypt.key-secret=sec1,file.filename=sn.qcow2,backing.encrypt.key-secret=sec0
qemu-img: Could not open 'driver=qcow2,encrypt.key-secret=sec1,file.filename=sn.qcow2,backing.encrypt.key-secret=sec0': Volume is not in LUKS format    ------> Confirmed with Daniel,  this is a serious image corruption bug

5. Convert image 
5.1 Convert snapshot to a qcow2 image using a different password
# qemu-img convert -p --object secret,id=sec0,data=backing --object secret,id=sec1,data=snapshot --object secret,id=sec2,data=convert --image-opts driver=qcow2,encrypt.key-secret=sec1,file.filename=sn.qcow2,backing.encrypt.key-secret=sec0 -O qcow2 -o encrypt.format=luks,encrypt.key-secret=sec2 convert.qcow2
    (100.00/100%)

5.2 Get the information of the image
# qemu-img info convert.qcow2 
image: convert.qcow2
file format: qcow2
virtual size: 5.0G (5368709120 bytes)
disk size: 4.0G
encrypted: yes
cluster_size: 65536
Format specific information:
    compat: 1.1
    lazy refcounts: false
    refcount bits: 16
    encrypt:
        ivgen alg: plain64
        hash alg: sha256
        cipher alg: aes-256
        uuid: 5afe0e44-ca57-4f8a-803a-41a8b603ce88
        format: luks
        cipher mode: xts
        slots:
            [0]:
                active: true
                iters: 1384152
                key offset: 4096
                stripes: 4000
            [1]:
                active: false
                key offset: 262144
            [2]:
                active: false
                key offset: 520192
            [3]:
                active: false
                key offset: 778240
            [4]:
                active: false
                key offset: 1036288
            [5]:
                active: false
                key offset: 1294336
            [6]:
                active: false
                key offset: 1552384
            [7]:
                active: false
                key offset: 1810432
        payload offset: 2068480
        master key iters: 346000
    corrupt: false

5.3 Check the image
# qemu-img check --object secret,id=sec2,data=convert --image-opts driver=qcow2,encrypt.key-secret=sec2,file.filename=convert.qcow2
No errors were found on the image.
34678/81920 = 42.33% allocated, 0.00% fragmented, 0.00% compressed clusters
Image end offset: 2275737600

6. Compare images
# qemu-img compare -p --object secret,id=sec0,data=backing --object secret,id=sec1,data=snapshot --object secret,id=sec2,data=convert --image-opts driver=qcow2,encrypt.key-secret=sec1,file.filename=sn.qcow2,backing.encrypt.key-secret=sec0 driver=qcow2,encrypt.key-secret=sec2,file.filename=convert.qcow2
Images are identical.

7. Amend images.
7.1 Amend the converted image.
# qemu-img amend --object secret,id=sec2,data=convert --object secret,id=sec3,data=amend --image-opts driver=qcow2,encrypt.key-secret=sec2,file.filename=convert.qcow2 -o encrypt.key-secret=sec3
Aborted    ------> Confirmed with Daniel,  this is a minor bug.

7.2 Downgrade the version of qcow2 image
# qemu-img amend -p --object secret,id=sec2,data=convert --image-opts driver=qcow2,encrypt.key-secret=sec2,file.filename=convert.qcow2 -o compat=0.10
    (100.00/100%)

# qemu-img info convert.qcow2 
image: convert.qcow2
file format: qcow2
virtual size: 5.0G (5368709120 bytes)
disk size: 4.0G
encrypted: yes
cluster_size: 65536
Format specific information:
    compat: 0.10
    refcount bits: 16
    encrypt:
        ivgen alg: plain64
        hash alg: sha256
        cipher alg: aes-256
        uuid: 5afe0e44-ca57-4f8a-803a-41a8b603ce88
        format: luks
        cipher mode: xts
        slots:
            [0]:
                active: true
                iters: 1384152
                key offset: 4096
                stripes: 4000
            [1]:
                active: false
                key offset: 262144
            [2]:
                active: false
                key offset: 520192
            [3]:
                active: false
                key offset: 778240
            [4]:
                active: false
                key offset: 1036288
            [5]:
                active: false
                key offset: 1294336
            [6]:
                active: false
                key offset: 1552384
            [7]:
                active: false
                key offset: 1810432
        payload offset: 2068480
        master key iters: 346000

# qemu-img check --object secret,id=sec2,data=convert --image-opts driver=qcow2,encrypt.key-secret=sec2,file.filename=convert.qcow2
No errors were found on the image.
34678/81920 = 42.33% allocated, 0.00% fragmented, 0.00% compressed clusters
Image end offset: 2275737600

8 Rebase image
8.1 Rebase the snapshot to the converted image
# qemu-img rebase -p --object secret,id=sec0,data=backing --object secret,id=sec1,data=snapshot --object secret,id=sec2,data=convert --image-opts driver=qcow2,encrypt.key-secret=sec1,file.filename=sn.qcow2,backing.encrypt.key-secret=sec0 -b 'json:{"encrypt.key-secret": "sec2", "driver": "qcow2", "file": {"driver": "file", "filename": "/home/tests/diskfile/convert.qcow2"}}'
    (100.00/100%)

8.2 Get information of snapshot
# qemu-img info sn.qcow2 
image: sn.qcow2
file format: qcow2
virtual size: 5.0G (5368709120 bytes)
disk size: 521M
encrypted: yes
cluster_size: 65536
backing file: json:{"encrypt.key-secret": "sec2", "driver": "qcow2", "file": {"driver": "file", "filename": "/home/tests/diskfile/convert.qcow2"}}
Format specific information:
    compat: 1.1
    lazy refcounts: false
    refcount bits: 16
    encrypt:
        ivgen alg: plain64
        hash alg: sha256
        cipher alg: aes-256
        uuid: 4d864927-6c0a-4b4b-86a7-53905603a389
        format: luks
        cipher mode: xts
        slots:
            [0]:
                active: true
                iters: 1384498
                key offset: 4096
                stripes: 4000
            [1]:
                active: false
                key offset: 262144
            [2]:
                active: false
                key offset: 520192
            [3]:
                active: false
                key offset: 778240
            [4]:
                active: false
                key offset: 1036288
            [5]:
                active: false
                key offset: 1294336
            [6]:
                active: false
                key offset: 1552384
            [7]:
                active: false
                key offset: 1810432
        payload offset: 2068480
        master key iters: 347678
    corrupt: false

8.3 Check the snapshot
# qemu-img check --object secret,id=sec1,data=snapshot --object secret,id=sec2,data=convert --image-opts driver=qcow2,encrypt.key-secret=sec1,file.filename=sn.qcow2,backing.encrypt.key-secret=sec2
No errors were found on the image.
8307/81920 = 10.14% allocated, 3.66% fragmented, 0.00% compressed clusters
Image end offset: 547291136

9 Resize image
9.1 Change image size
# qemu-img resize --object secret,id=sec1,data=snapshot --object secret,id=sec2,data=convert --image-opts driver=qcow2,encrypt.key-secret=sec1,backing.encrypt.key-secret=sec2,file.filename=sn.qcow2 +1G 
Image resized.

9.2 Get information of the image
# qemu-img info sn.qcow2 
image: sn.qcow2
file format: qcow2
virtual size: 6.0G (6442450944 bytes)
disk size: 529M
encrypted: yes
cluster_size: 65536
backing file: json:{"encrypt.key-secret": "sec2", "driver": "qcow2", "file": {"driver": "file", "filename": "/home/tests/diskfile/convert.qcow2"}}
Format specific information:
    compat: 1.1
    lazy refcounts: false
    refcount bits: 16
    encrypt:
        ivgen alg: plain64
        hash alg: sha256
        cipher alg: aes-256
        uuid: 4d864927-6c0a-4b4b-86a7-53905603a389
        format: luks
        cipher mode: xts
        slots:
            [0]:
                active: true
                iters: 1384498
                key offset: 4096
                stripes: 4000
            [1]:
                active: false
                key offset: 262144
            [2]:
                active: false
                key offset: 520192
            [3]:
                active: false
                key offset: 778240
            [4]:
                active: false
                key offset: 1036288
            [5]:
                active: false
                key offset: 1294336
            [6]:
                active: false
                key offset: 1552384
            [7]:
                active: false
                key offset: 1810432
        payload offset: 2068480
        master key iters: 347678
    corrupt: false

9.3 Check snapshot
# qemu-img check --object secret,id=sec1,data=snapshot --object secret,id=sec2,data=convert --image-opts driver=qcow2,encrypt.key-secret=sec1,backing.encrypt.key-secret=sec2,file.filename=sn.qcow2
No errors were found on the image.
8307/98304 = 8.45% allocated, 3.66% fragmented, 0.00% compressed clusters
Image end offset: 547356672

Comment 18 Miroslav Rezanina 2017-12-05 12:57:17 UTC
Fix included in qemu-kvm-rhev-2.10.0-11.el7

Comment 20 Ping Li 2017-12-07 10:46:55 UTC
Hi Daniel,

1) As we talked in irc, the behaviour in the step 10 is expected. So it is not a blocker for me to verify this bug. But shall we need to report a RFE bug to track the issue? 

2) Are the test scenarios below enough to verify this bug?

Thanks.

Packages tested:
kernel-3.10.0-806.el7.x86_64
qemu-kvm-rhev-2.10.0-11.el7

Test steps:
1. Create a base image.
1.1 create image.
# qemu-img create --object secret,id=sec0,data=backing -f qcow2 -o encrypt.format=luks,encrypt.key-secret=sec0 base.qcow2 20G
Formatting 'base.qcow2', fmt=qcow2 size=21474836480 encrypt.format=luks encrypt.key-secret=sec0 cluster_size=65536 lazy_refcounts=off refcount_bits=16

1.2 Get information of the image.
# qemu-img info base.qcow2 
image: base.qcow2
file format: qcow2
virtual size: 20G (21474836480 bytes)
disk size: 540K
encrypted: yes
cluster_size: 65536
Format specific information:
    compat: 1.1
    lazy refcounts: false
    refcount bits: 16
    encrypt:
        ivgen alg: plain64
        hash alg: sha256
        cipher alg: aes-256
        uuid: 52ce7938-93a7-442b-85d7-36b653c4aef1
        format: luks
        cipher mode: xts
        slots:
            [0]:
                active: true
                iters: 1336130
                key offset: 4096
                stripes: 4000
            [1]:
                active: false
                key offset: 262144
            [2]:
                active: false
                key offset: 520192
            [3]:
                active: false
                key offset: 778240
            [4]:
                active: false
                key offset: 1036288
            [5]:
                active: false
                key offset: 1294336
            [6]:
                active: false
                key offset: 1552384
            [7]:
                active: false
                key offset: 1810432
        payload offset: 2068480
        master key iters: 333756
    corrupt: false

1.3 Check the image with right and wrong password.
# qemu-img check --object secret,id=sec0,data=backing --image-opts driver=qcow2,encrypt.key-secret=sec0,file.filename=base.qcow2
No errors were found on the image.
Image end offset: 2359296

# qemu-img check --object secret,id=sec0,data=wrong --image-opts driver=qcow2,encrypt.key-secret=sec0,file.filename=base.qcow2
qemu-img: Could not open 'driver=qcow2,encrypt.key-secret=sec0,file.filename=base.qcow2': Invalid password, cannot unlock any keyslot

2. Boot a guest and install OS on the image.
    --object secret,id=sec0,data=backing \
    -device virtio-scsi-pci,id=virtio_scsi_pci0,bus=pci.0,addr=0x3 \
    -drive id=drive_image1,if=none,snapshot=off,aio=threads,cache=none,format=qcow2,file=/home/tests/diskfile/base.qcow2,encrypt.key-secret=sec0 \
    -device scsi-hd,id=image1,drive=drive_image1 \

(qemu) info block
drive_image1 (#block154): json:{"encrypt.key-secret": "sec0", "driver": "qcow2", "file": {"driver": "file", "filename": "/home/tests/diskfile/base.qcow2"}} (qcow2, encrypted)
    Attached to:      image1
    Cache mode:       writeback, direct

3 Create a snapshot
3.1 Create a snapshot using a different password.
# qemu-img create --object secret,id=sec0,data=backing --object secret,id=sec1,data=snapshot -f qcow2 -o encrypt.format=luks,encrypt.key-secret=sec1 -b 'json:{"encrypt.key-secret": "sec0", "driver": "qcow2", "file": {"driver": "file", "filename": "/home/tests/diskfile/base.qcow2"}}' sn.qcow2
Formatting 'sn.qcow2', fmt=qcow2 size=21474836480 backing_file=json:{"encrypt.key-secret": "sec0",, "driver": "qcow2",, "file": {"driver": "file",, "filename": "/home/tests/diskfile/base.qcow2"}} encrypt.format=luks encrypt.key-secret=sec1 cluster_size=65536 lazy_refcounts=off refcount_bits=16

3.2 Get information of the snapshot
# qemu-img info sn.qcow2 
image: sn.qcow2
file format: qcow2
virtual size: 20G (21474836480 bytes)
disk size: 540K
encrypted: yes
cluster_size: 65536
backing file: json:{"encrypt.key-secret": "sec0", "driver": "qcow2", "file": {"driver": "file", "filename": "/home/tests/diskfile/base.qcow2"}}
Format specific information:
    compat: 1.1
    lazy refcounts: false
    refcount bits: 16
    encrypt:
        ivgen alg: plain64
        hash alg: sha256
        cipher alg: aes-256
        uuid: 457862ba-5756-4964-9ffd-3191079717e1
        format: luks
        cipher mode: xts
        slots:
            [0]:
                active: true
                iters: 1343196
                key offset: 4096
                stripes: 4000
            [1]:
                active: false
                key offset: 262144
            [2]:
                active: false
                key offset: 520192
            [3]:
                active: false
                key offset: 778240
            [4]:
                active: false
                key offset: 1036288
            [5]:
                active: false
                key offset: 1294336
            [6]:
                active: false
                key offset: 1552384
            [7]:
                active: false
                key offset: 1810432
        payload offset: 2068480
        master key iters: 336747
    corrupt: false

3.3 Check the snapshot
# qemu-img check --object secret,id=sec0,data=backing --object secret,id=sec1,data=snapshot --image-opts driver=qcow2,encrypt.key-secret=sec1,file.filename=sn.qcow2,backing.encrypt.key-secret=sec0
No errors were found on the image.
Image end offset: 2359296

3.4 Boot the snaoshot
    --object secret,id=sec0,data=backing \
    --object secret,id=sec1,data=snapshot \
    -device virtio-scsi-pci,id=virtio_scsi_pci0,bus=pci.0,addr=0x3 \
    -drive id=drive_image1,if=none,snapshot=off,aio=threads,cache=none,format=qcow2,file=/home/tests/diskfile/sn.qcow2,encrypt.key-secret=sec1,backing.encrypt.key-secret=sec0 \
    -device scsi-hd,id=image1,drive=drive_image1 \

(qemu) info block
drive_image1 (#block135): json:{"encrypt.key-secret": "sec1", "driver": "qcow2", "file": {"driver": "file", "filename": "/home/tests/diskfile/sn.qcow2"}} (qcow2, encrypted)
    Attached to:      image1
    Cache mode:       writeback, direct
    Backing file:     json:{"encrypt.key-secret": "sec0", "driver": "qcow2", "file": {"driver": "file", "filename": "/home/tests/diskfile/base.qcow2"}} (chain depth: 1)

4. Commit the changes to backing file
4.1 Commit the changes
# qemu-img commit --object secret,id=sec0,data=backing --object secret,id=sec1,data=snapshot --image-opts driver=qcow2,encrypt.key-secret=sec1,file.filename=sn.qcow2,backing.encrypt.key-secret=sec0
Image committed.

4.2 Get information of snapshot
# qemu-img info sn.qcow2 
image: sn.qcow2
file format: qcow2
virtual size: 20G (21474836480 bytes)
disk size: 3.0M
encrypted: yes
cluster_size: 65536
backing file: json:{"encrypt.key-secret": "sec0", "driver": "qcow2", "file": {"driver": "file", "filename": "/home/tests/diskfile/base.qcow2"}}
Format specific information:
    compat: 1.1
    lazy refcounts: false
    refcount bits: 16
    encrypt:
        ivgen alg: plain64
        hash alg: sha256
        cipher alg: aes-256
        uuid: 457862ba-5756-4964-9ffd-3191079717e1
        format: luks
        cipher mode: xts
        slots:
            [0]:
                active: true
                iters: 1343196
                key offset: 4096
                stripes: 4000
            [1]:
                active: false
                key offset: 262144
            [2]:
                active: false
                key offset: 520192
            [3]:
                active: false
                key offset: 778240
            [4]:
                active: false
                key offset: 1036288
            [5]:
                active: false
                key offset: 1294336
            [6]:
                active: false
                key offset: 1552384
            [7]:
                active: false
                key offset: 1810432
        payload offset: 2068480
        master key iters: 336747
    corrupt: false

4.3 Check the snapshot
# qemu-img check --object secret,id=sec0,data=backing --object secret,id=sec1,data=snapshot --image-opts driver=qcow2,encrypt.key-secret=sec1,file.filename=sn.qcow2,backing.encrypt.key-secret=sec0
No errors were found on the image.
Image end offset: 547291136

5. Convert image 
5.1 Convert snapshot to a qcow2 image using a different password
# qemu-img convert -p --object secret,id=sec0,data=backing --object secret,id=sec1,data=snapshot --object secret,id=sec2,data=convert --image-opts driver=qcow2,encrypt.key-secret=sec1,file.filename=sn.qcow2,backing.encrypt.key-secret=sec0 -O qcow2 -o encrypt.format=luks,encrypt.key-secret=sec2 convert.qcow2
    (100.00/100%)

5.2 Get the information of the image
# qemu-img info convert.qcow2 
image: convert.qcow2
file format: qcow2
virtual size: 20G (21474836480 bytes)
disk size: 3.9G
encrypted: yes
cluster_size: 65536
Format specific information:
    compat: 1.1
    lazy refcounts: false
    refcount bits: 16
    encrypt:
        ivgen alg: plain64
        hash alg: sha256
        cipher alg: aes-256
        uuid: 2446eeff-f17d-4105-b90c-0398f6d49ae9
        format: luks
        cipher mode: xts
        slots:
            [0]:
                active: true
                iters: 1338864
                key offset: 4096
                stripes: 4000
            [1]:
                active: false
                key offset: 262144
            [2]:
                active: false
                key offset: 520192
            [3]:
                active: false
                key offset: 778240
            [4]:
                active: false
                key offset: 1036288
            [5]:
                active: false
                key offset: 1294336
            [6]:
                active: false
                key offset: 1552384
            [7]:
                active: false
                key offset: 1810432
        payload offset: 2068480
        master key iters: 327352
    corrupt: false

5.3 Check the image
# qemu-img check --object secret,id=sec2,data=convert --image-opts driver=qcow2,encrypt.key-secret=sec2,file.filename=convert.qcow2
No errors were found on the image.
35525/327680 = 10.84% allocated, 0.00% fragmented, 0.00% compressed clusters
Image end offset: 2331312128

6. Compare images
# qemu-img compare -p --object secret,id=sec0,data=backing --object secret,id=sec1,data=snapshot --object secret,id=sec2,data=convert --image-opts driver=qcow2,encrypt.key-secret=sec1,file.filename=sn.qcow2,backing.encrypt.key-secret=sec0 driver=qcow2,encrypt.key-secret=sec2,file.filename=convert.qcow2
Images are identical.

7. Amend images.
7.1 Amend the converted image.
# qemu-img amend --object secret,id=sec2,data=convert --object secret,id=sec3,data=amend --image-opts driver=qcow2,encrypt.key-secret=sec2,file.filename=convert.qcow2 -o encrypt.key-secret=sec3
qemu-img: Changing the encryption parameters is not supported
qemu-img: Error while amending options: Operation not supported

7.2 Downgrade the version of qcow2 image
# qemu-img amend -p --object secret,id=sec2,data=convert --image-opts driver=qcow2,encrypt.key-secret=sec2,file.filename=convert.qcow2 -o compat=0.10
    (100.00/100%)

# qemu-img info convert.qcow2 
image: convert.qcow2
file format: qcow2
virtual size: 20G (21474836480 bytes)
disk size: 2.2G
encrypted: yes
cluster_size: 65536
Format specific information:
    compat: 0.10
    refcount bits: 16
    encrypt:
        ivgen alg: plain64
        hash alg: sha256
        cipher alg: aes-256
        uuid: e2b1873c-b983-4004-b06e-7d7b66ff0e37
        format: luks
        cipher mode: xts
        slots:
            [0]:
                active: true
                iters: 1344294
                key offset: 4096
                stripes: 4000
            [1]:
                active: false
                key offset: 262144
            [2]:
                active: false
                key offset: 520192
            [3]:
                active: false
                key offset: 778240
            [4]:
                active: false
                key offset: 1036288
            [5]:
                active: false
                key offset: 1294336
            [6]:
                active: false
                key offset: 1552384
            [7]:
                active: false
                key offset: 1810432
        payload offset: 2068480
        master key iters: 324793

# qemu-img check --object secret,id=sec2,data=convert --image-opts driver=qcow2,encrypt.key-secret=sec2,file.filename=convert.qcow2
No errors were found on the image.
34678/81920 = 42.33% allocated, 0.00% fragmented, 0.00% compressed clusters
Image end offset: 2275737600

8 Rebase image
8.1 Rebase the snapshot to the converted image
# qemu-img rebase -p --object secret,id=sec0,data=backing --object secret,id=sec1,data=snapshot --object secret,id=sec2,data=convert --image-opts driver=qcow2,encrypt.key-secret=sec1,file.filename=sn.qcow2,backing.encrypt.key-secret=sec0 -b 'json:{"encrypt.key-secret": "sec2", "driver": "qcow2", "file": {"driver": "file", "filename": "/home/tests/diskfile/convert.qcow2"}}'
    (100.00/100%)

8.2 Get information of snapshot
# qemu-img info sn.qcow2 
image: sn.qcow2
file format: qcow2
virtual size: 20G (21474836480 bytes)
disk size: 521M
encrypted: yes
cluster_size: 65536
backing file: json:{"encrypt.key-secret": "sec2", "driver": "qcow2", "file": {"driver": "file", "filename": "/home/tests/diskfile/convert.qcow2"}}
Format specific information:
    compat: 1.1
    lazy refcounts: false
    refcount bits: 16
    encrypt:
        ivgen alg: plain64
        hash alg: sha256
        cipher alg: aes-256
        uuid: 457862ba-5756-4964-9ffd-3191079717e1
        format: luks
        cipher mode: xts
        slots:
            [0]:
                active: true
                iters: 1343196
                key offset: 4096
                stripes: 4000
            [1]:
                active: false
                key offset: 262144
            [2]:
                active: false
                key offset: 520192
            [3]:
                active: false
                key offset: 778240
            [4]:
                active: false
                key offset: 1036288
            [5]:
                active: false
                key offset: 1294336
            [6]:
                active: false
                key offset: 1552384
            [7]:
                active: false
                key offset: 1810432
        payload offset: 2068480
        master key iters: 336747
    corrupt: false

8.3 Check the snapshot
# qemu-img check --object secret,id=sec1,data=snapshot --object secret,id=sec2,data=convert --image-opts driver=qcow2,encrypt.key-secret=sec1,file.filename=sn.qcow2,backing.encrypt.key-secret=sec2
No errors were found on the image.
8307/81920 = 10.14% allocated, 3.66% fragmented, 0.00% compressed clusters
Image end offset: 547291136

9 Resize image
9.1 Change image size
# qemu-img resize --object secret,id=sec1,data=snapshot --object secret,id=sec2,data=convert --image-opts driver=qcow2,encrypt.key-secret=sec1,backing.encrypt.key-secret=sec2,file.filename=sn.qcow2 +1G 
Image resized.

9.2 Get information of the image
# qemu-img info sn.qcow2 
image: sn.qcow2
file format: qcow2
virtual size: 21G (22548578304 bytes)
disk size: 1.5G
encrypted: yes
cluster_size: 65536
backing file: json:{"encrypt.key-secret": "sec2", "driver": "qcow2", "file": {"driver": "file", "filename": "/home/tests/diskfile/convert.qcow2"}}
Format specific information:
    compat: 1.1
    lazy refcounts: false
    refcount bits: 16
    encrypt:
        ivgen alg: plain64
        hash alg: sha256
        cipher alg: aes-256
        uuid: 457862ba-5756-4964-9ffd-3191079717e1
        format: luks
        cipher mode: xts
        slots:
            [0]:
                active: true
                iters: 1343196
                key offset: 4096
                stripes: 4000
            [1]:
                active: false
                key offset: 262144
            [2]:
                active: false
                key offset: 520192
            [3]:
                active: false
                key offset: 778240
            [4]:
                active: false
                key offset: 1036288
            [5]:
                active: false
                key offset: 1294336
            [6]:
                active: false
                key offset: 1552384
            [7]:
                active: false
                key offset: 1810432
        payload offset: 2068480
        master key iters: 336747
    corrupt: false

9.3 Check snapshot
# qemu-img check --object secret,id=sec1,data=snapshot --object secret,id=sec2,data=convert --image-opts driver=qcow2,encrypt.key-secret=sec1,backing.encrypt.key-secret=sec2,file.filename=sn.qcow2
No errors were found on the image.
8308/344064 = 2.41% allocated, 12.66% fragmented, 0.00% compressed clusters
Image end offset: 547487744

10. Dump the metadata of the image      ------>   Failed to dump the metadata of the image using the default human format
# qemu-img map --object secret,id=sec0,data=backing --image-opts driver=qcow2,encrypt.key-secret=sec0,file.filename=base.qcow2
Offset          Length          Mapped to       File
qemu-img: File contains external, encrypted or compressed clusters.
# echo $?
1
# qemu-img map --object secret,id=sec0,data=backing --image-opts driver=qcow2,encrypt.key-secret=sec0,file.filename=base.qcow2 --output=json
[{ "start": 0, "length": 65536, "depth": 0, "zero": false, "data": true},
{ "start": 65536, "length": 983040, "depth": 0, "zero": true, "data": false},
{ "start": 1048576, "length": 116260864, "depth": 0, "zero": false, "data": true},
{ "start": 117309440, "length": 152174592, "depth": 0, "zero": true, "data": false},
{ "start": 269484032, "length": 3342336, "depth": 0, "zero": false, "data": true},
{ "start": 272826368, "length": 265093120, "depth": 0, "zero": true, "data": false},
{ "start": 537919488, "length": 13172736, "depth": 0, "zero": false, "data": true},
{ "start": 551092224, "length": 255262720, "depth": 0, "zero": true, "data": false},
{ "start": 806354944, "length": 131072, "depth": 0, "zero": false, "data": true},
{ "start": 806486016, "length": 268173312, "depth": 0, "zero": true, "data": false},
{ "start": 1074659328, "length": 1245184, "depth": 0, "zero": false, "data": true},
{ "start": 1075904512, "length": 2147418112, "depth": 0, "zero": true, "data": false},
{ "start": 3223322624, "length": 908984320, "depth": 0, "zero": false, "data": true},
{ "start": 4132306944, "length": 3653369856, "depth": 0, "zero": true, "data": false},
{ "start": 7785676800, "length": 180486144, "depth": 0, "zero": false, "data": true},
{ "start": 7966162944, "length": 23986176, "depth": 0, "zero": true, "data": false},
{ "start": 7990149120, "length": 51183616, "depth": 0, "zero": false, "data": true},
{ "start": 8041332736, "length": 1900544, "depth": 0, "zero": true, "data": false},
{ "start": 8043233280, "length": 327680, "depth": 0, "zero": false, "data": true},
{ "start": 8043560960, "length": 131072, "depth": 0, "zero": true, "data": false},
{ "start": 8043692032, "length": 327680, "depth": 0, "zero": false, "data": true},
{ "start": 8044019712, "length": 131072, "depth": 0, "zero": true, "data": false},
{ "start": 8044150784, "length": 327680, "depth": 0, "zero": false, "data": true},
{ "start": 8044478464, "length": 131072, "depth": 0, "zero": true, "data": false},
{ "start": 8044609536, "length": 458752, "depth": 0, "zero": false, "data": true},
{ "start": 8045068288, "length": 65536, "depth": 0, "zero": true, "data": false},
{ "start": 8045133824, "length": 2228224, "depth": 0, "zero": false, "data": true},
{ "start": 8047362048, "length": 1900544, "depth": 0, "zero": true, "data": false},
{ "start": 8049262592, "length": 17170432, "depth": 0, "zero": false, "data": true},
{ "start": 8066433024, "length": 4281597952, "depth": 0, "zero": true, "data": false},
{ "start": 12348030976, "length": 210108416, "depth": 0, "zero": false, "data": true},
{ "start": 12558139392, "length": 4352245760, "depth": 0, "zero": true, "data": false},
{ "start": 16910385152, "length": 300089344, "depth": 0, "zero": false, "data": true},
{ "start": 17210474496, "length": 4262133760, "depth": 0, "zero": true, "data": false},
{ "start": 21472608256, "length": 131072, "depth": 0, "zero": false, "data": true},
{ "start": 21472739328, "length": 2031616, "depth": 0, "zero": true, "data": false},
{ "start": 21474770944, "length": 65536, "depth": 0, "zero": false, "data": true}]

11. Internal snapshot
# qemu-img snapshot --object secret,id=sec0,data=backing --image-opts driver=qcow2,encrypt.key-secret=sec0,file.filename=base.qcow2 -c internal_sn
# qemu-img snapshot --object secret,id=sec0,data=backing --image-opts driver=qcow2,encrypt.key-secret=sec0,file.filename=base.qcow2 -l
Snapshot list:
ID        TAG                 VM SIZE                DATE       VM CLOCK
1         internal_sn               0 2017-12-07 00:08:08   00:00:00.000
# qemu-img snapshot --object secret,id=sec0,data=backing --image-opts driver=qcow2,encrypt.key-secret=sec0,file.filename=base.qcow2 -a internal_sn
# qemu-img snapshot --object secret,id=sec0,data=backing --image-opts driver=qcow2,encrypt.key-secret=sec0,file.filename=base.qcow2 -l
Snapshot list:
ID        TAG                 VM SIZE                DATE       VM CLOCK
1         internal_sn               0 2017-12-07 00:08:08   00:00:00.000
# qemu-img snapshot --object secret,id=sec0,data=backing --image-opts driver=qcow2,encrypt.key-secret=sec0,file.filename=base.qcow2 -d internal_sn
# qemu-img snapshot --object secret,id=sec0,data=backing --image-opts driver=qcow2,encrypt.key-secret=sec0,file.filename=base.qcow2 -l

12. Calculate the file size
# qemu-img measure --object secret,id=sec0,data=backing --image-opts driver=qcow2,encrypt.key-secret=sec0,file.filename=base.qcow2 -O qcow2
required size: 1809645568
fully allocated size: 21478375424
# qemu-img measure --object secret,id=sec0,data=backing --image-opts driver=qcow2,encrypt.key-secret=sec0,file.filename=base.qcow2 -O raw
required size: 21474836480
fully allocated size: 21474836480

13. Run the suit of qemu-iotests
# brew download-build qemu-kvm-rhev-2.10.0-11.el7 --arch=src
# rpm -ivh qemu-kvm-rhev-2.10.0-11.el7.src.rpm
# rpmbuild -bp /root/rpmbuild/SPECS/qemu-kvm.spec --nodeps
# cd rpmbuild/BUILD/qemu-2.10.0
# ./configure
# export QEMU_PROG=/usr/libexec/qemu-kvm
# cd tests/qemu-iotests
# ./check -qcow2
Not run: 045 059 064 070 075 076 077 078 081 083 084 088 092 093 094 101 106 109 113 116 119 123 128 131 135 136 146 148 149 160 171 173 175 183
Failures: 030 041 051 055 118 138 139 142 147 153 172 186 195 198
Failed 14 of 144 tests
Below cases related to luks are passed 
042 048 049 082 085 087 134 144 158 188 189

Comment 21 Daniel Berrange 2017-12-07 11:06:03 UTC
This looks good to me. The 'qemu-img map' question is at most an RFE, which I'll investigate separately.

Comment 22 Ping Li 2017-12-08 02:17:46 UTC
According to the comment 20 and comment 21, set the bug status as verified.

Comment 25 hachen 2017-12-21 09:01:45 UTC
Hello Daniel,

Is there a way to create a snapshot of a luks encrypted qcow2 WITHOUT using json string?

# qemu-img create --object secret,id=sec0,data=backing --object secret,id=sec1,data=snapshot -f qcow2 -o encrypt.format=luks,encrypt.key-secret=sec1 -b 'json:{"encrypt.key-secret": "sec0", "driver": "qcow2", "file": {"driver": "file", "filename": "/home/tests/diskfile/base.qcow2"}}' sn.qcow2


I can only create a luks encrypted snapshot based on a plain base file. 
qemu-img create --object secret,id=sec1,data=snapshot -f qcow2 -o encrypt.format=luks,encrypt.key-secret=sec1 -b create_large_image.qcow2 sn111.qcow2

I'd like to use a similar cmd to create a encrypted snapshot based on a luks encrypted base file.

Thanks.

Comment 26 Daniel Berrange 2017-12-21 09:57:34 UTC
The 'qemu-img create' command is quite limited in what it supports - almost anything complicated wrt options has to be done using the JSON string format instead, as a workaround for its limitations.

Comment 27 Qianqian Zhu 2018-01-09 09:36:03 UTC
Hi Daniel,

I am trying to test block jobs with luks-inside-qcow2 format.
When I tried to perform live snapshot to an encrypted image, I did not find a way to pass the password to it, could you help point out how to complete such execution? Or if it is supported?

Steps:
1. Launch guest:
/usr/libexec/qemu-kvm \
-name qizhu  \
-M pseries-rhel7.5.0 \
-device virtio-scsi-pci,id=virtio_scsi_pci0,bus=pci.0,addr=03 \
-drive id=drive_image1,if=none,snapshot=off,aio=native,cache=none,format=qcow2,file=/home/qizhu/rhel75.luks_inside_qcow2,encrypt.key-secret=sec0 \
--object secret,id=sec0,data=backing \
-device scsi-hd,id=image1,drive=drive_image1 \
-qmp tcp::5555,server,nowait \

2. Create encrypted snapshot image:
 qemu-img create --object secret,id=sec0,data=backing -f qcow2 -o encrypt.format=luks,encrypt.key-secret=sec0 /home/qizhu/sn1  20G

3. Live snapshot:
{ "execute": "blockdev-snapshot-sync", "arguments": { "device": "drive_image1","snapshot-file": "/home/qizhu/sn1", "format": "qcow2", "mode": "existing"}}
{"error": {"class": "GenericError", "desc": "Parameter 'encrypt.key-secret' is required for cipher"}}

Thanks,
Qianqian

Comment 28 Daniel Berrange 2018-01-10 17:28:17 UTC
This is a known design limitation of the "blockdev-snapshot-sync" command. It has no way to accept options for the target file. It is intended to be replaced by using a combination of "blockdev-add" and "blockdev-snapshot", but I don't personally know the syntax to use for the latter yet.

Comment 30 errata-xmlrpc 2018-04-11 00:12:33 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/RHSA-2018:1104


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