From 57d6df39bd7eb8166fee68f4b6da03c0cb0802bf Mon Sep 17 00:00:00 2001 From: John Ferlan Date: Mon, 21 May 2018 06:40:58 -0400 Subject: [PATCH] storage: Add capability to use LUKS encryption for disk backend https://bugzilla.redhat.com/show_bug.cgi?id=1560946 Similar to the the Logical backend, use qemu-img on the created disk partition device to set up for LUKS encryption. Secret mgmt for the device can be complicated by a reboot possibly changing the path to the device if the infrastructure changes. Signed-off-by: John Ferlan ACKed-by: Peter Krempa --- src/storage/storage_backend_disk.c | 49 +++++++++++++++++++----------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/src/storage/storage_backend_disk.c b/src/storage/storage_backend_disk.c index 2e3d1e04a4..c638e2db25 100644 --- a/src/storage/storage_backend_disk.c +++ b/src/storage/storage_backend_disk.c @@ -879,16 +879,17 @@ virStorageBackendDiskCreateVol(virStoragePoolObjPtr pool, char *partFormat = NULL; unsigned long long startOffset = 0, endOffset = 0; virStoragePoolDefPtr def = virStoragePoolObjGetDef(pool); + virErrorPtr save_err; virCommandPtr cmd = virCommandNewArgList(PARTED, def->source.devices[0].path, "mkpart", "--script", NULL); - if (vol->target.encryption != NULL) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - "%s", _("storage pool does not support encrypted " - "volumes")); + if (vol->target.encryption && + vol->target.encryption->format != VIR_STORAGE_ENCRYPTION_FORMAT_LUKS) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("storage pool only supports LUKS encrypted volumes")); goto cleanup; } @@ -896,11 +897,14 @@ virStorageBackendDiskCreateVol(virStoragePoolObjPtr pool, goto cleanup; virCommandAddArg(cmd, partFormat); - if (virStorageBackendDiskPartBoundaries(pool, &startOffset, - &endOffset, - vol->target.capacity) != 0) { + /* If we're going to encrypt using LUKS, then we could need up to + * an extra 2MB for the LUKS header - so account for that now */ + if (vol->target.encryption) + vol->target.capacity += 2 * 1024 * 1024; + + if (virStorageBackendDiskPartBoundaries(pool, &startOffset, &endOffset, + vol->target.capacity) < 0) goto cleanup; - } virCommandAddArgFormat(cmd, "%lluB", startOffset); virCommandAddArgFormat(cmd, "%lluB", endOffset); @@ -919,15 +923,15 @@ virStorageBackendDiskCreateVol(virStoragePoolObjPtr pool, VIR_FREE(vol->target.path); /* Fetch actual extent info, generate key */ - if (virStorageBackendDiskReadPartitions(pool, vol) < 0) { - /* Best effort to remove the partition. Ignore any errors - * since we could be calling this with vol->target.path == NULL - */ - virErrorPtr save_err = virSaveLastError(); - ignore_value(virStorageBackendDiskDeleteVol(pool, vol, 0)); - virSetError(save_err); - virFreeError(save_err); - goto cleanup; + if (virStorageBackendDiskReadPartitions(pool, vol) < 0) + goto error; + + if (vol->target.encryption) { + /* Adjust the sizes to account for the LUKS header */ + vol->target.capacity -= 2 * 1024 * 1024; + vol->target.allocation -= 2 * 1024 * 1024; + if (virStorageBackendCreateVolUsingQemuImg(pool, vol, NULL, 0) < 0) + goto error; } res = 0; @@ -936,8 +940,19 @@ virStorageBackendDiskCreateVol(virStoragePoolObjPtr pool, VIR_FREE(partFormat); virCommandFree(cmd); return res; + + error: + /* Best effort to remove the partition. Ignore any errors + * since we could be calling this with vol->target.path == NULL + */ + save_err = virSaveLastError(); + ignore_value(virStorageBackendDiskDeleteVol(pool, vol, 0)); + virSetError(save_err); + virFreeError(save_err); + goto cleanup; } + static int virStorageBackendDiskBuildVolFrom(virStoragePoolObjPtr pool, virStorageVolDefPtr vol, -- GitLab