]> xenbits.xensource.com Git - libvirt.git/commitdiff
storage: remove "luks" storage volume type
authorDaniel P. Berrange <berrange@redhat.com>
Tue, 26 Jul 2016 16:41:46 +0000 (17:41 +0100)
committerDaniel P. Berrange <berrange@redhat.com>
Wed, 27 Jul 2016 17:59:15 +0000 (18:59 +0100)
The current LUKS support has a "luks" volume type which has
a "luks" encryption format.

This partially makes sense if you consider the QEMU shorthand
syntax only requires you to specify a format=luks, and it'll
automagically uses "raw" as the next level driver. QEMU will
however let you override the "raw" with any other driver it
supports (vmdk, qcow, rbd, iscsi, etc, etc)

IOW the intention though is that the "luks" encryption format
is applied to all disk formats (whether raw, qcow2, rbd, gluster
or whatever). As such it doesn't make much sense for libvirt
to say the volume type is "luks" - we should be saying that it
is a "raw" file, but with "luks" encryption applied.

IOW, when creating a storage volume we should use this XML

  <volume>
    <name>demo.raw</name>
    <capacity>5368709120</capacity>
    <target>
      <format type='raw'/>
      <encryption format='luks'>
        <secret type='passphrase' uuid='0a81f5b2-8403-7b23-c8d6-21ccd2f80d6f'/>
      </encryption>
    </target>
  </volume>

and when configuring a guest disk we should use

  <disk type='file' device='disk'>
    <driver name='qemu' type='raw'/>
    <source file='/home/berrange/VirtualMachines/demo.raw'/>
    <target dev='sda' bus='scsi'/>
    <encryption format='luks'>
      <secret type='passphrase' uuid='0a81f5b2-8403-7b23-c8d6-21ccd2f80d6f'/>
    </encryption>
  </disk>

This commit thus removes the "luks" storage volume type added
in

  commit 318ebb36f1027b3357a32d6f781bd77d7a9043fd
  Author: John Ferlan <jferlan@redhat.com>
  Date:   Tue Jun 21 12:59:54 2016 -0400

    util: Add 'luks' to the FileTypeInfo

The storage file probing code is modified so that it can probe
the actual encryption formats explicitly, rather than merely
probing existance of encryption and letting the storage driver
guess the format.

The rest of the code is then adapted to deal with
VIR_STORAGE_FILE_RAW w/ VIR_STORAGE_ENCRYPTION_FORMAT_LUKS
instead of just VIR_STORAGE_FILE_LUKS.

The commit mentioned above was included in libvirt v2.0.0.
So when querying volume XML this will be a change in behaviour
vs the 2.0.0 release - it'll report 'raw' instead of 'luks'
for the volume format, but still report 'luks' for encryption
format.  I think this change is OK because the storage driver
did not include any support for creating volumes, nor starting
guets with luks volumes in v2.0.0 - that only since then.
Clearly if we change this we must do it before v2.1.0 though.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
15 files changed:
docs/formatstorage.html.in
docs/formatstorageencryption.html.in
src/qemu/qemu_command.c
src/qemu/qemu_domain.c
src/qemu/qemu_hotplug.c
src/storage/storage_backend.c
src/storage/storage_backend_fs.c
src/storage/storage_backend_gluster.c
src/util/virstoragefile.c
src/util/virstoragefile.h
tests/qemuxml2argvdata/qemuxml2argv-luks-disks.xml
tests/storagevolxml2xmlin/vol-luks-cipher.xml
tests/storagevolxml2xmlin/vol-luks.xml
tests/storagevolxml2xmlout/vol-luks-cipher.xml
tests/storagevolxml2xmlout/vol-luks.xml

index a700e855910981b9c395863ab22893dd4f6b0540..56b49280dd6db18df94760df6f2bc53a34e423e3 100644 (file)
         &lt;capacity unit="G"&gt;5&lt;/capacity&gt;
         &lt;target&gt;
           &lt;path&gt;/var/lib/virt/images/MyLuks.img&lt;/path&gt;
-          &lt;format type='luks'/&gt;
+          &lt;format type='raw'/&gt;
           &lt;encryption format='luks'&gt;
             &lt;secret type='passphrase' uuid='f52a81b2-424e-490c-823d-6bd4235bc572'/&gt;
           &lt;/encryption&gt;
