qemu-img: "Could not open backing image to determine size" when backing image is encrypted
Use case: creating a non-encrypted qcow2 file (upper layer) with an encrypted backing file (lower layer).
Tested with: Ubuntu 20.04: qemu-img version 4.2.1 (Debian 1:4.2-3ubuntu6.16)
# qemu-img create --object secret,id=testsecret,data=abcd1234 -f qcow2 -o encrypt.format=luks,encrypt.key-secret=testsecret test.qcow2 100M
Formatting 'test.qcow2', fmt=qcow2 size=104857600 encrypt.format=luks encrypt.key-secret=testsecret cluster_size=65536 lazy_refcounts=off refcount_bits=16
# qemu-img create -f qcow2 -b test.qcow2 -F qcow2 test1.qcow2
qemu-img: test2.qcow2: Parameter 'encrypt.key-secret' is required for cipher
Could not open backing image to determine size.
<<< and no file is created >>>
The issue is: I believe it should not be necessary to decrypt the image to determine its size. After all, the image size information is displayed by qemu-img info
without providing the key:
# qemu-img info test.qcow2
image: test.qcow2
file format: qcow2
virtual size: 100 MiB (104857600 bytes) <<< HERE
disk size: 480 KiB
encrypted: yes
cluster_size: 65536
Format specific information:
compat: 1.1
lazy refcounts: false
refcount bits: 16
encrypt:
...
Workaround 1: obtain the size from qemu-img info
, and provide it as an extra parameter.
# qemu-img create -f qcow2 -b test.qcow2 -F qcow2 test2.qcow2 100M
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 'test2.qcow2', fmt=qcow2 size=104857600 backing_file=test.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16
#
Workaround 1a: same, but also provide -u
flag to suppress warning
# qemu-img create -f qcow2 -b test.qcow2 -F qcow2 -u test3.qcow2 100M
Formatting 'test3.qcow2', fmt=qcow2 size=104857600 backing_file=test.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16
#
Workaround 2: provide the decryption key (however I'm trying to avoid this)
# qemu-img create --object secret,id=testsecret,data=abcd1234 -f qcow2 -b 'json:{"encrypt.key-secret":"testsecret","driver":"qcow2","file":{"driver":"file","filename":"test.qcow2"}}' test4.qcow2
Formatting 'test4.qcow2', fmt=qcow2 size=104857600 backing_file=json:{"encrypt.key-secret":"testsecret",,"driver":"qcow2",,"file":{"driver":"file",,"filename":"test.qcow2"}} cluster_size=65536 lazy_refcounts=off refcount_bits=16
#
This one creates a slightly different result, in that it embeds the secret name into the top layer:
root@focal:~# qemu-img info test4.qcow2
image: test4.qcow2
file format: qcow2
virtual size: 100 MiB (104857600 bytes)
disk size: 196 KiB
cluster_size: 65536
backing file: json:{"encrypt.key-secret":"testsecret","driver":"qcow2","file":{"driver":"file","filename":"test.qcow2"}}
Format specific information:
compat: 1.1
lazy refcounts: false
refcount bits: 16
corrupt: false
This approach doesn't work if you give the backing config without the actual secret:
# qemu-img create -f qcow2 -b 'json:{"encrypt.key-secret":"testsecret","driver":"qcow2","file":{"driver":"file","filename":"test.qcow2"}}' test5.qcow2
qemu-img: test5.qcow2: No secret with id 'testsecret'
Could not open backing image to determine size.
<<< no file created >>>
although you can still provide the size manually:
# qemu-img create -f qcow2 -b 'json:{"encrypt.key-secret":"testsecret","driver":"qcow2","file":{"driver":"file","filename":"test.qcow2"}}' -u test6.qcow2 100M
Formatting 'test6.qcow2', fmt=qcow2 size=104857600 backing_file=json:{"encrypt.key-secret":"testsecret",,"driver":"qcow2",,"file":{"driver":"file",,"filename":"test.qcow2"}} cluster_size=65536 lazy_refcounts=off refcount_bits=16
This last case I think qemu-img should be able to handle for itself, although with some effort I can assemble the pieces myself:
qemu-img create -f qcow2 \
-b 'json:{"encrypt.key-secret":"testsecret","driver":"qcow2","file":{"driver":"file","filename":"test.qcow2"}}' \
-u test7.qcow2 $(qemu-img info --output=json test.qcow2 | jq '.["virtual-size"]')
Aside: in all cases, I'm able to access the qcow2 file by providing the bottom-layer secret. e.g.
# qemu-nbd -c /dev/nbd0 --object secret,id=testsecret,data=abcd1234 --image-opts driver=qcow2,file.driver=file,file.filename=test2.qcow2,backing.encrypt.key-secret=testsecret
... although admittedly it's simpler when the secret info is embedded (case 2 above), as this simplifies to:
# qemu-nbd -c /dev/nbd0 --object secret,id=testsecret,data=abcd1234 test4.qcow2