[PATCH v4 0/5] Add support for librbd encryption

v4: - added disk post parse to image creation flow in qemublocktest (since more tests failed after adding engine validation) - removed symlink changes - added luks2 and engine documentation - switched to using enum engine instead of int - added validation for encryption engine and formats v3: rebased on master v2: addressed (hopefully) all of Peter's v1 comments (thanks Peter!) Or Ozeri (5): qemu: add disk post parse to qemublocktest qemu: capablities: Detect presence of 'rbd-encryption' as QEMU_CAPS_RBD_ENCRYPTION conf: add encryption engine property qemu: add librbd encryption engine conf: add luks2 encryption format docs/formatstorageencryption.html.in | 23 ++++- docs/schemas/domainbackup.rng | 7 ++ docs/schemas/storagecommon.rng | 9 ++ src/conf/storage_encryption_conf.c | 29 ++++++- src/conf/storage_encryption_conf.h | 11 +++ src/qemu/qemu_block.c | 33 ++++++++ src/qemu/qemu_capabilities.c | 2 + src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_domain.c | 61 +++++++++++++- src/qemu/qemu_domain.h | 3 + tests/qemublocktest.c | 29 +++---- .../caps_6.1.0.x86_64.xml | 1 + tests/qemustatusxml2xmldata/upgrade-out.xml | 6 +- ...sk-network-rbd-encryption.x86_64-6.0.0.err | 1 + ...-network-rbd-encryption.x86_64-latest.args | 49 +++++++++++ .../disk-network-rbd-encryption.xml | 75 +++++++++++++++++ tests/qemuxml2argvdata/disk-nvme.xml | 2 +- .../qemuxml2argvdata/encrypted-disk-usage.xml | 2 +- tests/qemuxml2argvdata/luks-disks.xml | 4 +- tests/qemuxml2argvdata/user-aliases.xml | 2 +- tests/qemuxml2argvtest.c | 2 + ...k-network-rbd-encryption.x86_64-latest.xml | 83 +++++++++++++++++++ .../disk-slices.x86_64-latest.xml | 4 +- tests/qemuxml2xmloutdata/encrypted-disk.xml | 2 +- .../luks-disks-source-qcow2.x86_64-latest.xml | 14 ++-- .../qemuxml2xmloutdata/luks-disks-source.xml | 10 +-- tests/qemuxml2xmltest.c | 1 + 27 files changed, 421 insertions(+), 45 deletions(-) create mode 100644 tests/qemuxml2argvdata/disk-network-rbd-encryption.x86_64-6.0.0.err create mode 100644 tests/qemuxml2argvdata/disk-network-rbd-encryption.x86_64-latest.args create mode 100644 tests/qemuxml2argvdata/disk-network-rbd-encryption.xml create mode 100644 tests/qemuxml2xmloutdata/disk-network-rbd-encryption.x86_64-latest.xml -- 2.25.1

The post parse callback is part of the real (non-test) processing flow. This commit adds it (for disks) to the qemublocktest flow as well. Specifically, this will be needed for tests that use luks encryption, so that the default encryption engine (which is added in an upcoming commit) will be overridden by qemu. Signed-off-by: Or Ozeri <oro@il.ibm.com> --- src/qemu/qemu_domain.c | 2 +- src/qemu/qemu_domain.h | 3 +++ tests/qemublocktest.c | 29 ++++++++++++----------------- 3 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index a755f8678e..288a40bca6 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -5259,7 +5259,7 @@ qemuDomainDeviceDiskDefPostParseRestoreSecAlias(virDomainDiskDef *disk, } -static int +int qemuDomainDeviceDiskDefPostParse(virDomainDiskDef *disk, unsigned int parseFlags) { diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 64f92988b7..0642e44fbc 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -872,6 +872,9 @@ int qemuDomainSecretPrepare(virQEMUDriver *driver, int qemuDomainDeviceDefValidateDisk(const virDomainDiskDef *disk, virQEMUCaps *qemuCaps); +int qemuDomainDeviceDiskDefPostParse(virDomainDiskDef *disk, + unsigned int parseFlags); + int qemuDomainPrepareChannel(virDomainChrDef *chr, const char *domainChannelTargetDir) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index 3e61e923a9..0176fbd3f4 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -276,6 +276,9 @@ testQemuDiskXMLToProps(const void *opaque) VIR_DOMAIN_DEF_PARSE_STATUS))) return -1; + if (qemuDomainDeviceDiskDefPostParse(disk, 0) < 0) + return -1; + if (!(vmdef = virDomainDefNew(data->driver->xmlopt))) return -1; @@ -470,32 +473,24 @@ testQemuImageCreateLoadDiskXML(const char *name, virDomainXMLOption *xmlopt) { - virDomainSnapshotDiskDef *diskdef = NULL; - g_autoptr(xmlDoc) doc = NULL; - g_autoptr(xmlXPathContext) ctxt = NULL; - xmlNodePtr node; + virDomainDiskDef *disk = NULL; g_autofree char *xmlpath = NULL; - virStorageSource *ret = NULL; + g_autofree char *xmlstr = NULL; xmlpath = g_strdup_printf("%s%s.xml", testQemuImageCreatePath, name); - if (!(doc = virXMLParseFileCtxt(xmlpath, &ctxt))) + if (virTestLoadFile(xmlpath, &xmlstr) < 0) return NULL; - if (!(node = virXPathNode("//disk", ctxt))) { - VIR_TEST_VERBOSE("failed to find <source> element\n"); + /* qemu stores node names in the status XML portion */ + if (!(disk = virDomainDiskDefParse(xmlstr, xmlopt, + VIR_DOMAIN_DEF_PARSE_STATUS))) return NULL; - } - diskdef = g_new0(virDomainSnapshotDiskDef, 1); - - if (virDomainSnapshotDiskDefParseXML(node, ctxt, diskdef, - VIR_DOMAIN_DEF_PARSE_STATUS, - xmlopt) == 0) - ret = g_steal_pointer(&diskdef->src); + if (qemuDomainDeviceDiskDefPostParse(disk, 0) < 0) + return NULL; - virDomainSnapshotDiskDefFree(diskdef); - return ret; + return disk->src; } -- 2.25.1

On Thu, Oct 07, 2021 at 14:21:17 -0500, Or Ozeri wrote:
The post parse callback is part of the real (non-test) processing flow. This commit adds it (for disks) to the qemublocktest flow as well. Specifically, this will be needed for tests that use luks encryption, so that the default encryption engine (which is added in an upcoming commit) will be overridden by qemu.
Signed-off-by: Or Ozeri <oro@il.ibm.com> --- src/qemu/qemu_domain.c | 2 +- src/qemu/qemu_domain.h | 3 +++ tests/qemublocktest.c | 29 ++++++++++++----------------- 3 files changed, 16 insertions(+), 18 deletions(-)
Reviewed-by: Peter Krempa <pkrempa@redhat.com>

rbd encryption is new in qemu 6.1.0. This commit adds capability probing for it. Signed-off-by: Or Ozeri <oro@il.ibm.com> --- src/qemu/qemu_capabilities.c | 2 ++ src/qemu/qemu_capabilities.h | 1 + tests/qemucapabilitiesdata/caps_6.1.0.x86_64.xml | 1 + 3 files changed, 4 insertions(+) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 82687dbf39..ea0734db15 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -644,6 +644,7 @@ VIR_ENUM_IMPL(virQEMUCaps, "virtio-mem-pci", /* QEMU_CAPS_DEVICE_VIRTIO_MEM_PCI */ "memory-backend-file.reserve", /* QEMU_CAPS_MEMORY_BACKEND_RESERVE */ "piix4.acpi-root-pci-hotplug", /* QEMU_CAPS_PIIX4_ACPI_ROOT_PCI_HOTPLUG */ + "rbd-encryption", /* QEMU_CAPS_RBD_ENCRYPTION */ ); @@ -1565,6 +1566,7 @@ static struct virQEMUCapsStringFlags virQEMUCapsQMPSchemaQueries[] = { { "blockdev-add/arg-type/+file/$dynamic-auto-read-only", QEMU_CAPS_BLOCK_FILE_AUTO_READONLY_DYNAMIC }, { "blockdev-add/arg-type/+nvme", QEMU_CAPS_DRIVE_NVME }, { "blockdev-add/arg-type/+file/aio/^io_uring", QEMU_CAPS_AIO_IO_URING }, + { "blockdev-add/arg-type/+rbd/encrypt", QEMU_CAPS_RBD_ENCRYPTION }, { "blockdev-add/arg-type/discard", QEMU_CAPS_DRIVE_DISCARD }, { "blockdev-add/arg-type/detect-zeroes", QEMU_CAPS_DRIVE_DETECT_ZEROES }, { "blockdev-backup", QEMU_CAPS_BLOCKDEV_BACKUP }, diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 2bbfc15dc4..674da98539 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -624,6 +624,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */ QEMU_CAPS_DEVICE_VIRTIO_MEM_PCI, /* -device virtio-mem-pci */ QEMU_CAPS_MEMORY_BACKEND_RESERVE, /* -object memory-backend-*.reserve= */ QEMU_CAPS_PIIX4_ACPI_ROOT_PCI_HOTPLUG, /* -M pc PIIX4_PM.acpi-root-pci-hotplug */ + QEMU_CAPS_RBD_ENCRYPTION, /* Ceph RBD encryption support */ QEMU_CAPS_LAST /* this must always be the last item */ } virQEMUCapsFlags; diff --git a/tests/qemucapabilitiesdata/caps_6.1.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_6.1.0.x86_64.xml index 87b37a2b7c..8180cfd6c2 100644 --- a/tests/qemucapabilitiesdata/caps_6.1.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_6.1.0.x86_64.xml @@ -243,6 +243,7 @@ <flag name='virtio-mem-pci'/> <flag name='memory-backend-file.reserve'/> <flag name='piix4.acpi-root-pci-hotplug'/> + <flag name='rbd-encryption'/> <version>6001000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>43100243</microcodeVersion> -- 2.25.1