index 11af97ee259eb1f1a3c1168951c6a755478ad699..1511305fd82a5fda9e85acf14b828456f631eb97 100644 (file)
         &lt;capacity unit='G'&gt;5&lt;/capacity&gt;
         &lt;target&gt;
           &lt;path&gt;/var/lib/libvirt/images/demo.luks&lt;/path&gt;
-          &lt;format type='luks'/&gt;
+          &lt;format type='raw'/&gt;
           &lt;encryption format='luks'&gt;
              &lt;secret type='passphrase' uuid='f52a81b2-424e-490c-823d-6bd4235bc572'/&gt;
              &lt;cipher name='twofish' size='256' mode='cbc' hash='sha256'/&gt;
index 4abe8e4c83b5990cad8780cd6edc0659ca53c951..0094665ca1416081944641fedb347cff50c4a473 100644 (file)
@@ -1303,9 +1303,13 @@ qemuBuildDriveSourceStr(virDomainDiskDefPtr disk,
                              encinfo->s.aes.alias);
 
     if (disk->src->format > 0 &&
-        disk->src->type != VIR_STORAGE_TYPE_DIR)
-        virBufferAsprintf(buf, "format=%s,",
-                          virStorageFileFormatTypeToString(disk->src->format));
+        disk->src->type != VIR_STORAGE_TYPE_DIR) {
+        const char *qemuformat = virStorageFileFormatTypeToString(disk->src->format);
+        if (disk->src->encryption &&
+            disk->src->encryption->format == VIR_STORAGE_ENCRYPTION_FORMAT_LUKS)
+            qemuformat = "luks";
+        virBufferAsprintf(buf, "format=%s,", qemuformat);
+    }
 
     ret = 0;
 
