[libvirt] [PATCH v3 10/10] qemu: Add luks support for domain disk
Ján Tomko
jtomko at redhat.com
Sat Jun 25 07:07:38 UTC 2016
On Fri, Jun 24, 2016 at 04:53:39PM -0400, John Ferlan wrote:
>Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1301021
>
>Generate the luks command line using the AES secret key to encrypt the
>luks secret. A luks secret object will be in addition to a an AES secret.
>
>For hotplug, check if the encinfo exists and if so, add the AES secret
>for the passphrase for the secret object used to decrypt the device.
>
>Add tests for sample output
>
>Signed-off-by: John Ferlan <jferlan at redhat.com>
>---
> src/qemu/qemu_command.c | 9 +++
> src/qemu/qemu_domain.c | 25 ++++++-
> src/qemu/qemu_hotplug.c | 82 +++++++++++++++++++---
> .../qemuxml2argv-luks-disk-cipher.args | 36 ++++++++++
> .../qemuxml2argvdata/qemuxml2argv-luks-disks.args | 36 ++++++++++
> tests/qemuxml2argvtest.c | 11 ++-
> 6 files changed, 187 insertions(+), 12 deletions(-)
> create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-luks-disk-cipher.args
> create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-luks-disks.args
>
>diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
>index 71e9e63..038a60c 100644
>--- a/src/qemu/qemu_command.c
>+++ b/src/qemu/qemu_command.c
>@@ -1098,6 +1098,7 @@ qemuBuildDriveStr(virDomainDiskDefPtr disk,
> int actualType = virStorageSourceGetActualType(disk->src);
> qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
> qemuDomainSecretInfoPtr secinfo = diskPriv->secinfo;
>+ qemuDomainSecretInfoPtr encinfo = diskPriv->encinfo;
> bool emitDeviceSyntax = qemuDiskBusNeedsDeviceArg(disk->bus);
>
> if (idx < 0) {
>@@ -1237,6 +1238,10 @@ qemuBuildDriveStr(virDomainDiskDefPtr disk,
> secinfo->s.aes.alias);
> }
>
>+ if (encinfo)
>+ virQEMUBuildLuksOpts(&opt, &disk->src->encryption->encinfo,
>+ encinfo->s.aes.alias);
>+
> if (disk->src->format > 0 &&
> disk->src->type != VIR_STORAGE_TYPE_DIR)
> virBufferAsprintf(&opt, "format=%s,",
>@@ -1939,6 +1944,7 @@ qemuBuildDiskDriveCommandLine(virCommandPtr cmd,
> virDomainDiskDefPtr disk = def->disks[i];
> qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
> qemuDomainSecretInfoPtr secinfo = diskPriv->secinfo;
>+ qemuDomainSecretInfoPtr encinfo = diskPriv->encinfo;
>
> /* PowerPC pseries based VMs do not support floppy device */
> if (disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY &&
>@@ -1967,6 +1973,9 @@ qemuBuildDiskDriveCommandLine(virCommandPtr cmd,
> if (qemuBuildDiskSecinfoCommandLine(cmd, secinfo) < 0)
> return -1;
>
>+ if (qemuBuildDiskSecinfoCommandLine(cmd, encinfo) < 0)
>+ return -1;
>+
> virCommandAddArg(cmd, "-drive");
>
> optstr = qemuBuildDriveStr(disk,
>diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
>index d51e82b..5405365 100644
>--- a/src/qemu/qemu_domain.c
>+++ b/src/qemu/qemu_domain.c
>@@ -945,7 +945,8 @@ qemuDomainSecretSetup(virConnectPtr conn,
> {
> if (virCryptoHaveCipher(VIR_CRYPTO_CIPHER_AES256CBC) &&
> virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_OBJECT_SECRET) &&
>- secretUsageType == VIR_SECRET_USAGE_TYPE_CEPH) {
>+ (secretUsageType == VIR_SECRET_USAGE_TYPE_CEPH ||
>+ secretUsageType == VIR_SECRET_USAGE_TYPE_PASSPHRASE)) {
Since we have not allowed VIR_SECRET_USAGE_TYPE_PASSPHRASE before,
can we error out if we don't have both VIR_CRYPTO_CIPHER_AES256CBC and
QEMU_CAPS_OBJECT_SECRET to avoid putting plaintext on qemu command line?
> if (qemuDomainSecretAESSetup(conn, priv, secinfo, srcalias,
> secretUsageType, username,
> seclookupdef, isLuks) < 0)
>@@ -364,7 +370,7 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
> if (VIR_REALLOC_N(vm->def->disks, vm->def->ndisks+1) < 0)
> goto error;
>
>- /* Attach the device - possible 3 step process */
>+ /* Attach the device - possible 4 step process */
If you delete this outdated comment in 8/10, you don't have to update it
here.
> qemuDomainObjEnterMonitor(driver, vm);
>
> if (secobjProps && qemuMonitorAddObject(priv->mon, "secret",
>@@ -373,6 +379,12 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
> goto failaddobjsecret;
> secobjProps = NULL;
>
>+ if (encProps && qemuMonitorAddObject(priv->mon, "secret",
>+ encinfo->s.aes.alias,
>+ encProps) < 0)
>+ goto failaddencsecret;
s/failaddencsecret/delete_secinfo/
>+ encProps = NULL;
>+
> if (qemuMonitorAddDrive(priv->mon, drivestr) < 0)
> goto failadddrive;
>
>@@ -391,6 +403,7 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
>
> cleanup:
> virJSONValueFree(secobjProps);
>+ virJSONValueFree(encProps);
> qemuDomainSecretDiskDestroy(disk);
> VIR_FREE(devstr);
> VIR_FREE(drivestr);
>@@ -410,8 +423,13 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
> }
>
> failadddrive:
>+ if (encProps)
>+ ignore_value(qemuMonitorDelObject(priv->mon, encinfo->s.aes.alias));
This can also overwrite the error.
>+
>+ failaddencsecret:
> if (secobjProps)
> ignore_value(qemuMonitorDelObject(priv->mon, secinfo->s.aes.alias));
>+ encProps = NULL; /* qemuMonitorAddObject consumes props on failure too */
>
> failaddobjsecret:
> if (qemuDomainObjExitMonitor(driver, vm) < 0)
>@@ -571,6 +589,9 @@ qemuDomainAttachSCSIDisk(virConnectPtr conn,
> char *devstr = NULL;
> int ret = -1;
> virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
>+ virJSONValuePtr encProps = NULL;
>+ qemuDomainDiskPrivatePtr diskPriv;
>+ qemuDomainSecretInfoPtr encinfo;
>
> if (qemuDomainPrepareDisk(driver, vm, disk, NULL, false) < 0)
> goto cleanup;
>@@ -589,6 +610,11 @@ qemuDomainAttachSCSIDisk(virConnectPtr conn,
> if (qemuDomainSecretDiskPrepare(conn, priv, disk) < 0)
> goto error;
>
>+ diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
>+ encinfo = diskPriv->encinfo;
>+ if (encinfo && qemuBuildSecretInfoProps(encinfo, &encProps) < 0)
>+ goto error;
>+
> if (!(devstr = qemuBuildDriveDevStr(vm->def, disk, 0, priv->qemuCaps)))
> goto error;
>
>@@ -598,9 +624,15 @@ qemuDomainAttachSCSIDisk(virConnectPtr conn,
> if (VIR_REALLOC_N(vm->def->disks, vm->def->ndisks+1) < 0)
> goto error;
>
>- /* Attach the device - 2 step process */
>+ /* Attach the device - possible 3 step process */
> qemuDomainObjEnterMonitor(driver, vm);
>
>+ if (encProps && qemuMonitorAddObject(priv->mon, "secret",
>+ encinfo->s.aes.alias,
>+ encProps) < 0)
Don't we need to deal with secinfo like we do for virtio disks?
>+ goto failaddencsecret;
s/failaddencsecret/exit_monitor/
>+ encProps = NULL;
>+
> if (qemuMonitorAddDrive(priv->mon, drivestr) < 0)
> goto failadddrive;
>
ACK only if we don't need to deal with diskPriv->secinfo;
Jan
More information about the libvir-list
mailing list