<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>