]> xenbits.xensource.com Git - libvirt.git/commitdiff
storage: Add capability to use LUKS encryption for disk backend
authorJohn Ferlan <jferlan@redhat.com>
Mon, 21 May 2018 10:40:58 +0000 (06:40 -0400)
committerJohn Ferlan <jferlan@redhat.com>
Tue, 29 May 2018 14:48:51 +0000 (10:48 -0400)
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 <jferlan@redhat.com>
ACKed-by: Peter Krempa <pkrempa@redhat.com>
src/storage/storage_backend_disk.c

index 2e3d1e04a4b9c2ee65884a6c23ad823dd5ef408f..c638e2db2500f542715247cdf3f49f1eebd12875 100644 (file)
@@ -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,