<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Sep 17, 2020 at 1:06 AM Daniel P. Berrangé <<a href="mailto:berrange@redhat.com">berrange@redhat.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">The storage driver was wired up to support creating raw volumes in LUKS<br>
format, but was never adapted to support LUKS-in-qcow2. This is trivial<br>
as it merely requires the encryption properties to be prefixed with<br>
the "encrypt." prefix, and "encrypt.format=luks" when creating the<br>
volume.<br>
<br>
Signed-off-by: Daniel P. Berrangé <<a href="mailto:berrange@redhat.com" target="_blank">berrange@redhat.com</a>><br>
---<br>
src/storage/storage_util.c | 70 +++++++++++++++++++++++++++++---------<br>
src/util/virqemu.c | 23 +++++++++----<br>
src/util/virqemu.h | 1 +<br>
3 files changed, 72 insertions(+), 22 deletions(-)<br>
<br>
diff --git a/src/storage/storage_util.c b/src/storage/storage_util.c<br>
index cf82ea0a87..e5e4fe428f 100644<br>
--- a/src/storage/storage_util.c<br>
+++ b/src/storage/storage_util.c<br>
@@ -707,7 +707,7 @@ storageBackendCreateQemuImgOpts(virStorageEncryptionInfoDefPtr encinfo,<br>
virStorageFileFormatTypeToString(info->backingFormat));<br>
<br>
if (encinfo)<br>
- virQEMUBuildQemuImgKeySecretOpts(&buf, encinfo, info->secretAlias);<br>
+ virQEMUBuildQemuImgKeySecretOpts(&buf, info->format, encinfo, info->secretAlias);<br>
<br>
if (info->preallocate) {<br>
if (info->size_arg > info->allocation)<br>
@@ -761,7 +761,8 @@ storageBackendCreateQemuImgCheckEncryption(int format,<br>
{<br>
virStorageEncryptionPtr enc = vol->target.encryption;<br>
<br>
- if (format == VIR_STORAGE_FILE_RAW) {<br>
+ if (format == VIR_STORAGE_FILE_RAW ||<br>
+ format == VIR_STORAGE_FILE_QCOW2) {<br>
if (enc->format != VIR_STORAGE_ENCRYPTION_FORMAT_LUKS) {<br>
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,<br>
_("unsupported volume encryption format %d"),<br>
@@ -927,21 +928,34 @@ storageBackendCreateQemuImgSecretObject(virCommandPtr cmd,<br>
}<br>
<br>
<br>
-/* Add a --image-opts to the qemu-img resize command line:<br>
+/* Add a --image-opts to the qemu-img resize command line for use<br>
+ * with encryption:<br>
* --image-opts driver=luks,file.filename=$volpath,key-secret=$secretAlias<br>
+ * or<br>
+ * --image-opts driver=qcow2,file.filename=$volpath,encrypt.key-secret=$secretAlias<br>
*<br>
- * NB: format=raw is assumed<br>
*/<br>
static int<br>
storageBackendResizeQemuImgImageOpts(virCommandPtr cmd,<br>
+ int format,<br>
const char *path,<br>
const char *secretAlias)<br>
{<br>
g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;<br>
g_autofree char *commandStr = NULL;<br>
+ const char *encprefix;<br>
+ const char *driver;<br>
<br>
- virBufferAsprintf(&buf, "driver=luks,key-secret=%s,file.filename=",<br>
- secretAlias);<br>
+ if (format == VIR_STORAGE_FILE_QCOW2) {<br>
+ driver = "qcow2";<br>
+ encprefix = "encrypt.";<br>
+ } else {<br>
+ driver = "luks";<br>
+ encprefix = "";<br>
+ }<br>
+<br>
+ virBufferAsprintf(&buf, "driver=%s,%skey-secret=%s,file.filename=",<br>
+ driver, encprefix, secretAlias);<br>
virQEMUBuildBufferEscapeComma(&buf, path);<br>
<br>
commandStr = virBufferContentAndReset(&buf);<br>
@@ -1006,6 +1020,16 @@ virStorageBackendCreateQemuImgSetInfo(virStoragePoolObjPtr pool,<br>
return -1;<br>
}<br>
}<br></blockquote><div>storagevolxml2argvtest gets segment fault at this function:</div><div>➜ ~ abs_top_srcdir='/root/libvirt-6.7.0' LC_ALL='C' abs_top_builddir='/root/libvirt-6.7.0/build' abs_srcdir='/root/libvirt-6.7.0/tests' abs_builddir='/root/libvirt-6.7.0/build/tests' VIR_TEST_EXPENSIVE='0' LIBVIRT_AUTOSTART='0' /root/libvirt-6.7.0/build/tests/storagevolxml2argvtest <br><br>TEST: storagevolxml2argvtest<br> ...................![1] 916320 segmentation fault (core dumped) abs_top_srcdir='/root/libvirt-6.7.0' LC_ALL='C' abs_top_builddir= abs_srcdir= <br></div><div><br></div><div><br></div><div>Backtrace:</div><div>(gdb) bt<br>#0 0x0000558b997ea149 in virStorageBackendCreateQemuImgSetInfo (info=<synthetic pointer>, convertStep=VIR_STORAGE_VOL_ENCRYPT_CREATE, inputvol=0x558b9b32e810, vol=0x558b9b32f840, pool=0x558b9b323b30) <br> at ../src/storage/storage_util.c:1025<br>#1 0x0000558b997ea149 in virStorageBackendCreateQemuImgCmdFromVol<br> (pool=0x558b9b323b30, vol=0x558b9b32f840, inputvol=0x558b9b32e810, flags=0, create_tool=0x558b997f6a00 <create_tool> "qemu-img", secretPath=0x558b997f6537 "/path/to/secretFile", inputSecretPath=0x558b997f654b "/path/to/inputSecretFile", convertStep=VIR_STORAGE_VOL_ENCRYPT_CREATE) at ../src/storage/storage_util.c:1103<br>#2 0x0000558b997e4b57 in testCompareXMLToArgvFiles<br> (parse_flags=<optimized out>, flags=0, cmdline=0x558b9b325030 "/root/libvirt-6.7.0/tests/storagevolxml2argvdata/luks-convert-encrypt2fileraw.argv", inputvolxml=0x558b9b32f7f0 "/root/libvirt-6.7.0/tests/storagevolxml2xmlin/vol-encrypt2.xml", inputpoolxml=0x558b9b331730 "/root/libvirt-6.7.0/tests/storagepoolxml2xmlin/pool-dir.xml", volxml=0x558b9b3309f0 "/root/libvirt-6.7.0/tests/storagevolxml2xmlin/vol-file.xml", poolxml=0x558b9b32a530 "/root/libvirt-6.7.0/tests/storagepoolxml2xmlin/pool-dir.xml", shouldFail=false) at ../tests/storagevolxml2argvtest.c:92<br>#3 0x0000558b997e4b57 in testCompareXMLToArgvHelper (data=<optimized out>) at ../tests/storagevolxml2argvtest.c:174<br>#4 0x0000558b997e561a in virTestRun (title=0x558b997f6928 "Storage Vol XML-2-argv luks-convert-encrypt2fileraw", body=0x558b997e4930 <testCompareXMLToArgvHelper>, data=0x7ffea16a5870) at ../tests/testutils.c:142 <br>#5 0x0000558b997e489a in mymain () at ../tests/storagevolxml2argvtest.c:271<br>#6 0x0000558b997e6512 in virTestMain (argc=1, argv=0x7ffea16a5aa8, func=0x558b997e40d0 <mymain>) at ../tests/testutils.c:841 <br>#7 0x00007f2597f5b7b3 in __libc_start_main (main=0x558b997e3fd0 <main>, argc=1, argv=0x7ffea16a5aa8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7ffea16a5a98) at ../csu/libc-start.c:308 <br>#8 0x0000558b997e400e in _start () at ../tests/storagevolxml2argvtest.c:282 </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+ if (inputvol && inputvol->target.format == VIR_STORAGE_FILE_RAW &&<br>
+ inputvol->target.encryption) {<br>
+ if (vol->target.encryption->format == VIR_STORAGE_ENCRYPTION_FORMAT_LUKS) {<br>
+ info->type = "luks";<br>
+ } else {<br>
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",<br>
+ _("Only luks encryption is supported for raw files"));<br>
+ return -1;<br>
+ }<br>
+ }<br>
<br>
if (inputvol &&<br>
storageBackendCreateQemuImgSetInput(inputvol, convertStep, info) < 0)<br>
@@ -1056,6 +1080,8 @@ virStorageBackendCreateQemuImgCmdFromVol(virStoragePoolObjPtr pool,<br>
virStorageEncryptionPtr inputenc = inputvol ? inputvol->target.encryption : NULL;<br>
virStorageEncryptionInfoDefPtr encinfo = NULL;<br>
g_autofree char *inputSecretAlias = NULL;<br>
+ const char *encprefix;<br>
+ const char *inputencprefix;<br>
<br>
virCheckFlags(VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA, NULL);<br>
<br>
@@ -1134,24 +1160,34 @@ virStorageBackendCreateQemuImgCmdFromVol(virStoragePoolObjPtr pool,<br>
virCommandAddArgFormat(cmd, "%lluK", info.size_arg);<br>
} else {<br>
/* source */<br>
- if (inputenc)<br>
+ if (inputenc) {<br>
+ if (inputvol->target.format == VIR_STORAGE_FILE_QCOW2)<br>
+ inputencprefix = "encrypt.";<br>
+ else<br>
+ inputencprefix = "";<br>
virCommandAddArgFormat(cmd,<br>
- "driver=luks,file.filename=%s,key-secret=%s",<br>
- info.inputPath, inputSecretAlias);<br>
- else<br>
+ "driver=%s,file.filename=%s,%skey-secret=%s",<br>
+ info.inputType, info.inputPath, inputencprefix, inputSecretAlias);<br>
+ } else {<br>
virCommandAddArgFormat(cmd, "driver=%s,file.filename=%s",<br>
info.inputType ? info.inputType : "raw",<br>
info.inputPath);<br>
+ }<br>
<br>
/* dest */<br>
- if (enc)<br>
+ if (enc) {<br>
+ if (vol->target.format == VIR_STORAGE_FILE_QCOW2)<br>
+ encprefix = "encrypt.";<br>
+ else<br>
+ encprefix = "";<br>
+<br>
virCommandAddArgFormat(cmd,<br>
- "driver=%s,file.filename=%s,key-secret=%s",<br>
- info.type, info.path, info.secretAlias);<br>
- else<br>
+ "driver=%s,file.filename=%s,%skey-secret=%s",<br>
+ info.type, info.path, encprefix, info.secretAlias);<br>
+ } else {<br>
virCommandAddArgFormat(cmd, "driver=%s,file.filename=%s",<br>
info.type, info.path);<br>
-<br>
+ }<br>
}<br>
VIR_FREE(info.secretAlias);<br>
<br>
@@ -2276,7 +2312,9 @@ storageBackendResizeQemuImg(virStoragePoolObjPtr pool,<br>
secretAlias) < 0)<br>
goto cleanup;<br>
<br>
- if (storageBackendResizeQemuImgImageOpts(cmd, vol->target.path,<br>
+ if (storageBackendResizeQemuImgImageOpts(cmd,<br>
+ vol->target.format,<br>
+ vol->target.path,<br>
secretAlias) < 0)<br>
goto cleanup;<br>
}<br>
diff --git a/src/util/virqemu.c b/src/util/virqemu.c<br>
index 25d6fd35c5..bbb38eed75 100644<br>
--- a/src/util/virqemu.c<br>
+++ b/src/util/virqemu.c<br>
@@ -28,6 +28,7 @@<br>
#include "virqemu.h"<br>
#include "virstring.h"<br>
#include "viralloc.h"<br>
+#include "virstoragefile.h"<br>
<br>
#define VIR_FROM_THIS VIR_FROM_NONE<br>
<br>
@@ -407,36 +408,46 @@ virQEMUBuildBufferEscapeComma(virBufferPtr buf, const char *str)<br>
*/<br>
void<br>
virQEMUBuildQemuImgKeySecretOpts(virBufferPtr buf,<br>
+ int format,<br>
virStorageEncryptionInfoDefPtr encinfo,<br>
const char *alias)<br>
{<br>
- virBufferAsprintf(buf, "key-secret=%s,", alias);<br>
+ const char *encprefix;<br>
+<br>
+ if (format == VIR_STORAGE_FILE_QCOW2) {<br>
+ virBufferAsprintf(buf, "encrypt.format=luks,");<br></blockquote><div>syntax check is failed here:<br></div><div>--- command ---<br>09:13:21 /usr/bin/make -C /root/libvirt-6.7.0/build/build-aux sc_prohibit_virBufferAsprintf_with_string_literal<br>--- stdout ---<br>make: Entering directory '/root/libvirt-6.7.0/build/build-aux'<br>prohibit_virBufferAsprintf_with_string_literal<br>/root/libvirt-6.7.0/src/util/virqemu.c:418: virBufferAsprintf(buf, "encrypt.format=luks,");<br> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+ encprefix = "encrypt.";<br>
+ } else {<br>
+ encprefix = "";<br>
+ }<br>
+<br>
+ virBufferAsprintf(buf, "%skey-secret=%s,", encprefix, alias);<br>
<br>
if (!encinfo->cipher_name)<br>
return;<br>
<br>
- virBufferAddLit(buf, "cipher-alg=");<br>
+ virBufferAsprintf(buf, "%scipher-alg=", encprefix);<br>
virQEMUBuildBufferEscapeComma(buf, encinfo->cipher_name);<br>
virBufferAsprintf(buf, "-%u,", encinfo->cipher_size);<br>
if (encinfo->cipher_mode) {<br>
- virBufferAddLit(buf, "cipher-mode=");<br>
+ virBufferAsprintf(buf, "%scipher-mode=", encprefix);<br>
virQEMUBuildBufferEscapeComma(buf, encinfo->cipher_mode);<br>
virBufferAddLit(buf, ",");<br>
}<br>
if (encinfo->cipher_hash) {<br>
- virBufferAddLit(buf, "hash-alg=");<br>
+ virBufferAsprintf(buf, "%shash-alg=", encprefix);<br>
virQEMUBuildBufferEscapeComma(buf, encinfo->cipher_hash);<br>
virBufferAddLit(buf, ",");<br>
}<br>
if (!encinfo->ivgen_name)<br>
return;<br>
<br>
- virBufferAddLit(buf, "ivgen-alg=");<br>
+ virBufferAsprintf(buf, "%sivgen-alg=", encprefix);<br>
virQEMUBuildBufferEscapeComma(buf, encinfo->ivgen_name);<br>
virBufferAddLit(buf, ",");<br>
<br>
if (encinfo->ivgen_hash) {<br>
- virBufferAddLit(buf, "ivgen-hash-alg=");<br>
+ virBufferAsprintf(buf, "%sivgen-hash-alg=", encprefix);<br>
virQEMUBuildBufferEscapeComma(buf, encinfo->ivgen_hash);<br>
virBufferAddLit(buf, ",");<br>
}<br>
diff --git a/src/util/virqemu.h b/src/util/virqemu.h<br>
index b1296cb657..be14c04d51 100644<br>
--- a/src/util/virqemu.h<br>
+++ b/src/util/virqemu.h<br>
@@ -60,6 +60,7 @@ char *virQEMUBuildDriveCommandlineFromJSON(virJSONValuePtr src);<br>
<br>
void virQEMUBuildBufferEscapeComma(virBufferPtr buf, const char *str);<br>
void virQEMUBuildQemuImgKeySecretOpts(virBufferPtr buf,<br>
+ int format,<br>
virStorageEncryptionInfoDefPtr enc,<br>
const char *alias)<br>
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);<br>
-- <br>
2.26.2<br>
<br>
</blockquote></div><br clear="all"><br>-- <br><div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr">Reviewed-by: Han Han <<a href="mailto:hhan@redhat.com" target="_blank">hhan@redhat.com</a>><br></div></div></div>