diff --git a/docs/formatstorageencryption.html.in b/docs/formatstorageencryption.html.in index 178fcd0d7c..fb04a6a0ad 100644 --- a/docs/formatstorageencryption.html.in +++ b/docs/formatstorageencryption.html.in @@ -27,7 +27,16 @@ The encryption tag supports an optional engine tag, which allows selecting which component actually handles the encryption. Currently defined values of engine are - qemu. + qemu and librbd. + Both qemu and librbd require using the qemu + driver. + The librbd engine requires qemu version >= 6.1.0, + and is only applicable for RBD network disks. + If the engine tag is not specified, the qemu engine will be + used by default (assuming the qemu driver is used). + Note that librbd engine is currently only supported by the + qemu VM driver, and is not supported by the storage driver. Furthermore, + the storage driver currently ignores the engine tag.

The encryption 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 @@ qemu + librbd diff --git a/src/conf/storage_encryption_conf.c b/src/conf/storage_encryption_conf.c index 7fd601e4a2..d45ad717a0 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 0e2395278a..4af06aea1b 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,40 @@ 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_QCOW: + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("librbd encryption engine only supports luks/luks2 formats")); + return NULL; + + case VIR_STORAGE_ENCRYPTION_FORMAT_DEFAULT: + 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 5eff3eadd7..3309dd6cde 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -4773,6 +4773,44 @@ 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_QCOW: + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("librbd encryption engine only supports luks/luks2 formats")); + return -1; + + 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_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..474c245d60 --- /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 '{"driver":"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 '{"driver":"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 '{"driver":"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 '{"driver":"virtio-blk-pci","bus":"pci.0","addr":"0x5","drive":"libvirt-1-format","id":"virtio-disk2"}' \ +-audiodev id=audio1,driver=none \ +-device '{"driver":"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 @@ + + encryptdisk + 496898a6-e6ff-f7c8-5dc2-3cf410945ee9 + 1048576 + 524288 + 1 + + hvm + + + + destroy + restart + destroy + + /usr/bin/qemu-system-x86_64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ + + + + +
+ + + diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index e209b48fce..df7cfe020e 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -1344,6 +1344,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 @@ + + encryptdisk + 496898a6-e6ff-f7c8-5dc2-3cf410945ee9 + 1048576 + 524288 + 1 + + hvm + + + + qemu64 + + + destroy + restart + destroy + + /usr/bin/qemu-system-x86_64 + + + + + + + + + + + +
+ + + + + + + + + + + + +
+ + + + + + + + + + + + +
+ + +
+ + + + +