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@xxxxxxxxxx> --- docs/formatstorageencryption.html.in | 6 +++++ docs/schemas/domainbackup.rng | 7 +++++ docs/schemas/storagecommon.rng | 7 +++++ src/conf/storage_encryption_conf.c | 26 ++++++++++++++++++- 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, 99 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..7fd601e4a2 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]))) @@ -239,6 +245,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 +339,7 @@ int virStorageEncryptionFormat(virBuffer *buf, virStorageEncryption *enc) { + const char *engine; const char *format; size_t i; @@ -335,7 +348,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 b6d6d95692..0e2395278a 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 5ff602e3af..75cc656ed9 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -4770,6 +4770,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; } @@ -5222,6 +5234,8 @@ int qemuDomainDeviceDiskDefPostParse(virDomainDiskDef *disk, unsigned int parseFlags) { + virStorageSource *n; + /* set default disk types and drivers */ if (!virDomainDiskGetDriver(disk)) virDomainDiskSetDriver(disk, "qemu"); @@ -5236,6 +5250,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