On Thu, Oct 07, 2021 at 14:21:18 -0500, Or Ozeri wrote:
rbd encryption is new in qemu 6.1.0. This commit adds capability probing for it.
Signed-off-by: Or Ozeri <oro@il.ibm.com> --- src/qemu/qemu_capabilities.c | 2 ++ src/qemu/qemu_capabilities.h | 1 + tests/qemucapabilitiesdata/caps_6.1.0.x86_64.xml | 1 + 3 files changed, 4 insertions(+)
Some new test files were added in the meanwhile. I'll update the patch to accomodate those. Reviewed-by: Peter Krempa <pkrempa@redhat.com>

This commit extends libvirt XML configuration to support a custom encryption engine. This means that <encryption format="luks" engine="qemu"> becomes valid. The only engine for now is qemu. However, a new engine (librbd) will be added in an upcoming commit. If no engine is specified, qemu will be used (assuming qemu driver is used). Signed-off-by: Or Ozeri <oro@il.ibm.com> --- docs/formatstorageencryption.html.in | 6 +++++ docs/schemas/domainbackup.rng | 7 +++++ docs/schemas/storagecommon.rng | 7 +++++ src/conf/storage_encryption_conf.c | 27 ++++++++++++++++++- src/conf/storage_encryption_conf.h | 9 +++++++ src/qemu/qemu_block.c | 2 ++ src/qemu/qemu_domain.c | 20 ++++++++++++++ tests/qemustatusxml2xmldata/upgrade-out.xml | 6 ++--- tests/qemuxml2argvdata/disk-nvme.xml | 2 +- .../qemuxml2argvdata/encrypted-disk-usage.xml | 2 +- tests/qemuxml2argvdata/luks-disks.xml | 4 +-- tests/qemuxml2argvdata/user-aliases.xml | 2 +- .../disk-slices.x86_64-latest.xml | 4 +-- tests/qemuxml2xmloutdata/encrypted-disk.xml | 2 +- .../luks-disks-source-qcow2.x86_64-latest.xml | 14 +++++----- .../qemuxml2xmloutdata/luks-disks-source.xml | 10 +++---- 16 files changed, 100 insertions(+), 24 deletions(-) diff --git a/docs/formatstorageencryption.html.in b/docs/formatstorageencryption.html.in index 7215c307d7..178fcd0d7c 100644 --- a/docs/formatstorageencryption.html.in +++ b/docs/formatstorageencryption.html.in @@ -23,6 +23,12 @@ content of the <code>encryption</code> tag. Other format values may be defined in the future. </p> + <p> + The <code>encryption</code> tag supports an optional <code>engine</code> + tag, which allows selecting which component actually handles + the encryption. Currently defined values of <code>engine</code> are + <code>qemu</code>. + </p> <p> The <code>encryption</code> tag can currently contain a sequence of <code>secret</code> tags, each with mandatory attributes <code>type</code> diff --git a/docs/schemas/domainbackup.rng b/docs/schemas/domainbackup.rng index c03455a5a7..05cc28ab00 100644 --- a/docs/schemas/domainbackup.rng +++ b/docs/schemas/domainbackup.rng @@ -14,6 +14,13 @@ <value>luks</value> </choice> </attribute> + <optional> + <attribute name="engine"> + <choice> + <value>qemu</value> + </choice> + </attribute> + </optional> <interleave> <ref name="secret"/> <optional> diff --git a/docs/schemas/storagecommon.rng b/docs/schemas/storagecommon.rng index 9ebb27700d..60dcfac06c 100644 --- a/docs/schemas/storagecommon.rng +++ b/docs/schemas/storagecommon.rng @@ -15,6 +15,13 @@ <value>luks</value> </choice> </attribute> + <optional> + <attribute name="engine"> + <choice> + <value>qemu</value> + </choice> + </attribute> + </optional> <interleave> <ref name="secret"/> <optional> diff --git a/src/conf/storage_encryption_conf.c b/src/conf/storage_encryption_conf.c index 9112b96cc7..59178b41ef 100644 --- a/src/conf/storage_encryption_conf.c +++ b/src/conf/storage_encryption_conf.c @@ -47,6 +47,11 @@ VIR_ENUM_IMPL(virStorageEncryptionFormat, "default", "qcow", "luks", ); +VIR_ENUM_IMPL(virStorageEncryptionEngine, + VIR_STORAGE_ENCRYPTION_ENGINE_LAST, + "default", "qemu", +); + static void virStorageEncryptionInfoDefClear(virStorageEncryptionInfoDef *def) { @@ -120,6 +125,7 @@ virStorageEncryptionCopy(const virStorageEncryption *src) ret->secrets = g_new0(virStorageEncryptionSecret *, src->nsecrets); ret->nsecrets = src->nsecrets; ret->format = src->format; + ret->engine = src->engine; for (i = 0; i < src->nsecrets; i++) { if (!(ret->secrets[i] = virStorageEncryptionSecretCopy(src->secrets[i]))) @@ -217,6 +223,7 @@ virStorageEncryptionParseNode(xmlNodePtr node, xmlNodePtr *nodes = NULL; virStorageEncryption *encdef = NULL; virStorageEncryption *ret = NULL; + g_autofree char *engine_str = NULL; g_autofree char *format_str = NULL; int n; size_t i; @@ -239,6 +246,12 @@ virStorageEncryptionParseNode(xmlNodePtr node, goto cleanup; } + if (virXMLPropEnum(node, "engine", + virStorageEncryptionEngineTypeFromString, + VIR_XML_PROP_NONZERO, + &encdef->engine) < 0) + goto cleanup; + if ((n = virXPathNodeSet("./secret", ctxt, &nodes)) < 0) goto cleanup; @@ -327,6 +340,7 @@ int virStorageEncryptionFormat(virBuffer *buf, virStorageEncryption *enc) { + const char *engine; const char *format; size_t i; @@ -335,7 +349,18 @@ virStorageEncryptionFormat(virBuffer *buf, "%s", _("unexpected encryption format")); return -1; } - virBufferAsprintf(buf, "<encryption format='%s'>\n", format); + if (enc->engine == VIR_STORAGE_ENCRYPTION_ENGINE_DEFAULT) { + virBufferAsprintf(buf, "<encryption format='%s'>\n", format); + } else { + if (!(engine = virStorageEncryptionEngineTypeToString(enc->engine))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("unexpected encryption engine")); + return -1; + } + virBufferAsprintf(buf, "<encryption format='%s' engine='%s'>\n", + format, engine); + } + virBufferAdjustIndent(buf, 2); for (i = 0; i < enc->nsecrets; i++) { diff --git a/src/conf/storage_encryption_conf.h b/src/conf/storage_encryption_conf.h index 34adbd5f7b..e0ac0fe4bf 100644 --- a/src/conf/storage_encryption_conf.h +++ b/src/conf/storage_encryption_conf.h @@ -51,6 +51,14 @@ struct _virStorageEncryptionInfoDef { char *ivgen_hash; }; +typedef enum { + VIR_STORAGE_ENCRYPTION_ENGINE_DEFAULT = 0, + VIR_STORAGE_ENCRYPTION_ENGINE_QEMU, + + VIR_STORAGE_ENCRYPTION_ENGINE_LAST, +} virStorageEncryptionEngine; +VIR_ENUM_DECL(virStorageEncryptionEngine); + typedef enum { /* "default" is only valid for volume creation */ VIR_STORAGE_ENCRYPTION_FORMAT_DEFAULT = 0, @@ -63,6 +71,7 @@ VIR_ENUM_DECL(virStorageEncryptionFormat); typedef struct _virStorageEncryption virStorageEncryption; struct _virStorageEncryption { + virStorageEncryptionEngine engine; int format; /* virStorageEncryptionFormatType */ int payload_offset; diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index 393d3f44d7..18c5852d2e 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -1314,6 +1314,7 @@ qemuBlockStorageSourceGetCryptoProps(virStorageSource *src, *encprops = NULL; if (!src->encryption || + src->encryption->engine != VIR_STORAGE_ENCRYPTION_ENGINE_QEMU || !srcpriv || !srcpriv->encinfo) return 0; @@ -1448,6 +1449,7 @@ qemuBlockStorageSourceGetBlockdevFormatProps(virStorageSource *src) * put a raw layer on top */ case VIR_STORAGE_FILE_RAW: if (src->encryption && + src->encryption->engine == VIR_STORAGE_ENCRYPTION_ENGINE_QEMU && src->encryption->format == VIR_STORAGE_ENCRYPTION_FORMAT_LUKS) { if (qemuBlockStorageSourceGetFormatLUKSProps(src, props) < 0) return NULL; diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 288a40bca6..354f65c6d5 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -4811,6 +4811,18 @@ qemuDomainValidateStorageSource(virStorageSource *src, } } + if (src->encryption) { + switch (src->encryption->engine) { + case VIR_STORAGE_ENCRYPTION_ENGINE_QEMU: + break; + case VIR_STORAGE_ENCRYPTION_ENGINE_DEFAULT: + case VIR_STORAGE_ENCRYPTION_ENGINE_LAST: + virReportEnumRangeError(virStorageEncryptionEngine, + src->encryption->engine); + return -1; + } + } + return 0; } @@ -5263,6 +5275,8 @@ int qemuDomainDeviceDiskDefPostParse(virDomainDiskDef *disk, unsigned int parseFlags) { + virStorageSource *n; + /* set default disk types and drivers */ if (!virDomainDiskGetDriver(disk)) virDomainDiskSetDriver(disk, "qemu"); @@ -5277,6 +5291,12 @@ qemuDomainDeviceDiskDefPostParse(virDomainDiskDef *disk, disk->mirror->format == VIR_STORAGE_FILE_NONE) disk->mirror->format = VIR_STORAGE_FILE_RAW; + /* default disk encryption engine */ + for (n = disk->src; virStorageSourceIsBacking(n); n = n->backingStore) { + if (n->encryption && n->encryption->engine == VIR_STORAGE_ENCRYPTION_ENGINE_DEFAULT) + n->encryption->engine = VIR_STORAGE_ENCRYPTION_ENGINE_QEMU; + } + if (qemuDomainDeviceDiskDefPostParseRestoreSecAlias(disk, parseFlags) < 0) return -1; diff --git a/tests/qemustatusxml2xmldata/upgrade-out.xml b/tests/qemustatusxml2xmldata/upgrade-out.xml index f9476731f6..5218092cb9 100644 --- a/tests/qemustatusxml2xmldata/upgrade-out.xml +++ b/tests/qemustatusxml2xmldata/upgrade-out.xml @@ -316,7 +316,7 @@ <disk type='file' device='disk'> <driver name='qemu' type='qcow2'/> <source file='/var/lib/libvirt/images/b.qcow2'> - <encryption format='luks'> + <encryption format='luks' engine='qemu'> <secret type='passphrase' uuid='0a81f5b2-8403-7b23-c8d6-21ccc2f80d6f'/> </encryption> <privateData> @@ -333,7 +333,7 @@ <disk type='file' device='disk'> <driver name='qemu' type='qcow2'/> <source file='/var/lib/libvirt/images/c.qcow2'> - <encryption format='luks'> + <encryption format='luks' engine='qemu'> <secret type='passphrase' uuid='0a81f5b2-8403-7b23-c8d6-21ccc2f80d6f'/> </encryption> <privateData> @@ -354,7 +354,7 @@ <auth username='testuser-iscsi'> <secret type='iscsi' usage='testuser-iscsi-secret'/> </auth> - <encryption format='luks'> + <encryption format='luks' engine='qemu'> <secret type='passphrase' uuid='0a81f5b2-8403-7b23-c8d6-21ccc2f80d6f'/> </encryption> <privateData> diff --git a/tests/qemuxml2argvdata/disk-nvme.xml b/tests/qemuxml2argvdata/disk-nvme.xml index 1ccbbfd598..9a5fafce7d 100644 --- a/tests/qemuxml2argvdata/disk-nvme.xml +++ b/tests/qemuxml2argvdata/disk-nvme.xml @@ -42,7 +42,7 @@ <driver name='qemu' type='qcow2' cache='none'/> <source type='pci' managed='no' namespace='2'> <address domain='0x0001' bus='0x02' slot='0x00' function='0x0'/> - <encryption format='luks'> + <encryption format='luks' engine='qemu'> <secret type='passphrase' uuid='0a81f5b2-8403-7b23-c8d6-21ccc2f80d6f'/> </encryption> </source> diff --git a/tests/qemuxml2argvdata/encrypted-disk-usage.xml b/tests/qemuxml2argvdata/encrypted-disk-usage.xml index 7c2da9ee83..d2b87b94b6 100644 --- a/tests/qemuxml2argvdata/encrypted-disk-usage.xml +++ b/tests/qemuxml2argvdata/encrypted-disk-usage.xml @@ -18,7 +18,7 @@ <driver name='qemu' type='qcow2'/> <source file='/storage/guest_disks/encryptdisk'/> <target dev='vda' bus='virtio'/> - <encryption format='luks'> + <encryption format='luks' engine='qemu'> <secret type='passphrase' usage='/storage/guest_disks/encryptdisk'/> </encryption> <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> diff --git a/tests/qemuxml2argvdata/luks-disks.xml b/tests/qemuxml2argvdata/luks-disks.xml index ae6d3d996c..1c76f0dc26 100644 --- a/tests/qemuxml2argvdata/luks-disks.xml +++ b/tests/qemuxml2argvdata/luks-disks.xml @@ -18,7 +18,7 @@ <driver name='qemu' type='raw'/> <source file='/storage/guest_disks/encryptdisk'/> <target dev='vda' bus='virtio'/> - <encryption format='luks'> + <encryption format='luks' engine='qemu'> <secret type='passphrase' uuid='0a81f5b2-8403-7b23-c8d6-21ccc2f80d6f'/> </encryption> <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> @@ -27,7 +27,7 @@ <driver name='qemu' type='raw'/> <source file='/storage/guest_disks/encryptdisk2'/> <target dev='vdb' bus='virtio'/> - <encryption format='luks'> + <encryption format='luks' engine='qemu'> <secret type='passphrase' usage='/storage/guest_disks/encryptdisk2'/> </encryption> <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> diff --git a/tests/qemuxml2argvdata/user-aliases.xml b/tests/qemuxml2argvdata/user-aliases.xml index 47bfc56e73..10b7749521 100644 --- a/tests/qemuxml2argvdata/user-aliases.xml +++ b/tests/qemuxml2argvdata/user-aliases.xml @@ -55,7 +55,7 @@ <driver name='qemu' type='qcow2'/> <source file='/var/lib/libvirt/images/OtherDemo.img'/> <target dev='vdb' bus='virtio'/> - <encryption format='luks'> + <encryption format='luks' engine='qemu'> <secret type='passphrase' uuid='e78d4b51-a2af-485f-b0f5-afca709a80f4'/> </encryption> <alias name='ua-myEncryptedDisk1'/> diff --git a/tests/qemuxml2xmloutdata/disk-slices.x86_64-latest.xml b/tests/qemuxml2xmloutdata/disk-slices.x86_64-latest.xml index be5cd25084..a058cbad61 100644 --- a/tests/qemuxml2xmloutdata/disk-slices.x86_64-latest.xml +++ b/tests/qemuxml2xmloutdata/disk-slices.x86_64-latest.xml @@ -49,7 +49,7 @@ <slices> <slice type='storage' offset='1234' size='321'/> </slices> - <encryption format='luks'> + <encryption format='luks' engine='qemu'> <secret type='passphrase' uuid='0a81f5b2-8403-7b23-c8d6-21ccc2f80d6f'/> </encryption> </source> @@ -75,7 +75,7 @@ <slices> <slice type='storage' offset='1234' size='321'/> </slices> - <encryption format='luks'> + <encryption format='luks' engine='qemu'> <secret type='passphrase' uuid='0a81f5b2-8403-7b23-c8d6-21ccc2f80d6f'/> </encryption> </source> diff --git a/tests/qemuxml2xmloutdata/encrypted-disk.xml b/tests/qemuxml2xmloutdata/encrypted-disk.xml index 06f2c5b47c..e30c8a36e8 100644 --- a/tests/qemuxml2xmloutdata/encrypted-disk.xml +++ b/tests/qemuxml2xmloutdata/encrypted-disk.xml @@ -18,7 +18,7 @@ <driver name='qemu' type='qcow2'/> <source file='/storage/guest_disks/encryptdisk'/> <target dev='vda' bus='virtio'/> - <encryption format='luks'> + <encryption format='luks' engine='qemu'> <secret type='passphrase' uuid='0a81f5b2-8403-7b23-c8d6-21ccc2f80d6f'/> </encryption> <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> diff --git a/tests/qemuxml2xmloutdata/luks-disks-source-qcow2.x86_64-latest.xml b/tests/qemuxml2xmloutdata/luks-disks-source-qcow2.x86_64-latest.xml index 5f600f5ba7..7f98dd597e 100644 --- a/tests/qemuxml2xmloutdata/luks-disks-source-qcow2.x86_64-latest.xml +++ b/tests/qemuxml2xmloutdata/luks-disks-source-qcow2.x86_64-latest.xml @@ -20,7 +20,7 @@ <disk type='file' device='disk'> <driver name='qemu' type='qcow2'/> <source file='/storage/guest_disks/encryptdisk'> - <encryption format='luks'> + <encryption format='luks' engine='qemu'> <secret type='passphrase' uuid='0a81f5b2-8403-7b23-c8d6-21ccc2f80d6f'/> </encryption> </source> @@ -30,7 +30,7 @@ <disk type='file' device='disk'> <driver name='qemu' type='qcow2'/> <source file='/storage/guest_disks/encryptdisk2'> - <encryption format='luks'> + <encryption format='luks' engine='qemu'> <secret type='passphrase' usage='/storage/guest_disks/encryptdisk2'/> </encryption> </source> @@ -44,7 +44,7 @@ <auth username='myname'> <secret type='iscsi' uuid='0a81f5b2-8403-7b23-c8d6-21ccc2f80e80'/> </auth> - <encryption format='luks'> + <encryption format='luks' engine='qemu'> <secret type='passphrase' uuid='0a81f5b2-8403-7b23-c8d6-21ccc2f80f77'/> </encryption> </source> @@ -54,7 +54,7 @@ <disk type='volume' device='disk'> <driver name='qemu' type='qcow2'/> <source pool='pool-iscsi' volume='unit:0:0:3' mode='direct'> - <encryption format='luks'> + <encryption format='luks' engine='qemu'> <secret type='passphrase' uuid='0a81f5b2-8403-7b23-c8d6-21ccc2f80f80'/> </encryption> </source> @@ -67,7 +67,7 @@ <host name='mon1.example.org' port='6321'/> <host name='mon2.example.org' port='6322'/> <host name='mon3.example.org' port='6322'/> - <encryption format='luks'> + <encryption format='luks' engine='qemu'> <secret type='passphrase' uuid='0a81f5b2-8403-7b23-c8d6-21ccc2f80fb0'/> </encryption> </source> @@ -77,14 +77,14 @@ <disk type='file' device='disk'> <driver name='qemu' type='qcow2'/> <source file='/storage/guest_disks/encryptdisk5'> - <encryption format='luks'> + <encryption format='luks' engine='qemu'> <secret type='passphrase' uuid='0a81f5b2-8403-7b23-c8d6-21ccc2f80d6f'/> </encryption> </source> <backingStore type='file'> <format type='qcow2'/> <source file='/storage/guest_disks/base.qcow2'> - <encryption format='luks'> + <encryption format='luks' engine='qemu'> <secret type='passphrase' uuid='0a81f5b2-8403-7b23-c8d6-21ccc2f80d6f'/> </encryption> </source> diff --git a/tests/qemuxml2xmloutdata/luks-disks-source.xml b/tests/qemuxml2xmloutdata/luks-disks-source.xml index 5333d4ac6e..891b5d9d17 100644 --- a/tests/qemuxml2xmloutdata/luks-disks-source.xml +++ b/tests/qemuxml2xmloutdata/luks-disks-source.xml @@ -17,7 +17,7 @@ <disk type='file' device='disk'> <driver name='qemu' type='raw'/> <source file='/storage/guest_disks/encryptdisk'> - <encryption format='luks'> + <encryption format='luks' engine='qemu'> <secret type='passphrase' uuid='0a81f5b2-8403-7b23-c8d6-21ccc2f80d6f'/> </encryption> </source> @@ -27,7 +27,7 @@ <disk type='file' device='disk'> <driver name='qemu' type='raw'/> <source file='/storage/guest_disks/encryptdisk2'> - <encryption format='luks'> + <encryption format='luks' engine='qemu'> <secret type='passphrase' usage='/storage/guest_disks/encryptdisk2'/> </encryption> </source> @@ -41,7 +41,7 @@ <auth username='myname'> <secret type='iscsi' uuid='0a81f5b2-8403-7b23-c8d6-21ccc2f80e80'/> </auth> - <encryption format='luks'> + <encryption format='luks' engine='qemu'> <secret type='passphrase' uuid='0a81f5b2-8403-7b23-c8d6-21ccc2f80f77'/> </encryption> </source> @@ -51,7 +51,7 @@ <disk type='volume' device='disk'> <driver name='qemu' type='raw'/> <source pool='pool-iscsi' volume='unit:0:0:3' mode='direct'> - <encryption format='luks'> + <encryption format='luks' engine='qemu'> <secret type='passphrase' uuid='0a81f5b2-8403-7b23-c8d6-21ccc2f80f80'/> </encryption> </source> @@ -64,7 +64,7 @@ <host name='mon1.example.org' port='6321'/> <host name='mon2.example.org' port='6322'/> <host name='mon3.example.org' port='6322'/> - <encryption format='luks'> + <encryption format='luks' engine='qemu'> <secret type='passphrase' uuid='0a81f5b2-8403-7b23-c8d6-21ccc2f80fb0'/> </encryption> </source> -- 2.25.1

On Thu, Oct 07, 2021 at 14:21:19 -0500, Or Ozeri wrote:
This commit extends libvirt XML configuration to support a custom encryption engine. This means that <encryption format="luks" engine="qemu"> becomes valid. The only engine for now is qemu. However, a new engine (librbd) will be added in an upcoming commit. If no engine is specified, qemu will be used (assuming qemu driver is used).
Signed-off-by: Or Ozeri <oro@il.ibm.com> --- docs/formatstorageencryption.html.in | 6 +++++ docs/schemas/domainbackup.rng | 7 +++++ docs/schemas/storagecommon.rng | 7 +++++ src/conf/storage_encryption_conf.c | 27 ++++++++++++++++++- src/conf/storage_encryption_conf.h | 9 +++++++ src/qemu/qemu_block.c | 2 ++ src/qemu/qemu_domain.c | 20 ++++++++++++++ tests/qemustatusxml2xmldata/upgrade-out.xml | 6 ++--- tests/qemuxml2argvdata/disk-nvme.xml | 2 +- .../qemuxml2argvdata/encrypted-disk-usage.xml | 2 +- tests/qemuxml2argvdata/luks-disks.xml | 4 +-- tests/qemuxml2argvdata/user-aliases.xml | 2 +- .../disk-slices.x86_64-latest.xml | 4 +-- tests/qemuxml2xmloutdata/encrypted-disk.xml | 2 +- .../luks-disks-source-qcow2.x86_64-latest.xml | 14 +++++----- .../qemuxml2xmloutdata/luks-disks-source.xml | 10 +++---- 16 files changed, 100 insertions(+), 24 deletions(-)
diff --git a/docs/formatstorageencryption.html.in b/docs/formatstorageencryption.html.in index 7215c307d7..178fcd0d7c 100644 --- a/docs/formatstorageencryption.html.in +++ b/docs/formatstorageencryption.html.in @@ -23,6 +23,12 @@ content of the <code>encryption</code> tag. Other format values may be defined in the future. </p> + <p> + The <code>encryption</code> tag supports an optional <code>engine</code> + tag, which allows selecting which component actually handles + the encryption. Currently defined values of <code>engine</code> are + <code>qemu</code>. + </p>
I'll add a note and possibly also a check that this works only in the qemu VM driver, and not in the storage driver as this part of the docs is shared between those two.
<p> The <code>encryption</code> tag can currently contain a sequence of <code>secret</code> tags, each with mandatory attributes <code>type</code>
@@ -217,6 +223,7 @@ virStorageEncryptionParseNode(xmlNodePtr node, xmlNodePtr *nodes = NULL; virStorageEncryption *encdef = NULL; virStorageEncryption *ret = NULL; + g_autofree char *engine_str = NULL;
This is unused. I'll remove it before pushing.
g_autofree char *format_str = NULL; int n; size_t i;
Reviewed-by: Peter Krempa <pkrempa@redhat.com>

rbd encryption is new in qemu 6.1.0. This commit adds a new encryption engine property which allows the user to use this new encryption engine. Signed-off-by: Or Ozeri <oro@il.ibm.com> --- docs/formatstorageencryption.html.in | 7 +- docs/schemas/storagecommon.rng | 1 + src/conf/storage_encryption_conf.c | 2 +- src/conf/storage_encryption_conf.h | 1 + src/qemu/qemu_block.c | 26 +++++++ src/qemu/qemu_domain.c | 34 +++++++++ ...sk-network-rbd-encryption.x86_64-6.0.0.err | 1 + ...-network-rbd-encryption.x86_64-latest.args | 45 ++++++++++++ .../disk-network-rbd-encryption.xml | 63 +++++++++++++++++ tests/qemuxml2argvtest.c | 2 + ...k-network-rbd-encryption.x86_64-latest.xml | 70 +++++++++++++++++++ tests/qemuxml2xmltest.c | 1 + 12 files changed, 251 insertions(+), 2 deletions(-) create mode 100644 tests/qemuxml2argvdata/disk-network-rbd-encryption.x86_64-6.0.0.err create mode 100644 tests/qemuxml2argvdata/disk-network-rbd-encryption.x86_64-latest.args create mode 100644 tests/qemuxml2argvdata/disk-network-rbd-encryption.xml create mode 100644 tests/qemuxml2xmloutdata/disk-network-rbd-encryption.x86_64-latest.xml diff --git a/docs/formatstorageencryption.html.in b/docs/formatstorageencryption.html.in index 178fcd0d7c..02ee8f8ca3 100644 --- a/docs/formatstorageencryption.html.in +++ b/docs/formatstorageencryption.html.in @@ -27,7 +27,12 @@ The <code>encryption</code> tag supports an optional <code>engine</code> tag, which allows selecting which component actually handles the encryption. Currently defined values of <code>engine</code> are - <code>qemu</code>. + <code>qemu</code> and <code>librbd</code>. + Both <code>qemu</code> and <code>librbd</code> require using the qemu driver. + The <code>librbd</code> engine requires qemu version >= 6.1.0, + and is only applicable for RBD network disks. + If the engine tag is not specified, the <code>qemu</code> engine will be + used by default (assuming the qemu driver is used). </p> <p> The <code>encryption</code> tag can currently contain a sequence of diff --git a/docs/schemas/storagecommon.rng b/docs/schemas/storagecommon.rng index 60dcfac06c..3ddff02e43 100644 --- a/docs/schemas/storagecommon.rng +++ b/docs/schemas/storagecommon.rng @@ -19,6 +19,7 @@ <attribute name="engine"> <choice> <value>qemu</value> + <value>librbd</value> </choice> </attribute> </optional> diff --git a/src/conf/storage_encryption_conf.c b/src/conf/storage_encryption_conf.c index 59178b41ef..3c1267ed40 100644 --- a/src/conf/storage_encryption_conf.c +++ b/src/conf/storage_encryption_conf.c @@ -49,7 +49,7 @@ VIR_ENUM_IMPL(virStorageEncryptionFormat, VIR_ENUM_IMPL(virStorageEncryptionEngine, VIR_STORAGE_ENCRYPTION_ENGINE_LAST, - "default", "qemu", + "default", "qemu", "librbd", ); static void diff --git a/src/conf/storage_encryption_conf.h b/src/conf/storage_encryption_conf.h index e0ac0fe4bf..0931618608 100644 --- a/src/conf/storage_encryption_conf.h +++ b/src/conf/storage_encryption_conf.h @@ -54,6 +54,7 @@ struct _virStorageEncryptionInfoDef { typedef enum { VIR_STORAGE_ENCRYPTION_ENGINE_DEFAULT = 0, VIR_STORAGE_ENCRYPTION_ENGINE_QEMU, + VIR_STORAGE_ENCRYPTION_ENGINE_LIBRBD, VIR_STORAGE_ENCRYPTION_ENGINE_LAST, } virStorageEncryptionEngine; diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index 18c5852d2e..5b1b5bea2e 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -875,6 +875,8 @@ qemuBlockStorageSourceGetRBDProps(virStorageSource *src, qemuDomainStorageSourcePrivate *srcPriv = QEMU_DOMAIN_STORAGE_SOURCE_PRIVATE(src); g_autoptr(virJSONValue) servers = NULL; virJSONValue *ret = NULL; + g_autoptr(virJSONValue) encrypt = NULL; + const char *encformat; const char *username = NULL; g_autoptr(virJSONValue) authmodes = NULL; g_autoptr(virJSONValue) mode = NULL; @@ -899,12 +901,36 @@ qemuBlockStorageSourceGetRBDProps(virStorageSource *src, return NULL; } + if (src->encryption && + src->encryption->engine == VIR_STORAGE_ENCRYPTION_ENGINE_LIBRBD) { + switch ((virStorageEncryptionFormatType) src->encryption->format) { + case VIR_STORAGE_ENCRYPTION_FORMAT_LUKS: + encformat = "luks"; + break; + + case VIR_STORAGE_ENCRYPTION_FORMAT_DEFAULT: + case VIR_STORAGE_ENCRYPTION_FORMAT_QCOW: + case VIR_STORAGE_ENCRYPTION_FORMAT_LAST: + default: + virReportEnumRangeError(virStorageEncryptionFormatType, + src->encryption->format); + return NULL; + } + + if (virJSONValueObjectCreate(&encrypt, + "s:format", encformat, + "s:key-secret", srcPriv->encinfo->alias, + NULL) < 0) + return NULL; + } + if (virJSONValueObjectCreate(&ret, "s:pool", src->volume, "s:image", src->path, "S:snapshot", src->snapshot, "S:conf", src->configFile, "A:server", &servers, + "A:encrypt", &encrypt, "S:user", username, "A:auth-client-required", &authmodes, "S:key-secret", keysecret, diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 354f65c6d5..13869dd79b 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -4814,6 +4814,40 @@ qemuDomainValidateStorageSource(virStorageSource *src, if (src->encryption) { switch (src->encryption->engine) { case VIR_STORAGE_ENCRYPTION_ENGINE_QEMU: + switch ((virStorageEncryptionFormatType) src->encryption->format) { + case VIR_STORAGE_ENCRYPTION_FORMAT_LUKS: + case VIR_STORAGE_ENCRYPTION_FORMAT_QCOW: + break; + + case VIR_STORAGE_ENCRYPTION_FORMAT_DEFAULT: + case VIR_STORAGE_ENCRYPTION_FORMAT_LAST: + default: + virReportEnumRangeError(virStorageEncryptionFormatType, + src->encryption->format); + return -1; + } + + break; + case VIR_STORAGE_ENCRYPTION_ENGINE_LIBRBD: + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_RBD_ENCRYPTION)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("librbd encryption is not supported by this QEMU binary")); + return -1; + } + + switch ((virStorageEncryptionFormatType) src->encryption->format) { + case VIR_STORAGE_ENCRYPTION_FORMAT_LUKS: + break; + + case VIR_STORAGE_ENCRYPTION_FORMAT_DEFAULT: + case VIR_STORAGE_ENCRYPTION_FORMAT_QCOW: + case VIR_STORAGE_ENCRYPTION_FORMAT_LAST: + default: + virReportEnumRangeError(virStorageEncryptionFormatType, + src->encryption->format); + return -1; + } + break; case VIR_STORAGE_ENCRYPTION_ENGINE_DEFAULT: case VIR_STORAGE_ENCRYPTION_ENGINE_LAST: diff --git a/tests/qemuxml2argvdata/disk-network-rbd-encryption.x86_64-6.0.0.err b/tests/qemuxml2argvdata/disk-network-rbd-encryption.x86_64-6.0.0.err new file mode 100644 index 0000000000..edd8481a20 --- /dev/null +++ b/tests/qemuxml2argvdata/disk-network-rbd-encryption.x86_64-6.0.0.err @@ -0,0 +1 @@ +unsupported configuration: librbd encryption is not supported by this QEMU binary diff --git a/tests/qemuxml2argvdata/disk-network-rbd-encryption.x86_64-latest.args b/tests/qemuxml2argvdata/disk-network-rbd-encryption.x86_64-latest.args new file mode 100644 index 0000000000..69837a8003 --- /dev/null +++ b/tests/qemuxml2argvdata/disk-network-rbd-encryption.x86_64-latest.args @@ -0,0 +1,45 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/tmp/lib/domain--1-encryptdisk \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/tmp/lib/domain--1-encryptdisk/.local/share \ +XDG_CACHE_HOME=/tmp/lib/domain--1-encryptdisk/.cache \ +XDG_CONFIG_HOME=/tmp/lib/domain--1-encryptdisk/.config \ +/usr/bin/qemu-system-x86_64 \ +-name guest=encryptdisk,debug-threads=on \ +-S \ +-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/tmp/lib/domain--1-encryptdisk/master-key.aes"}' \ +-machine pc-i440fx-2.1,accel=tcg,usb=off,dump-guest-core=off,memory-backend=pc.ram \ +-cpu qemu64 \ +-m 1024 \ +-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":1073741824}' \ +-overcommit mem-lock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid 496898a6-e6ff-f7c8-5dc2-3cf410945ee9 \ +-display none \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-no-acpi \ +-boot strict=on \ +-device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 \ +-object '{"qom-type":"secret","id":"libvirt-3-format-encryption-secret0","data":"9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1","keyid":"masterKey0","iv":"AAECAwQFBgcICQoLDA0ODw==","format":"base64"}' \ +-blockdev '{"driver":"rbd","pool":"pool","image":"image","server":[{"host":"mon1.example.org","port":"6321"},{"host":"mon2.example.org","port":"6322"},{"host":"mon3.example.org","port":"6322"}],"node-name":"libvirt-3-storage","auto-read-only":true,"discard":"unmap"}' \ +-blockdev '{"node-name":"libvirt-3-format","read-only":false,"driver":"luks","key-secret":"libvirt-3-format-encryption-secret0","file":"libvirt-3-storage"}' \ +-device virtio-blk-pci,bus=pci.0,addr=0x2,drive=libvirt-3-format,id=virtio-disk0,bootindex=1 \ +-object '{"qom-type":"secret","id":"libvirt-2-format-encryption-secret0","data":"9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1","keyid":"masterKey0","iv":"AAECAwQFBgcICQoLDA0ODw==","format":"base64"}' \ +-blockdev '{"driver":"rbd","pool":"pool","image":"image","server":[{"host":"mon1.example.org","port":"6321"},{"host":"mon2.example.org","port":"6322"},{"host":"mon3.example.org","port":"6322"}],"node-name":"libvirt-2-storage","auto-read-only":true,"discard":"unmap"}' \ +-blockdev '{"node-name":"libvirt-2-format","read-only":false,"driver":"luks","key-secret":"libvirt-2-format-encryption-secret0","file":"libvirt-2-storage"}' \ +-device virtio-blk-pci,bus=pci.0,addr=0x4,drive=libvirt-2-format,id=virtio-disk1 \ +-object '{"qom-type":"secret","id":"libvirt-1-format-encryption-secret0","data":"9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1","keyid":"masterKey0","iv":"AAECAwQFBgcICQoLDA0ODw==","format":"base64"}' \ +-blockdev '{"driver":"rbd","pool":"pool","image":"image","server":[{"host":"mon1.example.org","port":"6321"},{"host":"mon2.example.org","port":"6322"},{"host":"mon3.example.org","port":"6322"}],"encrypt":{"format":"luks","key-secret":"libvirt-1-format-encryption-secret0"},"node-name":"libvirt-1-storage","auto-read-only":true,"discard":"unmap"}' \ +-blockdev '{"node-name":"libvirt-1-format","read-only":false,"driver":"raw","file":"libvirt-1-storage"}' \ +-device virtio-blk-pci,bus=pci.0,addr=0x5,drive=libvirt-1-format,id=virtio-disk2 \ +-audiodev id=audio1,driver=none \ +-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 \ +-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ +-msg timestamp=on diff --git a/tests/qemuxml2argvdata/disk-network-rbd-encryption.xml b/tests/qemuxml2argvdata/disk-network-rbd-encryption.xml new file mode 100644 index 0000000000..d8c2d3dbe2 --- /dev/null +++ b/tests/qemuxml2argvdata/disk-network-rbd-encryption.xml @@ -0,0 +1,63 @@ +<domain type='qemu'> + <name>encryptdisk</name> + <uuid>496898a6-e6ff-f7c8-5dc2-3cf410945ee9</uuid> + <memory unit='KiB'>1048576</memory> + <currentMemory unit='KiB'>524288</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='pc-i440fx-2.1'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <disk type='network' device='disk'> + <driver name='qemu' type='raw'/> + <source protocol='rbd' name='pool/image'> + <host name='mon1.example.org' port='6321'/> + <host name='mon2.example.org' port='6322'/> + <host name='mon3.example.org' port='6322'/> + <encryption format='luks'> + <secret type='passphrase' uuid='0a81f5b2-8403-7b23-c8d6-21ccc2f80fb0'/> + </encryption> + </source> + <target dev='vda' bus='virtio'/> + </disk> + <disk type='network' device='disk'> + <driver name='qemu' type='raw'/> + <source protocol='rbd' name='pool/image'> + <host name='mon1.example.org' port='6321'/> + <host name='mon2.example.org' port='6322'/> + <host name='mon3.example.org' port='6322'/> + <encryption format='luks' engine='qemu'> + <secret type='passphrase' uuid='0a81f5b2-8403-7b23-c8d6-21ccc2f80fb0'/> + </encryption> + </source> + <target dev='vdb' bus='virtio'/> + </disk> + <disk type='network' device='disk'> + <driver name='qemu' type='raw'/> + <source protocol='rbd' name='pool/image'> + <host name='mon1.example.org' port='6321'/> + <host name='mon2.example.org' port='6322'/> + <host name='mon3.example.org' port='6322'/> + <encryption format='luks' engine='librbd'> + <secret type='passphrase' uuid='0a81f5b2-8403-7b23-c8d6-21ccc2f80fb0'/> + </encryption> + </source> + <target dev='vdc' bus='virtio'/> + </disk> + <controller type='usb' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> + </controller> + <controller type='pci' index='0' model='pci-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + </memballoon> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 94aaa2f53e..b14154fd0c 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -1349,6 +1349,8 @@ mymain(void) DO_TEST_CAPS_LATEST("disk-network-gluster"); DO_TEST_CAPS_VER("disk-network-rbd", "2.12.0"); DO_TEST_CAPS_LATEST("disk-network-rbd"); + DO_TEST_CAPS_VER_PARSE_ERROR("disk-network-rbd-encryption", "6.0.0"); + DO_TEST_CAPS_LATEST("disk-network-rbd-encryption"); DO_TEST_CAPS_VER_FAILURE("disk-network-rbd-no-colon", "4.1.0"); DO_TEST_CAPS_LATEST("disk-network-rbd-no-colon"); DO_TEST_CAPS_VER("disk-network-sheepdog", "2.12.0"); diff --git a/tests/qemuxml2xmloutdata/disk-network-rbd-encryption.x86_64-latest.xml b/tests/qemuxml2xmloutdata/disk-network-rbd-encryption.x86_64-latest.xml new file mode 100644 index 0000000000..d4942718bb --- /dev/null +++ b/tests/qemuxml2xmloutdata/disk-network-rbd-encryption.x86_64-latest.xml @@ -0,0 +1,70 @@ +<domain type='qemu'> + <name>encryptdisk</name> + <uuid>496898a6-e6ff-f7c8-5dc2-3cf410945ee9</uuid> + <memory unit='KiB'>1048576</memory> + <currentMemory unit='KiB'>524288</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='pc-i440fx-2.1'>hvm</type> + <boot dev='hd'/> + </os> + <cpu mode='custom' match='exact' check='none'> + <model fallback='forbid'>qemu64</model> + </cpu> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <disk type='network' device='disk'> + <driver name='qemu' type='raw'/> + <source protocol='rbd' name='pool/image'> + <host name='mon1.example.org' port='6321'/> + <host name='mon2.example.org' port='6322'/> + <host name='mon3.example.org' port='6322'/> + <encryption format='luks' engine='qemu'> + <secret type='passphrase' uuid='0a81f5b2-8403-7b23-c8d6-21ccc2f80fb0'/> + </encryption> + </source> + <target dev='vda' bus='virtio'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> + </disk> + <disk type='network' device='disk'> + <driver name='qemu' type='raw'/> + <source protocol='rbd' name='pool/image'> + <host name='mon1.example.org' port='6321'/> + <host name='mon2.example.org' port='6322'/> + <host name='mon3.example.org' port='6322'/> + <encryption format='luks' engine='qemu'> + <secret type='passphrase' uuid='0a81f5b2-8403-7b23-c8d6-21ccc2f80fb0'/> + </encryption> + </source> + <target dev='vdb' bus='virtio'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> + </disk> + <disk type='network' device='disk'> + <driver name='qemu' type='raw'/> + <source protocol='rbd' name='pool/image'> + <host name='mon1.example.org' port='6321'/> + <host name='mon2.example.org' port='6322'/> + <host name='mon3.example.org' port='6322'/> + <encryption format='luks' engine='librbd'> + <secret type='passphrase' uuid='0a81f5b2-8403-7b23-c8d6-21ccc2f80fb0'/> + </encryption> + </source> + <target dev='vdc' bus='virtio'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> + </disk> + <controller type='usb' index='0' model='piix3-uhci'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> + </controller> + <controller type='pci' index='0' model='pci-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <audio id='1' type='none'/> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + </memballoon> + </devices> +</domain> diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 69363ef85c..290ab1bed1 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -315,6 +315,7 @@ mymain(void) QEMU_CAPS_SCSI_BLOCK); DO_TEST_NOCAPS("disk-network-gluster"); DO_TEST_NOCAPS("disk-network-rbd"); + DO_TEST_CAPS_LATEST("disk-network-rbd-encryption"); DO_TEST_NOCAPS("disk-network-source-auth"); DO_TEST_NOCAPS("disk-network-sheepdog"); DO_TEST_NOCAPS("disk-network-vxhs"); -- 2.25.1

On Thu, Oct 07, 2021 at 14:21:20 -0500, Or Ozeri wrote:
rbd encryption is new in qemu 6.1.0. This commit adds a new encryption engine property which allows the user to use this new encryption engine.
Signed-off-by: Or Ozeri <oro@il.ibm.com> --- docs/formatstorageencryption.html.in | 7 +- docs/schemas/storagecommon.rng | 1 + src/conf/storage_encryption_conf.c | 2 +- src/conf/storage_encryption_conf.h | 1 + src/qemu/qemu_block.c | 26 +++++++ src/qemu/qemu_domain.c | 34 +++++++++ ...sk-network-rbd-encryption.x86_64-6.0.0.err | 1 + ...-network-rbd-encryption.x86_64-latest.args | 45 ++++++++++++ .../disk-network-rbd-encryption.xml | 63 +++++++++++++++++ tests/qemuxml2argvtest.c | 2 + ...k-network-rbd-encryption.x86_64-latest.xml | 70 +++++++++++++++++++ tests/qemuxml2xmltest.c | 1 + 12 files changed, 251 insertions(+), 2 deletions(-) create mode 100644 tests/qemuxml2argvdata/disk-network-rbd-encryption.x86_64-6.0.0.err create mode 100644 tests/qemuxml2argvdata/disk-network-rbd-encryption.x86_64-latest.args create mode 100644 tests/qemuxml2argvdata/disk-network-rbd-encryption.xml create mode 100644 tests/qemuxml2xmloutdata/disk-network-rbd-encryption.x86_64-latest.xml
diff --git a/docs/formatstorageencryption.html.in b/docs/formatstorageencryption.html.in index 178fcd0d7c..02ee8f8ca3 100644 --- a/docs/formatstorageencryption.html.in +++ b/docs/formatstorageencryption.html.in @@ -27,7 +27,12 @@ The <code>encryption</code> tag supports an optional <code>engine</code> tag, which allows selecting which component actually handles the encryption. Currently defined values of <code>engine</code> are - <code>qemu</code>. + <code>qemu</code> and <code>librbd</code>. + Both <code>qemu</code> and <code>librbd</code> require using the qemu driver. + The <code>librbd</code> engine requires qemu version >= 6.1.0, + and is only applicable for RBD network disks. + If the engine tag is not specified, the <code>qemu</code> engine will be + used by default (assuming the qemu driver is used).
Okay, this is slightly better but it doesn't specify what's happening in the storage driver.
</p> <p> The <code>encryption</code> tag can currently contain a sequence of
[...]
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 354f65c6d5..13869dd79b 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -4814,6 +4814,40 @@ qemuDomainValidateStorageSource(virStorageSource *src, if (src->encryption) { switch (src->encryption->engine) { case VIR_STORAGE_ENCRYPTION_ENGINE_QEMU: + switch ((virStorageEncryptionFormatType) src->encryption->format) { + case VIR_STORAGE_ENCRYPTION_FORMAT_LUKS: + case VIR_STORAGE_ENCRYPTION_FORMAT_QCOW: + break; + + case VIR_STORAGE_ENCRYPTION_FORMAT_DEFAULT: + case VIR_STORAGE_ENCRYPTION_FORMAT_LAST: + default: + virReportEnumRangeError(virStorageEncryptionFormatType, + src->encryption->format); + return -1;
This here is okay, because both are basically impossible.
+ } + + break; + case VIR_STORAGE_ENCRYPTION_ENGINE_LIBRBD: + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_RBD_ENCRYPTION)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("librbd encryption is not supported by this QEMU binary")); + return -1; + } + + switch ((virStorageEncryptionFormatType) src->encryption->format) { + case VIR_STORAGE_ENCRYPTION_FORMAT_LUKS: + break; + + case VIR_STORAGE_ENCRYPTION_FORMAT_DEFAULT: + case VIR_STORAGE_ENCRYPTION_FORMAT_QCOW: + case VIR_STORAGE_ENCRYPTION_FORMAT_LAST: + default: + virReportEnumRangeError(virStorageEncryptionFormatType, + src->encryption->format);
This creates an error message which is not very informative. Specifically for VIR_STORAGE_ENCRYPTION_FORMAT_QCOW which is a legitimate configuration we need a proper error message.
+ return -1; + } + break; case VIR_STORAGE_ENCRYPTION_ENGINE_DEFAULT: case VIR_STORAGE_ENCRYPTION_ENGINE_LAST:
[...] The test input files are okay. The output files will need some tweaking after recent changes. I think adding the error message is trivial enough so that I'll do it before pushing if you are okay with it. Reviewed-by: Peter Krempa <pkrempa@redhat.com>

On Thu, Oct 21, 2021 at 11:40:20 +0000, Or Ozeri wrote:
Thanks for reviewing all of my patches! I'm fine with you making any of the changes you suggested. So the only change I need to make is "specify what's happening in the storage driver"? Can you elaborate what do you mean by that? I can add something like: For librbd engine, the encryption happens inside the librbd storage driver, so block read/write requests coming in from the hypervisor (qemu) are plaintext, but encrypted by the storage driver before being persisted. Is this the kind of thing you were thinking about?
I meant the libvirt storage driver, which provides the storage pool/volume functionality. The code in the storage driver can create encrypted qcow2 images. (not on RBD IIRC), but is using qemu-img to do that, which doesn't use the same code we use in the qemu driver to instantiate VMs. So while qemu-img could use the librbd encryption engine, the storage driver code can't control it in such way. Similarly the code doesn't share the 'qemu' validation/post-parse checks so the librbd and luks2 combinations are not rejected.

This commit extends libvirt XML configuration to support luks2 encryption format. This means that <encryption format="luks2" engine="librbd"> becomes valid. Currently librbd is the only engine that supports this new format. Signed-off-by: Or Ozeri <oro@il.ibm.com> --- docs/formatstorageencryption.html.in | 12 +++++++++++- docs/schemas/storagecommon.rng | 1 + src/conf/storage_encryption_conf.c | 2 +- src/conf/storage_encryption_conf.h | 1 + src/qemu/qemu_block.c | 5 +++++ src/qemu/qemu_domain.c | 5 ++++- ...isk-network-rbd-encryption.x86_64-latest.args | 16 ++++++++++------ .../disk-network-rbd-encryption.xml | 12 ++++++++++++ ...disk-network-rbd-encryption.x86_64-latest.xml | 13 +++++++++++++ 9 files changed, 58 insertions(+), 9 deletions(-) diff --git a/docs/formatstorageencryption.html.in b/docs/formatstorageencryption.html.in index 02ee8f8ca3..6cf1f94a9f 100644 --- a/docs/formatstorageencryption.html.in +++ b/docs/formatstorageencryption.html.in @@ -18,7 +18,7 @@ is <code>encryption</code>, with a mandatory attribute <code>format</code>. Currently defined values of <code>format</code> are <code>default</code>, <code>qcow</code>, - and <code>luks</code>. + <code>luks</code>, and <code>luks2</code>. Each value of <code>format</code> implies some expectations about the content of the <code>encryption</code> tag. Other format values may be defined in the future. @@ -121,6 +121,16 @@ </dd> </dl> + <h3><a id="StorageEncryptionLuks2">"luks2" format</a></h3> + <p> + The <code>luks2</code> format is currently supported only by the + <code>librbd</code> engine, and can only be applied to RBD network disks. + <code>luks2</code> encrypted RBD disks can be decrypted by the domain, + but creation of such disks is currently not supported through libvirt. + A single + <code><secret type='passphrase'...></code> element is expected. + </p> + <h2><a id="example">Examples</a></h2> diff --git a/docs/schemas/storagecommon.rng b/docs/schemas/storagecommon.rng index 3ddff02e43..591a158209 100644 --- a/docs/schemas/storagecommon.rng +++ b/docs/schemas/storagecommon.rng @@ -13,6 +13,7 @@ <value>default</value> <value>qcow</value> <value>luks</value> + <value>luks2</value> </choice> </attribute> <optional> diff --git a/src/conf/storage_encryption_conf.c b/src/conf/storage_encryption_conf.c index 3c1267ed40..c312236d4c 100644 --- a/src/conf/storage_encryption_conf.c +++ b/src/conf/storage_encryption_conf.c @@ -44,7 +44,7 @@ VIR_ENUM_IMPL(virStorageEncryptionSecret, VIR_ENUM_IMPL(virStorageEncryptionFormat, VIR_STORAGE_ENCRYPTION_FORMAT_LAST, - "default", "qcow", "luks", + "default", "qcow", "luks", "luks2", ); VIR_ENUM_IMPL(virStorageEncryptionEngine, diff --git a/src/conf/storage_encryption_conf.h b/src/conf/storage_encryption_conf.h index 0931618608..312599ad44 100644 --- a/src/conf/storage_encryption_conf.h +++ b/src/conf/storage_encryption_conf.h @@ -65,6 +65,7 @@ typedef enum { VIR_STORAGE_ENCRYPTION_FORMAT_DEFAULT = 0, VIR_STORAGE_ENCRYPTION_FORMAT_QCOW, /* Both qcow and qcow2 */ VIR_STORAGE_ENCRYPTION_FORMAT_LUKS, + VIR_STORAGE_ENCRYPTION_FORMAT_LUKS2, VIR_STORAGE_ENCRYPTION_FORMAT_LAST, } virStorageEncryptionFormatType; diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index 5b1b5bea2e..62c40d39d1 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -908,6 +908,10 @@ qemuBlockStorageSourceGetRBDProps(virStorageSource *src, encformat = "luks"; break; + case VIR_STORAGE_ENCRYPTION_FORMAT_LUKS2: + encformat = "luks2"; + break; + case VIR_STORAGE_ENCRYPTION_FORMAT_DEFAULT: case VIR_STORAGE_ENCRYPTION_FORMAT_QCOW: case VIR_STORAGE_ENCRYPTION_FORMAT_LAST: @@ -1355,6 +1359,7 @@ qemuBlockStorageSourceGetCryptoProps(virStorageSource *src, break; case VIR_STORAGE_ENCRYPTION_FORMAT_DEFAULT: + case VIR_STORAGE_ENCRYPTION_FORMAT_LUKS2: case VIR_STORAGE_ENCRYPTION_FORMAT_LAST: default: virReportEnumRangeError(virStorageEncryptionFormatType, diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 13869dd79b..8c2a5408da 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -1228,7 +1228,8 @@ static bool qemuDomainDiskHasEncryptionSecret(virStorageSource *src) { if (!virStorageSourceIsEmpty(src) && src->encryption && - src->encryption->format == VIR_STORAGE_ENCRYPTION_FORMAT_LUKS && + (src->encryption->format == VIR_STORAGE_ENCRYPTION_FORMAT_LUKS || + src->encryption->format == VIR_STORAGE_ENCRYPTION_FORMAT_LUKS2) && src->encryption->nsecrets > 0) return true; @@ -4820,6 +4821,7 @@ qemuDomainValidateStorageSource(virStorageSource *src, break; case VIR_STORAGE_ENCRYPTION_FORMAT_DEFAULT: + case VIR_STORAGE_ENCRYPTION_FORMAT_LUKS2: case VIR_STORAGE_ENCRYPTION_FORMAT_LAST: default: virReportEnumRangeError(virStorageEncryptionFormatType, @@ -4837,6 +4839,7 @@ qemuDomainValidateStorageSource(virStorageSource *src, switch ((virStorageEncryptionFormatType) src->encryption->format) { case VIR_STORAGE_ENCRYPTION_FORMAT_LUKS: + case VIR_STORAGE_ENCRYPTION_FORMAT_LUKS2: break; case VIR_STORAGE_ENCRYPTION_FORMAT_DEFAULT: diff --git a/tests/qemuxml2argvdata/disk-network-rbd-encryption.x86_64-latest.args b/tests/qemuxml2argvdata/disk-network-rbd-encryption.x86_64-latest.args index 69837a8003..9b3e8d31b8 100644 --- a/tests/qemuxml2argvdata/disk-network-rbd-encryption.x86_64-latest.args +++ b/tests/qemuxml2argvdata/disk-network-rbd-encryption.x86_64-latest.args @@ -27,18 +27,22 @@ XDG_CONFIG_HOME=/tmp/lib/domain--1-encryptdisk/.config \ -no-acpi \ -boot strict=on \ -device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 \ +-object '{"qom-type":"secret","id":"libvirt-4-format-encryption-secret0","data":"9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1","keyid":"masterKey0","iv":"AAECAwQFBgcICQoLDA0ODw==","format":"base64"}' \ +-blockdev '{"driver":"rbd","pool":"pool","image":"image","server":[{"host":"mon1.example.org","port":"6321"},{"host":"mon2.example.org","port":"6322"},{"host":"mon3.example.org","port":"6322"}],"node-name":"libvirt-4-storage","auto-read-only":true,"discard":"unmap"}' \ +-blockdev '{"node-name":"libvirt-4-format","read-only":false,"driver":"luks","key-secret":"libvirt-4-format-encryption-secret0","file":"libvirt-4-storage"}' \ +-device virtio-blk-pci,bus=pci.0,addr=0x2,drive=libvirt-4-format,id=virtio-disk0,bootindex=1 \ -object '{"qom-type":"secret","id":"libvirt-3-format-encryption-secret0","data":"9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1","keyid":"masterKey0","iv":"AAECAwQFBgcICQoLDA0ODw==","format":"base64"}' \ -blockdev '{"driver":"rbd","pool":"pool","image":"image","server":[{"host":"mon1.example.org","port":"6321"},{"host":"mon2.example.org","port":"6322"},{"host":"mon3.example.org","port":"6322"}],"node-name":"libvirt-3-storage","auto-read-only":true,"discard":"unmap"}' \ -blockdev '{"node-name":"libvirt-3-format","read-only":false,"driver":"luks","key-secret":"libvirt-3-format-encryption-secret0","file":"libvirt-3-storage"}' \ --device virtio-blk-pci,bus=pci.0,addr=0x2,drive=libvirt-3-format,id=virtio-disk0,bootindex=1 \ +-device virtio-blk-pci,bus=pci.0,addr=0x4,drive=libvirt-3-format,id=virtio-disk1 \ -object '{"qom-type":"secret","id":"libvirt-2-format-encryption-secret0","data":"9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1","keyid":"masterKey0","iv":"AAECAwQFBgcICQoLDA0ODw==","format":"base64"}' \ --blockdev '{"driver":"rbd","pool":"pool","image":"image","server":[{"host":"mon1.example.org","port":"6321"},{"host":"mon2.example.org","port":"6322"},{"host":"mon3.example.org","port":"6322"}],"node-name":"libvirt-2-storage","auto-read-only":true,"discard":"unmap"}' \ --blockdev '{"node-name":"libvirt-2-format","read-only":false,"driver":"luks","key-secret":"libvirt-2-format-encryption-secret0","file":"libvirt-2-storage"}' \ --device virtio-blk-pci,bus=pci.0,addr=0x4,drive=libvirt-2-format,id=virtio-disk1 \ +-blockdev '{"driver":"rbd","pool":"pool","image":"image","server":[{"host":"mon1.example.org","port":"6321"},{"host":"mon2.example.org","port":"6322"},{"host":"mon3.example.org","port":"6322"}],"encrypt":{"format":"luks","key-secret":"libvirt-2-format-encryption-secret0"},"node-name":"libvirt-2-storage","auto-read-only":true,"discard":"unmap"}' \ +-blockdev '{"node-name":"libvirt-2-format","read-only":false,"driver":"raw","file":"libvirt-2-storage"}' \ +-device virtio-blk-pci,bus=pci.0,addr=0x5,drive=libvirt-2-format,id=virtio-disk2 \ -object '{"qom-type":"secret","id":"libvirt-1-format-encryption-secret0","data":"9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1","keyid":"masterKey0","iv":"AAECAwQFBgcICQoLDA0ODw==","format":"base64"}' \ --blockdev '{"driver":"rbd","pool":"pool","image":"image","server":[{"host":"mon1.example.org","port":"6321"},{"host":"mon2.example.org","port":"6322"},{"host":"mon3.example.org","port":"6322"}],"encrypt":{"format":"luks","key-secret":"libvirt-1-format-encryption-secret0"},"node-name":"libvirt-1-storage","auto-read-only":true,"discard":"unmap"}' \ +-blockdev '{"driver":"rbd","pool":"pool","image":"image2","server":[{"host":"mon1.example.org","port":"6321"},{"host":"mon2.example.org","port":"6322"},{"host":"mon3.example.org","port":"6322"}],"encrypt":{"format":"luks2","key-secret":"libvirt-1-format-encryption-secret0"},"node-name":"libvirt-1-storage","auto-read-only":true,"discard":"unmap"}' \ -blockdev '{"node-name":"libvirt-1-format","read-only":false,"driver":"raw","file":"libvirt-1-storage"}' \ --device virtio-blk-pci,bus=pci.0,addr=0x5,drive=libvirt-1-format,id=virtio-disk2 \ +-device virtio-blk-pci,bus=pci.0,addr=0x6,drive=libvirt-1-format,id=virtio-disk3 \ -audiodev id=audio1,driver=none \ -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 \ -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ diff --git a/tests/qemuxml2argvdata/disk-network-rbd-encryption.xml b/tests/qemuxml2argvdata/disk-network-rbd-encryption.xml index d8c2d3dbe2..eeadbfeeba 100644 --- a/tests/qemuxml2argvdata/disk-network-rbd-encryption.xml +++ b/tests/qemuxml2argvdata/disk-network-rbd-encryption.xml @@ -50,6 +50,18 @@ </source> <target dev='vdc' bus='virtio'/> </disk> + <disk type='network' device='disk'> + <driver name='qemu' type='raw'/> + <source protocol='rbd' name='pool/image2'> + <host name='mon1.example.org' port='6321'/> + <host name='mon2.example.org' port='6322'/> + <host name='mon3.example.org' port='6322'/> + <encryption format='luks2' engine='librbd'> + <secret type='passphrase' uuid='0a81f5b2-8403-7b23-c8d6-21ccc2f80fb0'/> + </encryption> + </source> + <target dev='vdd' bus='virtio'/> + </disk> <controller type='usb' index='0'> <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> </controller> diff --git a/tests/qemuxml2xmloutdata/disk-network-rbd-encryption.x86_64-latest.xml b/tests/qemuxml2xmloutdata/disk-network-rbd-encryption.x86_64-latest.xml index d4942718bb..a91504202a 100644 --- a/tests/qemuxml2xmloutdata/disk-network-rbd-encryption.x86_64-latest.xml +++ b/tests/qemuxml2xmloutdata/disk-network-rbd-encryption.x86_64-latest.xml @@ -56,6 +56,19 @@ <target dev='vdc' bus='virtio'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> </disk> + <disk type='network' device='disk'> + <driver name='qemu' type='raw'/> + <source protocol='rbd' name='pool/image2'> + <host name='mon1.example.org' port='6321'/> + <host name='mon2.example.org' port='6322'/> + <host name='mon3.example.org' port='6322'/> + <encryption format='luks2' engine='librbd'> + <secret type='passphrase' uuid='0a81f5b2-8403-7b23-c8d6-21ccc2f80fb0'/> + </encryption> + </source> + <target dev='vdd' bus='virtio'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/> + </disk> <controller type='usb' index='0' model='piix3-uhci'> <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> </controller> -- 2.25.1

On Thu, Oct 07, 2021 at 14:21:21 -0500, Or Ozeri wrote:
This commit extends libvirt XML configuration to support luks2 encryption format. This means that <encryption format="luks2" engine="librbd"> becomes valid. Currently librbd is the only engine that supports this new format.
Signed-off-by: Or Ozeri <oro@il.ibm.com> --- docs/formatstorageencryption.html.in | 12 +++++++++++- docs/schemas/storagecommon.rng | 1 + src/conf/storage_encryption_conf.c | 2 +- src/conf/storage_encryption_conf.h | 1 + src/qemu/qemu_block.c | 5 +++++ src/qemu/qemu_domain.c | 5 ++++- ...isk-network-rbd-encryption.x86_64-latest.args | 16 ++++++++++------ .../disk-network-rbd-encryption.xml | 12 ++++++++++++ ...disk-network-rbd-encryption.x86_64-latest.xml | 13 +++++++++++++ 9 files changed, 58 insertions(+), 9 deletions(-)
diff --git a/docs/formatstorageencryption.html.in b/docs/formatstorageencryption.html.in index 02ee8f8ca3..6cf1f94a9f 100644 --- a/docs/formatstorageencryption.html.in +++ b/docs/formatstorageencryption.html.in
[...]
@@ -121,6 +121,16 @@ </dd> </dl>
+ <h3><a id="StorageEncryptionLuks2">"luks2" format</a></h3> + <p> + The <code>luks2</code> format is currently supported only by the + <code>librbd</code> engine, and can only be applied to RBD network disks. + <code>luks2</code> encrypted RBD disks can be decrypted by the domain, + but creation of such disks is currently not supported through libvirt. + A single + <code><secret type='passphrase'...></code> element is expected. + </p>
As noted before this doesn't really tell what's happening in the storage driver, so it will need some tweaking.
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 13869dd79b..8c2a5408da 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -1228,7 +1228,8 @@ static bool qemuDomainDiskHasEncryptionSecret(virStorageSource *src) { if (!virStorageSourceIsEmpty(src) && src->encryption && - src->encryption->format == VIR_STORAGE_ENCRYPTION_FORMAT_LUKS && + (src->encryption->format == VIR_STORAGE_ENCRYPTION_FORMAT_LUKS || + src->encryption->format == VIR_STORAGE_ENCRYPTION_FORMAT_LUKS2) && src->encryption->nsecrets > 0) return true;
@@ -4820,6 +4821,7 @@ qemuDomainValidateStorageSource(virStorageSource *src, break;
case VIR_STORAGE_ENCRYPTION_FORMAT_DEFAULT: + case VIR_STORAGE_ENCRYPTION_FORMAT_LUKS2: case VIR_STORAGE_ENCRYPTION_FORMAT_LAST: default: virReportEnumRangeError(virStorageEncryptionFormatType,
Same problem as in previous patch. This creates an error message which is not really descriptive. Again both seem to be easy enough for me to do before pushing if you are okay with it. Reviewed-by: Peter Krempa <pkrempa@redhat.com> (Note that I'm on PTO until Monday).
participants (3)
-
Or Ozeri
-
Or Ozeri
-
Peter Krempa