index 9045f37bd1d1152ca5256630685bdf56045ad598..b3ca993f43c91c51911368cb67fb1739adb3f4ba 100644 (file)
@@ -1078,7 +1078,7 @@ qemuDomainSecretDiskPrepare(virConnectPtr conn,
     }
 
     if (!virStorageSourceIsEmpty(src) && src->encryption &&
-        src->format == VIR_STORAGE_FILE_LUKS) {
+        src->encryption->format == VIR_STORAGE_ENCRYPTION_FORMAT_LUKS) {
 
         if (VIR_ALLOC(secinfo) < 0)
             return -1;
index 34a14247f4f72b83863fbd6ce469f43a8b7a3c24..b970448e177bcf1febe657ccda04005bb8939f48 100644 (file)
@@ -2989,7 +2989,7 @@ qemuDomainRemoveDiskDevice(virQEMUDriverPtr driver,
      * can remove the luks object password too
      */
     if (!virStorageSourceIsEmpty(disk->src) && disk->src->encryption &&
-        disk->src->format == VIR_STORAGE_FILE_LUKS) {
+        disk->src->encryption->format == VIR_STORAGE_ENCRYPTION_FORMAT_LUKS) {
 
         if (!(encAlias =
               qemuDomainGetSecretAESAlias(disk->info.alias, true))) {
index 862fb2914473e14aec07d1bbc539444da9affc87..6e99f3c314202278cf9208f6834f79db7b1d27e3 100644 (file)
@@ -963,12 +963,7 @@ virStorageBackendCreateQemuImgOpts(virStorageEncryptionInfoDefPtr enc,
 {
     virBuffer buf = VIR_BUFFER_INITIALIZER;
 
-    if (info.format == VIR_STORAGE_FILE_LUKS) {
-        if (!enc) {
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                           _("missing luks encryption information"));
-            goto error;
-        }
+    if (info.format == VIR_STORAGE_FILE_RAW && enc) {
         virQEMUBuildLuksOpts(&buf, enc, info.secretAlias);
     } else {
         if (info.backingPath)
@@ -1049,7 +1044,7 @@ virStorageBackendCreateQemuImgCheckEncryption(int format,
             if (virStorageGenerateQcowEncryption(conn, vol) < 0)
                 return -1;
         }
-    } else if (format == VIR_STORAGE_FILE_LUKS) {
+    } else if (format == VIR_STORAGE_FILE_RAW) {
         if (enc->format != VIR_STORAGE_ENCRYPTION_FORMAT_LUKS) {
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                            _("unsupported volume encryption format %d"),
@@ -1116,9 +1111,9 @@ virStorageBackendCreateQemuImgSetBacking(virStoragePoolObjPtr pool,
     int accessRetCode = -1;
     char *absolutePath = NULL;
 
-    if (info->format == VIR_STORAGE_FILE_LUKS) {
+    if (info->format == VIR_STORAGE_FILE_RAW) {
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                       _("cannot set backing store for luks volume"));
+                       _("cannot set backing store for raw volume"));
         return -1;
     }
 
@@ -1283,10 +1278,11 @@ virStorageBackendCreateQemuImgCmdFromVol(virConnectPtr conn,
                        _("format features only available with qcow2"));
         return NULL;
     }
-    if (info.format == VIR_STORAGE_FILE_LUKS) {
+    if (info.format == VIR_STORAGE_FILE_RAW &&
+        vol->target.encryption != NULL) {
         if (inputvol) {
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                           _("cannot use inputvol with luks volume"));
+                           _("cannot use inputvol with encrypted raw volume"));
             return NULL;
         }
         if (!info.encryption) {
@@ -1294,6 +1290,13 @@ virStorageBackendCreateQemuImgCmdFromVol(virConnectPtr conn,
                            _("missing encryption description"));
             return NULL;
         }
+        if (vol->target.encryption->format == VIR_STORAGE_ENCRYPTION_FORMAT_LUKS) {
+            type = "luks";
+        } else {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("Only luks encryption is supported for raw files"));
+            return NULL;
+        }
     }
 
     if (inputvol &&
@@ -1329,7 +1332,9 @@ virStorageBackendCreateQemuImgCmdFromVol(virConnectPtr conn,
     if (info.backingPath)
         virCommandAddArgList(cmd, "-b", info.backingPath, NULL);
 
-    if (info.format == VIR_STORAGE_FILE_LUKS) {
+    if (info.format == VIR_STORAGE_FILE_RAW &&
+        vol->target.encryption != NULL &&
+        vol->target.encryption->format == VIR_STORAGE_ENCRYPTION_FORMAT_LUKS) {
         if (virStorageBackendCreateQemuImgSecretObject(cmd, vol, &info) < 0) {
             VIR_FREE(info.secretAlias);
             virCommandFree(cmd);
@@ -1453,7 +1458,8 @@ virStorageBackendCreateQemuImg(virConnectPtr conn,
     if (imgformat < 0)
         goto cleanup;
 
-    if (vol->target.format == VIR_STORAGE_FILE_LUKS) {
+    if (vol->target.format == VIR_STORAGE_FILE_RAW &&
+        vol->target.encryption->format == VIR_STORAGE_ENCRYPTION_FORMAT_LUKS) {
         if (!(secretPath =
               virStorageBackendCreateQemuImgSecretPath(conn, pool, vol)))
             goto cleanup;
@@ -1484,13 +1490,15 @@ virStorageBackendGetBuildVolFromFunction(virStorageVolDefPtr vol,
     if (!inputvol)
         return NULL;
 
-    /* If either volume is a non-raw file vol, we need to use an external
-     * tool for converting
+    /* If either volume is a non-raw file vol, or uses encryption,
+     * we need to use an external tool for converting
      */
     if ((vol->type == VIR_STORAGE_VOL_FILE &&
-         vol->target.format != VIR_STORAGE_FILE_RAW) ||
+         (vol->target.format != VIR_STORAGE_FILE_RAW ||
+          vol->target.encryption != NULL)) ||
         (inputvol->type == VIR_STORAGE_VOL_FILE &&
-         inputvol->target.format != VIR_STORAGE_FILE_RAW)) {
+         (inputvol->target.format != VIR_STORAGE_FILE_RAW ||
+          inputvol->target.encryption != NULL))) {
         return virStorageBackendCreateQemuImg;
     }
 
index 0a12ecbf908de0dcefa1e3080fa88fbb8a2f34c3..ac6abbb18b3fa1ea7d77797439831e5a1264bcaf 100644 (file)
@@ -152,20 +152,6 @@ virStorageBackendProbeTarget(virStorageSourcePtr target,
         *encryption = meta->encryption;
         meta->encryption = NULL;
 
-        switch (target->format) {
-        case VIR_STORAGE_FILE_QCOW:
-        case VIR_STORAGE_FILE_QCOW2:
-            (*encryption)->format = VIR_STORAGE_ENCRYPTION_FORMAT_QCOW;
-            break;
-
-        case VIR_STORAGE_FILE_LUKS:
-            (*encryption)->format = VIR_STORAGE_ENCRYPTION_FORMAT_LUKS;
-            break;
-
-        case VIR_STORAGE_ENCRYPTION_FORMAT_LAST:
-            break;
-        }
-
         /* XXX ideally we'd fill in secret UUID here
          * but we cannot guarantee 'conn' is non-NULL
          * at this point in time :-(  So we only fill
@@ -1182,7 +1168,8 @@ _virStorageBackendFileSystemVolBuild(virConnectPtr conn,
                                                                inputvol);
         if (!create_func)
             return -1;
-    } else if (vol->target.format == VIR_STORAGE_FILE_RAW) {
+    } else if (vol->target.format == VIR_STORAGE_FILE_RAW &&
+               vol->target.encryption == NULL) {
         create_func = virStorageBackendCreateRaw;
     } else if (vol->target.format == VIR_STORAGE_FILE_DIR) {
         create_func = createFileDir;
index 5bcbef481e436c30a5e95dfd96971f6c721d088a..8e867043e9c2da448b50e68cd0d68382565cdcda 100644 (file)
@@ -318,11 +318,6 @@ virStorageBackendGlusterRefreshVol(virStorageBackendGlusterStatePtr state,
     if (meta->encryption) {
         vol->target.encryption = meta->encryption;
         meta->encryption = NULL;
-        if (vol->target.format == VIR_STORAGE_FILE_QCOW ||
-            vol->target.format == VIR_STORAGE_FILE_QCOW2)
-            vol->target.encryption->format = VIR_STORAGE_ENCRYPTION_FORMAT_QCOW;
-        if (vol->target.format == VIR_STORAGE_FILE_LUKS)
-            vol->target.encryption->format = VIR_STORAGE_ENCRYPTION_FORMAT_LUKS;
     }
     vol->target.features = meta->features;
     meta->features = NULL;
index 1612e66a99709931742a752a914de846c0b1bd7c..6f7d131a82fe076e2f2d41067e3896e0771956f8 100644 (file)
@@ -44,6 +44,7 @@
 #include "dirname.h"
 #include "virbuffer.h"
 #include "virjson.h"
+#include "virstorageencryption.h"
 
 #define VIR_FROM_THIS VIR_FROM_STORAGE
 
@@ -64,7 +65,7 @@ VIR_ENUM_IMPL(virStorageFileFormat,
               "cloop", "dmg", "iso",
               "vpc", "vdi",
               /* Not direct file formats, but used for various drivers */
-              "fat", "vhd", "ploop", "luks",
+              "fat", "vhd", "ploop",
               /* Formats with backing file below here */
               "cow", "qcow", "qcow2", "qed", "vmdk")
 
@@ -115,6 +116,26 @@ enum {
 
 #define FILE_TYPE_VERSIONS_LAST 2
 
+struct FileEncryptionInfo {
+    int format; /* Encryption format to assign */
+
+    int magicOffset; /* Byte offset of the magic */
+    const char *magic; /* Optional string of magic */
+
+    enum lv_endian endian; /* Endianness of file format */
+
+    int versionOffset;    /* Byte offset from start of file
+                           * where we find version number,
+                           * -1 to always fail the version test,
+                           * -2 to always pass the version test */
+    int versionSize;      /* Size in bytes of version data (0, 2, or 4) */
+    int versionNumbers[FILE_TYPE_VERSIONS_LAST];
+                          /* Version numbers to validate. Zeroes are ignored. */
+
+    int modeOffset; /* Byte offset of the format native encryption mode */
+    char modeValue; /* Value expected at offset */
+};
+
 /* Either 'magic' or 'extension' *must* be provided */
 struct FileTypeInfo {
     int magicOffset;    /* Byte offset of the magic */
@@ -138,15 +159,14 @@ struct FileTypeInfo {
                           /* Store a COW base image path (possibly relative),
                            * or NULL if there is no COW base image, to RES;
                            * return BACKING_STORE_* */
-    int qcowCryptOffset;  /* Byte offset from start of file
-                           * where to find encryption mode,
-                           * -1 if encryption is not used */
+    const struct FileEncryptionInfo *cryptInfo; /* Encryption info */
     int (*getBackingStore)(char **res, int *format,
                            const char *buf, size_t buf_size);
     int (*getFeatures)(virBitmapPtr *features, int format,
                        char *buf, ssize_t len);
 };
 
+
 static int cowGetBackingStore(char **, int *,
                               const char *, size_t);
 static int qcow1GetBackingStore(char **, int *,
@@ -197,19 +217,75 @@ qedGetBackingStore(char **, int *, const char *, size_t);
 /* Format described by qemu commit id '3e308f20e' */
 #define LUKS_HDR_VERSION_OFFSET LUKS_HDR_MAGIC_LEN
 
+static struct FileEncryptionInfo const luksEncryptionInfo[] = {
+    {
+        .format = VIR_STORAGE_ENCRYPTION_FORMAT_LUKS,
+
+        /* Magic is 'L','U','K','S', 0xBA, 0xBE */
+        .magicOffset = 0,
+        .magic = "\x4c\x55\x4b\x53\xba\xbe",
+        .endian = LV_BIG_ENDIAN,
+
+        .versionOffset  = LUKS_HDR_VERSION_OFFSET,
+        .versionSize = LUKS_HDR_VERSION_LEN,
+        .versionNumbers = {1},
+
+        .modeOffset = -1,
+        .modeValue = -1,
+    },
+    { 0 }
+};
+
+static struct FileEncryptionInfo const qcow1EncryptionInfo[] = {
+    {
+        .format = VIR_STORAGE_ENCRYPTION_FORMAT_QCOW,
+
+        .magicOffset = 0,
+        .magic = NULL,
+        .endian = LV_BIG_ENDIAN,
+
+        .versionOffset  = -1,
+        .versionSize = 0,
+        .versionNumbers = {},
+
+        .modeOffset = QCOW1_HDR_CRYPT,
+        .modeValue = 1,
+    },
+    { 0 }
+};
+
+static struct FileEncryptionInfo const qcow2EncryptionInfo[] = {
+    {
+        .format = VIR_STORAGE_ENCRYPTION_FORMAT_QCOW,
+
+        .magicOffset = 0,
+        .magic = NULL,
+        .endian = LV_BIG_ENDIAN,
+
+        .versionOffset  = -1,
+        .versionSize = 0,
+        .versionNumbers = {},
+
+        .modeOffset = QCOW2_HDR_CRYPT,
+        .modeValue = 1,
+    },
+    { 0 }
+};
 
 static struct FileTypeInfo const fileTypeInfo[] = {
     [VIR_STORAGE_FILE_NONE] = { 0, NULL, NULL, LV_LITTLE_ENDIAN,
-                                -1, 0, {0}, 0, 0, 0, 0, NULL, NULL },
+                                -1, 0, {0}, 0, 0, 0, NULL, NULL, NULL },
     [VIR_STORAGE_FILE_RAW] = { 0, NULL, NULL, LV_LITTLE_ENDIAN,
-                               -1, 0, {0}, 0, 0, 0, 0, NULL, NULL },
+                               -1, 0, {0}, 0, 0, 0,
+                               luksEncryptionInfo,
+                               NULL, NULL },
     [VIR_STORAGE_FILE_DIR] = { 0, NULL, NULL, LV_LITTLE_ENDIAN,
-                               -1, 0, {0}, 0, 0, 0, 0, NULL, NULL },
+                               -1, 0, {0}, 0, 0, 0, NULL, NULL, NULL },
     [VIR_STORAGE_FILE_BOCHS] = {
         /*"Bochs Virtual HD Image", */ /* Untested */
         0, NULL, NULL,
         LV_LITTLE_ENDIAN, 64, 4, {0x20000},
-        32+16+16+4+4+4+4+4, 8, 1, -1, NULL, NULL
+        32+16+16+4+4+4+4+4, 8, 1, NULL, NULL, NULL
     },
     [VIR_STORAGE_FILE_CLOOP] = {
         /* #!/bin/sh
@@ -218,7 +294,7 @@ static struct FileTypeInfo const fileTypeInfo[] = {
         */ /* Untested */
         0, NULL, NULL,
         LV_LITTLE_ENDIAN, -1, 0, {0},
-        -1, 0, 0, -1, NULL, NULL
+        -1, 0, 0, NULL, NULL, NULL
     },
     [VIR_STORAGE_FILE_DMG] = {
         /* XXX QEMU says there's no magic for dmg,
@@ -226,71 +302,69 @@ static struct FileTypeInfo const fileTypeInfo[] = {
          * would have to match) but then disables that check. */
         0, NULL, ".dmg",
         0, -1, 0, {0},
-        -1, 0, 0, -1, NULL, NULL
+        -1, 0, 0, NULL, NULL, NULL
     },
     [VIR_STORAGE_FILE_ISO] = {
         32769, "CD001", ".iso",
         LV_LITTLE_ENDIAN, -2, 0, {0},
-        -1, 0, 0, -1, NULL, NULL
+        -1, 0, 0, NULL, NULL, NULL
     },
     [VIR_STORAGE_FILE_VPC] = {
         0, "conectix", NULL,
         LV_BIG_ENDIAN, 12, 4, {0x10000},
-        8 + 4 + 4 + 8 + 4 + 4 + 2 + 2 + 4, 8, 1, -1, NULL, NULL
+        8 + 4 + 4 + 8 + 4 + 4 + 2 + 2 + 4, 8, 1, NULL, NULL, NULL
     },
     /* TODO: add getBackingStore function */
     [VIR_STORAGE_FILE_VDI] = {
         64, "\x7f\x10\xda\xbe", ".vdi",
         LV_LITTLE_ENDIAN, 68, 4, {0x00010001},
-        64 + 5 * 4 + 256 + 7 * 4, 8, 1, -1, NULL, NULL},
+        64 + 5 * 4 + 256 + 7 * 4, 8, 1, NULL, NULL, NULL},
 
     /* Not direct file formats, but used for various drivers */
     [VIR_STORAGE_FILE_FAT] = { 0, NULL, NULL, LV_LITTLE_ENDIAN,
-                               -1, 0, {0}, 0, 0, 0, 0, NULL, NULL },
+                               -1, 0, {0}, 0, 0, 0, NULL, NULL, NULL },
     [VIR_STORAGE_FILE_VHD] = { 0, NULL, NULL, LV_LITTLE_ENDIAN,
-                               -1, 0, {0}, 0, 0, 0, 0, NULL, NULL },
+                               -1, 0, {0}, 0, 0, 0, NULL, NULL, NULL },
     [VIR_STORAGE_FILE_PLOOP] = { 0, "WithouFreSpacExt", NULL, LV_LITTLE_ENDIAN,
                                  -2, 0, {0}, PLOOP_IMAGE_SIZE_OFFSET, 0,
-                                 PLOOP_SIZE_MULTIPLIER, -1, NULL, NULL },
-
-    /* Magic is 'L','U','K','S', 0xBA, 0xBE
-     * Set sizeOffset = -1 and let hypervisor handle */
-    [VIR_STORAGE_FILE_LUKS] = {
-        0, "\x4c\x55\x4b\x53\xba\xbe", NULL,
-        LV_BIG_ENDIAN, LUKS_HDR_VERSION_OFFSET, 2, {1},
-        -1, 0, 0, -1, NULL, NULL
-    },
+                                 PLOOP_SIZE_MULTIPLIER, NULL, NULL, NULL },
+
     /* All formats with a backing store probe below here */
     [VIR_STORAGE_FILE_COW] = {
         0, "OOOM", NULL,
         LV_BIG_ENDIAN, 4, 4, {2},
-        4+4+1024+4, 8, 1, -1, cowGetBackingStore, NULL
+        4+4+1024+4, 8, 1, NULL, cowGetBackingStore, NULL
     },
     [VIR_STORAGE_FILE_QCOW] = {
         0, "QFI", NULL,
         LV_BIG_ENDIAN, 4, 4, {1},
-        QCOWX_HDR_IMAGE_SIZE, 8, 1, QCOW1_HDR_CRYPT, qcow1GetBackingStore, NULL
+        QCOWX_HDR_IMAGE_SIZE, 8, 1,
+        qcow1EncryptionInfo,
+        qcow1GetBackingStore, NULL
     },
     [VIR_STORAGE_FILE_QCOW2] = {
         0, "QFI", NULL,
         LV_BIG_ENDIAN, 4, 4, {2, 3},
-        QCOWX_HDR_IMAGE_SIZE, 8, 1, QCOW2_HDR_CRYPT, qcow2GetBackingStore,
+        QCOWX_HDR_IMAGE_SIZE, 8, 1,
+        qcow2EncryptionInfo,
+        qcow2GetBackingStore,
         qcow2GetFeatures
     },
     [VIR_STORAGE_FILE_QED] = {
         /* http://wiki.qemu.org/Features/QED */
         0, "QED", NULL,
         LV_LITTLE_ENDIAN, -2, 0, {0},
-        QED_HDR_IMAGE_SIZE, 8, 1, -1, qedGetBackingStore, NULL
+        QED_HDR_IMAGE_SIZE, 8, 1, NULL, qedGetBackingStore, NULL
     },
     [VIR_STORAGE_FILE_VMDK] = {
         0, "KDMV", NULL,
         LV_LITTLE_ENDIAN, 4, 4, {1, 2},
-        4+4+4, 8, 512, -1, vmdk4GetBackingStore, NULL
+        4+4+4, 8, 512, NULL, vmdk4GetBackingStore, NULL
     },
 };
 verify(ARRAY_CARDINALITY(fileTypeInfo) == VIR_STORAGE_FILE_LAST);
 
+
 /* qcow2 compatible features in the order they appear on-disk */
 enum qcow2CompatibleFeature {
     QCOW2_COMPATIBLE_FEATURE_LAZY_REFCOUNTS = 0,
@@ -644,7 +718,7 @@ virStorageFileMatchesVersion(int versionOffset,
                              char *buf,
                              size_t buflen)
 {
-    int version = 0;
+    int version;
     size_t i;
 
     /* Validate version number info */
@@ -808,6 +882,43 @@ qcow2GetFeatures(virBitmapPtr *features,
 }
 
 
+static bool
+virStorageFileHasEncryptionFormat(const struct FileEncryptionInfo *info,
+                                  char *buf,
+                                  size_t len)
+{
+    if (!info->magic && info->modeOffset == -1)
+        return 0; /* Shouldn't happen - expect at least one */
+
+    if (info->magic) {
+        if (!virStorageFileMatchesMagic(info->magicOffset,
+                                        info->magic,
+                                        buf, len))
+            return false;
+
+        if (info->versionOffset != -1 &&
+            !virStorageFileMatchesVersion(info->versionOffset,
+                                          info->versionSize,
+                                          info->versionNumbers,
+                                          info->endian,
+                                          buf, len))
+            return false;
+
+        return true;
+    } else if (info->modeOffset != -1) {
+        if (info->modeOffset >= len)
+            return false;
+
+        if (buf[info->modeOffset] != info->modeValue)
+            return false;
+
+        return true;
+    } else {
+        return false;
+    }
+}
+
+
 /* Given a header in BUF with length LEN, as parsed from the storage file
  * assuming it has the given FORMAT, populate information into META
  * with information about the file and its backing store. Return format
@@ -820,6 +931,7 @@ virStorageFileGetMetadataInternal(virStorageSourcePtr meta,
                                   int *backingFormat)
 {
     int ret = -1;
+    size_t i;
 
     VIR_DEBUG("path=%s, buf=%p, len=%zu, meta->format=%d",
               meta->path, buf, len, meta->format);
@@ -834,6 +946,18 @@ virStorageFileGetMetadataInternal(virStorageSourcePtr meta,
         goto cleanup;
     }
 
+    if (fileTypeInfo[meta->format].cryptInfo != NULL) {
+        for (i = 0; fileTypeInfo[meta->format].cryptInfo[i].format != 0; i++) {
+            if (virStorageFileHasEncryptionFormat(&fileTypeInfo[meta->format].cryptInfo[i],
+                                                  buf, len)) {
+                if (VIR_ALLOC(meta->encryption) < 0)
+                    goto cleanup;
+
+                meta->encryption->format = fileTypeInfo[meta->format].cryptInfo[i].format;
+            }
+        }
+    }
+
     /* XXX we should consider moving virStorageBackendUpdateVolInfo
      * code into this method, for non-magic files
      */
@@ -858,22 +982,6 @@ virStorageFileGetMetadataInternal(virStorageSourcePtr meta,
         meta->capacity *= fileTypeInfo[meta->format].sizeMultiplier;
     }
 
-    if (fileTypeInfo[meta->format].qcowCryptOffset != -1) {
-        int crypt_format;
-
-        crypt_format = virReadBufInt32BE(buf +
-                                         fileTypeInfo[meta->format].qcowCryptOffset);
-        if (crypt_format && !meta->encryption &&
-            VIR_ALLOC(meta->encryption) < 0)
-            goto cleanup;
-    }
-
-    if (meta->format == VIR_STORAGE_FILE_LUKS) {
-        /* By definition, this is encrypted */
-        if (!meta->encryption && VIR_ALLOC(meta->encryption) < 0)
-            goto cleanup;
-    }
-
     VIR_FREE(meta->backingStoreRaw);
     if (fileTypeInfo[meta->format].getBackingStore != NULL) {
         int store = fileTypeInfo[meta->format].getBackingStore(&meta->backingStoreRaw,
index 3ea3a60dfbdde2508c310d7724d8180e63c0512c..3d0946801f636f057b512aa37cc9b675996d6d50 100644 (file)
@@ -74,7 +74,6 @@ typedef enum {
     VIR_STORAGE_FILE_FAT,
     VIR_STORAGE_FILE_VHD,
     VIR_STORAGE_FILE_PLOOP,
-    VIR_STORAGE_FILE_LUKS,
 
     /* Not a format, but a marker: all formats below this point have
      * libvirt support for following a backing chain */
index 4c9c4c7fb71d88c9392dae32dea9db1512ff90ad..3ae0a409867250713678fc043866304d083e3430 100644 (file)
@@ -15,7 +15,7 @@
   <devices>
     <emulator>/usr/bin/qemu</emulator>
     <disk type='file' device='disk'>
-      <driver name='qemu' type='luks'/>
+      <driver name='qemu' type='raw'/>
       <source file='/storage/guest_disks/encryptdisk'/>
       <target dev='vda' bus='virtio'/>
       <encryption format='luks'>
@@ -24,7 +24,7 @@
       <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
     </disk>
     <disk type='file' device='disk'>
-      <driver name='qemu' type='luks'/>
+      <driver name='qemu' type='raw'/>
       <source file='/storage/guest_disks/encryptdisk2'/>
       <target dev='vdb' bus='virtio'/>
       <encryption format='luks'>
index da28a27cc29499e229287a24716c7080660ce8ff..94789c6d1509e97e35e8f46af7f7e1f0ed9fd7ce 100644 (file)
@@ -7,7 +7,7 @@
   <allocation>294912</allocation>
   <target>
     <path>/var/lib/libvirt/images/LuksDemo.img</path>
-    <format type='luks'/>
+    <format type='raw'/>
     <permissions>
       <mode>0644</mode>
       <owner>0</owner>
index bf3c5192b4668b71c0e0a603cc4371a9dbc595c0..9ab1429e65d7677996c8aaf51add8c63fafe1d73 100644 (file)
@@ -7,7 +7,7 @@
   <allocation>294912</allocation>
   <target>
     <path>/var/lib/libvirt/images/LuksDemo.img</path>
-    <format type='luks'/>
+    <format type='raw'/>
     <permissions>
       <mode>0644</mode>
       <owner>0</owner>
index 1ac742437609e9405d0f4d4d649c21d47505d47c..2b58850aaf708118e6d20ee148a0dbf71e244df2 100644 (file)
@@ -7,7 +7,7 @@
   <allocation unit='bytes'>294912</allocation>
   <target>
     <path>/var/lib/libvirt/images/LuksDemo.img</path>
-    <format type='luks'/>
+    <format type='raw'/>
     <permissions>
       <mode>0644</mode>
       <owner>0</owner>
index 7b82866c6f63deaa94fb913c174a61edc6c0a9bd..599b3c5c4d6dc11b8e3be19e849267158b845094 100644 (file)
@@ -7,7 +7,7 @@
   <allocation unit='bytes'>294912</allocation>
   <target>
     <path>/var/lib/libvirt/images/LuksDemo.img</path>
-    <format type='luks'/>
+    <format type='raw'/>
     <permissions>
       <mode>0644</mode>
       <owner>0</owner>